diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c89bd50 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,30 @@ +# jQuery Enhanced Splitter Change Log + +## Branch v1.2.0 + +Changes made so far over v1.1.0. +- Updated composer.json to specify valid jQuery versions (1.8+ / 2.0+). +- Implemented drag-delay if the user clicks on the collapse handle then starts dragging. Drag will not begin until mouse has moved past 5 pixels in either direction. (UX improvement) +- Prevent click event if the user started and ended their drag on the collapse handle. (UX improvement) +- Change splitter bar class from .splitter to .splitter_bar for consistency. +- Fixed issue where collapse handle would ignore one click if manually dragged to the collapsed position. (UX improvement/bug) +- Modified onDrag, onDragStart, onDragEnd events to pass splitter container for easy manipulation. + +## Release v1.1.0 + +This release adds a number of new options, as well as a few fixes and overall UX improvements. +- Added 'lowerLimit' and 'upperLimit' options, changed 'limit' to an alias to set both. +- Added 'collapse' option. +- Added 'fixed' option. +- Added 'splitterSize' option. +- Changed 'orientation' string setting to 'vertical' boolean setting. (BREAKING CHANGE) +- Fixed a few bugs. +- Significantly rewrote event handling, now smoother, faster, and tastier. + +## Release v1.0.1 + +More bug fixes, improved event handlers, improved CSS. + +## Release v1.0.0 + +Original release of fork, with significant changes and bug fixes. diff --git a/README.md b/README.md index c200409..7b38047 100644 --- a/README.md +++ b/README.md @@ -3,20 +3,17 @@ jquery.enhsplitter is a plugin to generate sliding splitters on your page. Useful for separating content, emulating the look of frames, collapsable tool windows, and more. Completely customizable look and feel, and touchscreen friendly. -Release v1.1.0 ------- +## Demo and Documentation -This release adds a number of new options, as well as a few fixes and overall UX improvements. -But since nobody is using this yet, I won't bother documenting all the changes here. Rest assured that any changes -from here forward will be properly documented! +A demo and basic documentation of options of the latest version are available at: -# Demo + -A demo and basic documentation of options are available at: +## Requirements - +jquery.enhsplitter requires jQuery v1.8 or greater, or v2.0 or greater. -# Example +## Example A minimal call to jquery.enhsplitter in a jQuery ready function looks like this: @@ -66,13 +63,13 @@ jQuery(function ($) { ``` -# License +## License Copyright (C) 2015 Hilton Janfield Released under the terms of the [GNU Lesser General Public License](http://www.gnu.org/licenses/lgpl.html) -# Original Author and Contributors +## Original Author and Contributors This plugin was originally created by Jakub Jankiewicz. See https://github.com/jcubic/jquery.splitter diff --git a/composer.json b/composer.json index 27f6933..301fd9c 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "homepage": "https://github.com/hiltonjanfield/jquery.enhsplitter", "bugs": "https://github.com/hiltonjanfield/jquery.enhsplitter/issues", "dependencies": { - "jquery": ">=2.1" + "jquery": ">=1.8 || >=2.0" }, "main": [ "js/jquery.enhsplitter.js", diff --git a/css/jquery.enhsplitter.css b/css/jquery.enhsplitter.css index 3442ff3..0b17703 100644 --- a/css/jquery.enhsplitter.css +++ b/css/jquery.enhsplitter.css @@ -1,7 +1,7 @@ /*! * jQuery Enhanced Splitter Plugin * LESS / CSS File - * Version 1.1.0 + * Version 1.2.0 * * https://github.com/hiltonjanfield/jquery.enhsplitter * @@ -47,19 +47,19 @@ /* Right panel */ right: 0; } -.splitter_container.splitter-fixed > .splitter { +.splitter_container.splitter-fixed > .splitter_bar { cursor: default; } -.splitter_container.splitter-handle-disabled > .splitter > .splitter_handle { +.splitter_container.splitter-handle-disabled > .splitter_bar > .splitter_handle { cursor: inherit; } -.splitter { +.splitter_bar { background-color: #c0c0c0; position: absolute; padding: 0 !important; box-sizing: border-box; } -.splitter > .splitter_handle { +.splitter_bar > .splitter_handle { cursor: pointer; background-color: #999999; position: relative; @@ -67,24 +67,24 @@ z-index: 1000; box-sizing: border-box; } -.splitter > .splitter_handle:hover { +.splitter_bar > .splitter_handle:hover { background-color: #666666; border-color: #666666; } -.splitter > .splitter_handle:active { +.splitter_bar > .splitter_handle:active { background-color: #000000; border-color: #000000; } -.splitter.splitter-invisible { +.splitter_bar.splitter-invisible { background: none!important; border: none!important; box-shadow: none!important; } -.splitter.splitter-invisible .splitter_handle, -.splitter.splitter-handle-none .splitter_handle { +.splitter_bar.splitter-invisible .splitter_handle, +.splitter_bar.splitter-handle-none .splitter_handle { display: none; } -.splitter-vertical > .splitter { +.splitter-vertical > .splitter_bar { border-left: 1px solid #eeeeee; border-right: 1px solid #666666; cursor: ew-resize; @@ -92,30 +92,30 @@ width: 7px; height: 100%; } -.splitter-vertical > .splitter > .splitter_handle { +.splitter-vertical > .splitter_bar > .splitter_handle { top: 50%; margin-top: -25px; height: 50px; } -.splitter-vertical > .splitter.splitter-handle-default > .splitter_handle { +.splitter-vertical > .splitter_bar.splitter-handle-default > .splitter_handle { width: 3px; border-left: 1px solid #999999; border-right: 1px solid #999999; background-color: transparent; } -.splitter-vertical > .splitter.splitter-handle-default > .splitter_handle:hover { +.splitter-vertical > .splitter_bar.splitter-handle-default > .splitter_handle:hover { border-color: #666666; } -.splitter-vertical > .splitter.splitter-handle-default > .splitter_handle:active { +.splitter-vertical > .splitter_bar.splitter-handle-default > .splitter_handle:active { border-color: #000000; } -.splitter-vertical > .splitter.splitter-handle-bar > .splitter_handle { +.splitter-vertical > .splitter_bar.splitter-handle-bar > .splitter_handle { width: 3px; } -.splitter-vertical > .splitter.splitter-handle-block > .splitter_handle { +.splitter-vertical > .splitter_bar.splitter-handle-block > .splitter_handle { width: 5px; } -.splitter-horizontal > .splitter { +.splitter-horizontal > .splitter_bar { border-top: 1px solid #eeeeee; border-bottom: 1px solid #666666; cursor: ns-resize; @@ -123,40 +123,40 @@ width: 100%; height: 7px; } -.splitter-horizontal > .splitter > .splitter_handle { +.splitter-horizontal > .splitter_bar > .splitter_handle { width: 50px; } -.splitter-horizontal > .splitter.splitter-handle-default > .splitter_handle { +.splitter-horizontal > .splitter_bar.splitter-handle-default > .splitter_handle { height: 3px; margin-top: 1px; border-top: 1px solid #999999; border-bottom: 1px solid #999999; background-color: transparent; } -.splitter-horizontal > .splitter.splitter-handle-default > .splitter_handle:hover { +.splitter-horizontal > .splitter_bar.splitter-handle-default > .splitter_handle:hover { border-color: #666666; } -.splitter-horizontal > .splitter.splitter-handle-default > .splitter_handle:active { +.splitter-horizontal > .splitter_bar.splitter-handle-default > .splitter_handle:active { border-color: #000000; } -.splitter-horizontal > .splitter.splitter-handle-bar > .splitter_handle { +.splitter-horizontal > .splitter_bar.splitter-handle-bar > .splitter_handle { height: 3px; margin-top: 1px; } -.splitter-horizontal > .splitter.splitter-handle-block > .splitter_handle { +.splitter-horizontal > .splitter_bar.splitter-handle-block > .splitter_handle { height: 5px; margin-top: 1px; } -.splitter_container.splitter-active > .splitter { +.splitter_container.splitter-active > .splitter_bar { z-index: 1000; /* Important to keep z-index of active splitter above .splitterMask. */ } -.splitter_container.splitter-active > .splitter > .splitter_handle { +.splitter_container.splitter-active > .splitter_bar > .splitter_handle { border-color: #000000; cursor: inherit; } -.splitter_container.splitter-active > .splitter.splitter-handle-bar > .splitter_handle, -.splitter_container.splitter-active > .splitter.splitter-handle-block > .splitter_handle { +.splitter_container.splitter-active > .splitter_bar.splitter-handle-bar > .splitter_handle, +.splitter_container.splitter-active > .splitter_bar.splitter-handle-block > .splitter_handle { background-color: #000000; } .splitter_mask { diff --git a/css/jquery.enhsplitter.less b/css/jquery.enhsplitter.less index 2d455bc..a9c7567 100644 --- a/css/jquery.enhsplitter.less +++ b/css/jquery.enhsplitter.less @@ -1,7 +1,7 @@ /*! * jQuery Enhanced Splitter Plugin * LESS / CSS File - * Version 1.1.0 + * Version 1.2.0 * * https://github.com/hiltonjanfield/jquery.enhsplitter * @@ -71,16 +71,16 @@ } - &.splitter-fixed > .splitter { + &.splitter-fixed > .splitter_bar { cursor: default; } - &.splitter-handle-disabled > .splitter > .splitter_handle { + &.splitter-handle-disabled > .splitter_bar > .splitter_handle { cursor: inherit; } } -.splitter { +.splitter_bar { background-color: @splitter_color; position: absolute; padding: 0 !important; @@ -120,7 +120,7 @@ } .splitter-vertical { - > .splitter { + > .splitter_bar { border-left: 1px solid @splitter_highlight; border-right: 1px solid @splitter_shadow; cursor: ew-resize; @@ -166,7 +166,7 @@ } .splitter-horizontal { - > .splitter { + > .splitter_bar { border-top: 1px solid @splitter_highlight; border-bottom: 1px solid @splitter_shadow; cursor: ns-resize; @@ -212,7 +212,7 @@ } } -.splitter_container.splitter-active > .splitter { +.splitter_container.splitter-active > .splitter_bar { z-index: 1000; /* Important to keep z-index of active splitter above .splitterMask. */ > .splitter_handle { diff --git a/demo.html b/demo.html index 0c5b6b9..fe6072d 100644 --- a/demo.html +++ b/demo.html @@ -473,23 +473,29 @@

Options

onDragStart
+ function (event, splitter_container) { ... } Default: $.noop

Event handler called when a user starts dragging a splitter.

+

Parameters passed are the standard event handler data, and the .splitter_container object.

onDragEnd
+ function (event, splitter_container) { ... } Default: $.noop

Event handler called when a user stops dragging a splitter.

+

Parameters passed are the standard event handler data, and the .splitter_container object.

onDrag
+ function (event, splitter_container) { ... } Default: $.noop

Event handler called after a user moves a splitter.

+

Parameters passed are the standard event handler data, and the .splitter_container object.

diff --git a/js/jquery.enhsplitter.js b/js/jquery.enhsplitter.js index df884aa..0a75ba0 100644 --- a/js/jquery.enhsplitter.js +++ b/js/jquery.enhsplitter.js @@ -1,7 +1,7 @@ /*! * jQuery Enhanced Splitter Plugin * Main ECMAScript File - * Version 1.1.0 + * Version 1.2.0 * * https://github.com/hiltonjanfield/jquery.enhsplitter * @@ -22,6 +22,8 @@ var splitterCount = 0; var splitters = []; var currentSplitter = null; + var dragStartPosition = null; + var disableClick = false; $.fn.enhsplitter = function (options) { var data = this.data('splitter'); @@ -75,7 +77,7 @@ this.css('height', settings.height); } - // Verify the limits are within allowed constaints (size of panel) + // Verify the limits are within allowed constraints (size of panel) // With a little obfuscation to reduce 36 lines to 3 settings.limit = (settings.limit < 0 ? 0 : (settings.vertical ? (settings.limit > (this.width() / 2) ? this.width() / 2 : settings.limit) : (settings.limit > (this.height() / 2) ? this.height() / 2 : settings.limit))); // Once settings.limit has been range checked, use it as a default for lowerLimit and upperLimit. @@ -96,7 +98,7 @@ this.addClass('splitter-fixed'); } - splitter = $('
') + splitter = $('
') .insertAfter(panelOne); handle = $('
') .appendTo(splitter); @@ -213,7 +215,8 @@ // If this is the first splitter, set up our events. if (splitters.length == 0) { - $(window).on('resize.splitter', function () { + $(window) + .on('resize.splitter', function () { $.each(splitters, function (i, splitter) { splitter.refresh(); }); @@ -221,6 +224,11 @@ $(document.documentElement) .on('click.splitter', '.splitter_handle', function (e) { + // Prevent clicks if the user started dragging too much. + // Some (all?) browsers fire the click event even after the bar has been dragged hundreds of pixels. + if (disableClick) { + return disableClick = false; + } currentSplitter = $(this).closest('.splitter_container').data('splitter'); if (currentSplitter.settings.collapsable) { @@ -246,13 +254,22 @@ currentSplitter.find('.splitter_panel').trigger('resize.splitter'); e.preventDefault(); $('.splitter_mask').remove(); - currentSplitter.settings.onDrag(e); + currentSplitter.settings.onDrag(e, currentSplitter); } currentSplitter.removeClass('splitter-active'); currentSplitter = null; }) - .on('mousedown.splitter touchstart.splitter', '.splitter_container > .splitter', function (e) { + .on('mousedown.splitter', '.splitter_handle', function (e) { + e.preventDefault(); + // This mousedown event gets called first because it is on top, but we need the other one to fire + // first - or duplicate the code, which is bad, m'kay? + $(this).closest('.splitter_bar').trigger('mousedown'); + + dragStartPosition = (currentSplitter.settings.vertical) ? e.pageX : e.pageY; + }) + + .on('mousedown.splitter touchstart.splitter', '.splitter_container > .splitter_bar', function (e) { e.preventDefault(); currentSplitter = $(this).closest('.splitter_container').data('splitter'); if (currentSplitter.settings.fixed) { @@ -260,72 +277,84 @@ } else { currentSplitter.addClass('splitter-active'); $('
').css('cursor', currentSplitter.children().eq(1).css('cursor')).insertAfter(currentSplitter); - currentSplitter.settings.onDragStart(e); + currentSplitter.settings.onDragStart(e, currentSplitter); } }) - // Todo: Explore and test the touch events. - .on('mouseup.splitter touchend.splitter touchleave.splitter touchcancel.splitter', '.splitter_mask, .splitter_container > .splitter', function (e) { + .on('mouseup.splitter touchend.splitter touchleave.splitter touchcancel.splitter', '.splitter_mask, .splitter_container > .splitter_bar', function (e) { if (currentSplitter) { e.preventDefault(); + dragStartPosition = null; // If the slider is dropped near it's collapsed position, set a saved position back to its - // original start position so the collapse handle works somewhat properly. + // original start position so the collapse handle works at least somewhat properly. if (!currentSplitter.data('savedPosition')) { if (currentSplitter.settings.collapseNormal) { if (currentSplitter.currentPosition <= (currentSplitter.settings.lowerLimit + 5)) { currentSplitter.data('savedPosition', self.translatePosition(currentSplitter.settings.position)); + disableClick = false; } } else { if (currentSplitter.settings.vertical) { if (currentSplitter.currentPosition >= (currentSplitter.containerWidth - currentSplitter.settings.upperLimit - 5)) { currentSplitter.data('savedPosition', self.translatePosition(currentSplitter.settings.position)); + disableClick = false; } } else { if (currentSplitter.currentPosition >= (currentSplitter.containerHeight - currentSplitter.settings.upperLimit - 5)) { currentSplitter.data('savedPosition', self.translatePosition(currentSplitter.settings.position)); + disableClick = false; } } } } $('.splitter_mask').remove(); - currentSplitter.settings.onDragEnd(e); + currentSplitter.settings.onDragEnd(e, currentSplitter); currentSplitter.removeClass('splitter-active'); currentSplitter = null; } }) - .on('mousemove.splitter touchmove.splitter', '.splitter_mask, .splitter', function (e) { + .on('mousemove.splitter touchmove.splitter', '.splitter_mask, .splitter_bar', function (e) { if (currentSplitter !== null) { currentSplitter.data('savedPosition', null); - if (currentSplitter.settings.vertical) { - var pageX = e.pageX; - if (e.originalEvent && e.originalEvent.changedTouches) { - pageX = e.originalEvent.changedTouches[0].pageX; + var position = (currentSplitter.settings.vertical) ? e.pageX : e.pageY; + if (e.originalEvent && e.originalEvent.changedTouches) { + position = (currentSplitter.settings.vertical) ? e.originalEvent.changedTouches[0].pageX : e.originalEvent.changedTouches[0].pageY; + } + + // If the user started the drag with a mousedown on the handle, give it a 5-pixel delay. + if (dragStartPosition !== null) { + if (position > (dragStartPosition + 5) || position < (dragStartPosition - 5)) { + dragStartPosition = null; + disableClick = true; + } else { + e.preventDefault(); + return false; } - currentSplitter.setPosition(pageX - currentSplitter.offset().left - currentSplitter.splitterSizeHalf); + } + + if (currentSplitter.settings.vertical) { + currentSplitter.setPosition(position - currentSplitter.offset().left - currentSplitter.splitterSizeHalf); } else { - var pageY = e.pageY; - if (e.originalEvent && e.originalEvent.changedTouches) { - pageY = e.originalEvent.changedTouches[0].pageY; - } - currentSplitter.setPosition(pageY - currentSplitter.offset().top - currentSplitter.splitterSizeHalf); + currentSplitter.setPosition(position - currentSplitter.offset().top - currentSplitter.splitterSizeHalf); } e.preventDefault(); - currentSplitter.settings.onDrag(e); + currentSplitter.settings.onDrag(e, currentSplitter); } - }); + } + ); } self.settings = settings; - // Initial position of the splitter itself. + // Set the initial position of the splitter. self.setPosition(self.translatePosition(settings.position)); self.data('splitter', self); - splitters.push(self); return self; }; -})(jQuery); +}) +(jQuery); diff --git a/package.json b/package.json new file mode 100644 index 0000000..db48341 --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "jquery.enhsplitter", + "version": "1.2.0", + "description": "Enhanced splitter bar for separation of content, tool bars, frame emulation, and more.", + "main": "js/jquery.enhsplitter.js", + "scripts": { + "test": "" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/hiltonjanfield/jquery.enhsplitter.git" + }, + "keywords": [ + "jquery-plugin", + "ecosystem:jquery", + "splitter", + "frames", + "frameset", + "divider" + ], + "author": "Hilton Janfield", + "license": "GPL-3.0", + "bugs": { + "url": "https://github.com/hiltonjanfield/jquery.enhsplitter/issues" + }, + "homepage": "https://github.com/hiltonjanfield/jquery.enhsplitter#readme" +} diff --git a/test.html b/test.html new file mode 100644 index 0000000..e74ebcd --- /dev/null +++ b/test.html @@ -0,0 +1,185 @@ + + + + + jQuery Splitter Features Test + + + + + + + + + + + + +

jquery.enhsplitter Features Tests

+ +

+ Demo and Documentation. + This test file uses jQuery 1.8.0, the minimum required version, to ensure there are no version compatibility breaks. +

+ + + + +