From 3b90c734e4d16cc4ec834af7166e48abdc338f96 Mon Sep 17 00:00:00 2001 From: DanielApt Date: Wed, 23 Sep 2015 20:49:37 +0100 Subject: [PATCH 1/4] Dispatch custom scroll events with new updateScroll function --- src/js/plugin/handler/click-rail.js | 7 +- src/js/plugin/handler/drag-scrollbar.js | 7 +- src/js/plugin/handler/keyboard.js | 7 +- src/js/plugin/handler/mouse-wheel.js | 15 +++-- src/js/plugin/handler/selection.js | 7 +- src/js/plugin/handler/touch.js | 7 +- src/js/plugin/update-geometry.js | 5 +- src/js/plugin/update-scroll.js | 85 +++++++++++++++++++++++++ 8 files changed, 116 insertions(+), 24 deletions(-) create mode 100644 src/js/plugin/update-scroll.js diff --git a/src/js/plugin/handler/click-rail.js b/src/js/plugin/handler/click-rail.js index ddb7d74..c08ba05 100644 --- a/src/js/plugin/handler/click-rail.js +++ b/src/js/plugin/handler/click-rail.js @@ -5,7 +5,8 @@ var h = require('../../lib/helper') , instances = require('../instances') - , updateGeometry = require('../update-geometry'); + , updateGeometry = require('../update-geometry') + , updateScroll = require('../update-scroll'); function bindClickRailHandler(element, i) { function pageOffset(el) { @@ -28,7 +29,7 @@ function bindClickRailHandler(element, i) { positionRatio = 1; } - element.scrollTop = (i.contentHeight - i.containerHeight) * positionRatio; + updateScroll(element, 'top', (i.contentHeight - i.containerHeight) * positionRatio); updateGeometry(element); e.stopPropagation(); @@ -49,7 +50,7 @@ function bindClickRailHandler(element, i) { positionRatio = 1; } - element.scrollLeft = ((i.contentWidth - i.containerWidth) * positionRatio) - i.negativeScrollAdjustment; + updateScroll(element, 'left', ((i.contentWidth - i.containerWidth) * positionRatio) - i.negativeScrollAdjustment); updateGeometry(element); e.stopPropagation(); diff --git a/src/js/plugin/handler/drag-scrollbar.js b/src/js/plugin/handler/drag-scrollbar.js index d26f862..060b30a 100644 --- a/src/js/plugin/handler/drag-scrollbar.js +++ b/src/js/plugin/handler/drag-scrollbar.js @@ -6,7 +6,8 @@ var d = require('../../lib/dom') , h = require('../../lib/helper') , instances = require('../instances') - , updateGeometry = require('../update-geometry'); + , updateGeometry = require('../update-geometry') + , updateScroll = require('../update-scroll'); function bindMouseScrollXHandler(element, i) { var currentLeft = null; @@ -25,7 +26,7 @@ function bindMouseScrollXHandler(element, i) { } var scrollLeft = h.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))) - i.negativeScrollAdjustment; - element.scrollLeft = scrollLeft; + updateScroll(element, 'left', scrollLeft); } var mouseMoveHandler = function (e) { @@ -70,7 +71,7 @@ function bindMouseScrollYHandler(element, i) { } var scrollTop = h.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight))); - element.scrollTop = scrollTop; + updateScroll(element, 'top', scrollTop); } var mouseMoveHandler = function (e) { diff --git a/src/js/plugin/handler/keyboard.js b/src/js/plugin/handler/keyboard.js index b7774da..3fc8155 100644 --- a/src/js/plugin/handler/keyboard.js +++ b/src/js/plugin/handler/keyboard.js @@ -5,7 +5,8 @@ var h = require('../../lib/helper') , instances = require('../instances') - , updateGeometry = require('../update-geometry'); + , updateGeometry = require('../update-geometry') + , updateScroll = require('../update-scroll'); function bindKeyboardHandler(element, i) { var hovered = false; @@ -107,8 +108,8 @@ function bindKeyboardHandler(element, i) { return; } - element.scrollTop = element.scrollTop - deltaY; - element.scrollLeft = element.scrollLeft + deltaX; + updateScroll(element, 'top', element.scrollTop - deltaY); + updateScroll(element, 'left', element.scrollLeft + deltaX); updateGeometry(element); shouldPrevent = shouldPreventDefault(deltaX, deltaY); diff --git a/src/js/plugin/handler/mouse-wheel.js b/src/js/plugin/handler/mouse-wheel.js index a465f8c..5b85089 100644 --- a/src/js/plugin/handler/mouse-wheel.js +++ b/src/js/plugin/handler/mouse-wheel.js @@ -5,7 +5,8 @@ var h = require('../../lib/helper') , instances = require('../instances') - , updateGeometry = require('../update-geometry'); + , updateGeometry = require('../update-geometry') + , updateScroll = require('../update-scroll'); function bindMouseWheelHandler(element, i) { var shouldPrevent = false; @@ -100,24 +101,24 @@ function bindMouseWheelHandler(element, i) { if (!i.settings.useBothWheelAxes) { // deltaX will only be used for horizontal scrolling and deltaY will // only be used for vertical scrolling - this is the default - element.scrollTop = element.scrollTop - (deltaY * i.settings.wheelSpeed); - element.scrollLeft = element.scrollLeft + (deltaX * i.settings.wheelSpeed); + updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed)); + updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed)); } else if (i.scrollbarYActive && !i.scrollbarXActive) { // only vertical scrollbar is active and useBothWheelAxes option is // active, so let's scroll vertical bar using both mouse wheel axes if (deltaY) { - element.scrollTop = element.scrollTop - (deltaY * i.settings.wheelSpeed); + updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed)); } else { - element.scrollTop = element.scrollTop + (deltaX * i.settings.wheelSpeed); + updateScroll(element, 'top', element.scrollTop + (deltaX * i.settings.wheelSpeed)); } shouldPrevent = true; } else if (i.scrollbarXActive && !i.scrollbarYActive) { // useBothWheelAxes and only horizontal bar is active, so use both // wheel axes for horizontal bar if (deltaX) { - element.scrollLeft = element.scrollLeft + (deltaX * i.settings.wheelSpeed); + updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed)); } else { - element.scrollLeft = element.scrollLeft - (deltaY * i.settings.wheelSpeed); + updateScroll(element, 'left', element.scrollLeft - (deltaY * i.settings.wheelSpeed)); } shouldPrevent = true; } diff --git a/src/js/plugin/handler/selection.js b/src/js/plugin/handler/selection.js index 774d8f0..50080e1 100644 --- a/src/js/plugin/handler/selection.js +++ b/src/js/plugin/handler/selection.js @@ -5,7 +5,8 @@ var h = require('../../lib/helper') , instances = require('../instances') - , updateGeometry = require('../update-geometry'); + , updateGeometry = require('../update-geometry') + , updateScroll = require('../update-scroll'); function bindSelectionHandler(element, i) { function getRangeNode() { @@ -28,8 +29,8 @@ function bindSelectionHandler(element, i) { return; } - element.scrollTop = element.scrollTop + scrollDiff.top; - element.scrollLeft = element.scrollLeft + scrollDiff.left; + updateScroll(element, 'top', element.scrollTop + scrollDiff.top); + updateScroll(element, 'left', element.scrollLeft + scrollDiff.left); updateGeometry(element); }, 50); // every .1 sec } diff --git a/src/js/plugin/handler/touch.js b/src/js/plugin/handler/touch.js index 0b5ceb4..b241384 100644 --- a/src/js/plugin/handler/touch.js +++ b/src/js/plugin/handler/touch.js @@ -4,7 +4,8 @@ 'use strict'; var instances = require('../instances') - , updateGeometry = require('../update-geometry'); + , updateGeometry = require('../update-geometry') + , updateScroll = require('../update-scroll'); function bindTouchHandler(element, i, supportsTouch, supportsIePointer) { function shouldPreventDefault(deltaX, deltaY) { @@ -33,8 +34,8 @@ function bindTouchHandler(element, i, supportsTouch, supportsIePointer) { } function applyTouchMove(differenceX, differenceY) { - element.scrollTop = element.scrollTop - differenceY; - element.scrollLeft = element.scrollLeft - differenceX; + updateScroll(element, 'top', element.scrollTop - differenceY); + updateScroll(element, 'left', element.scrollLeft - differenceX); updateGeometry(element); } diff --git a/src/js/plugin/update-geometry.js b/src/js/plugin/update-geometry.js index af8adb9..8dce8d7 100644 --- a/src/js/plugin/update-geometry.js +++ b/src/js/plugin/update-geometry.js @@ -6,7 +6,8 @@ var cls = require('../lib/class') , d = require('../lib/dom') , h = require('../lib/helper') - , instances = require('./instances'); + , instances = require('./instances') + , updateScroll = require('./update-scroll'); function getThumbSize(i, thumbSize) { if (i.settings.minScrollbarLength) { @@ -103,7 +104,7 @@ module.exports = function (element) { i.scrollbarYActive = false; i.scrollbarYHeight = 0; i.scrollbarYTop = 0; - element.scrollTop = 0; + updateScroll(element, 'top', 0); } if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) { diff --git a/src/js/plugin/update-scroll.js b/src/js/plugin/update-scroll.js new file mode 100644 index 0000000..02e7455 --- /dev/null +++ b/src/js/plugin/update-scroll.js @@ -0,0 +1,85 @@ +/* Copyright (c) 2015 Hyunje Alex Jun and other contributors + * Licensed under the MIT License + */ +'use strict'; + +var instances = require('./instances'); + +var upEvent = document.createEvent('Event') + , downEvent = document.createEvent('Event') + , leftEvent = document.createEvent('Event') + , rightEvent = document.createEvent('Event') + , yEvent = document.createEvent('Event') + , xEvent = document.createEvent('Event') + , lastTop + , lastLeft; + +upEvent.initEvent('ps-scroll-up', true, true); +downEvent.initEvent('ps-scroll-down', true, true); +leftEvent.initEvent('ps-scroll-left', true, true); +rightEvent.initEvent('ps-scroll-right', true, true); +yEvent.initEvent('ps-scroll-y', true, true); +xEvent.initEvent('ps-scroll-x', true, true); + +module.exports = function (element, axis, value) { + if (typeof element === 'undefined' ) { + throw 'You must provide an element to the update-scroll function'; + } + + if (typeof axis === 'undefined') { + throw 'You must provide an axis to the update-scroll function'; + } + + if (typeof value === 'undefined') { + throw 'You must provide a value to the update-scroll function' + } + + if (value < 0) { + return; // don't allow negative scroll + } + + var i = instances.get(element); + + if (axis === 'top' && value > i.contentHeight - i.containerHeight) { + return; // don't allow scroll past container + } + + if (axis === 'left' && value > i.contentWidth - i.containerWidth) { + return; // don't allow scroll past container + } + + if (!lastTop) { + lastTop = element.scrollTop; + } + + if (!lastLeft) { + lastLeft = element.scrollLeft; + } + + if (axis === 'top' && value < lastTop) { + element.dispatchEvent(upEvent); + } + + if (axis === 'top' && value > lastTop) { + element.dispatchEvent(downEvent); + } + + if (axis === 'left' && value < lastLeft) { + element.dispatchEvent(leftEvent); + } + + if (axis === 'left' && value > lastLeft) { + element.dispatchEvent(rightEvent); + } + + if (axis === 'top') { + element.scrollTop = lastTop = value; + element.dispatchEvent(yEvent); + } + + if (axis === 'left') { + element.scrollLeft = lastLeft = value; + element.dispatchEvent(xEvent); + } + +}; From 2ef7e81ce99fd02dfc4feec556ca53d9bfbcd614 Mon Sep 17 00:00:00 2001 From: DanielApt Date: Wed, 23 Sep 2015 21:05:28 +0100 Subject: [PATCH 2/4] Add Events to the README --- README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/README.md b/README.md index 0caa420..b70d6df 100644 --- a/README.md +++ b/README.md @@ -312,6 +312,41 @@ The number of pixels the content height can surpass the container height without When set to false, when clicking on a rail, the click event will be allowed to propagate. **Default: true** +## Events + +perfect-scrollbar dispatches custom events. + +### ps-scroll-y +This event fires when the y-axis is scrolled in either direction. + +### ps-scroll-x +This event fires when the x-axis is scrolled in either direction. + +### ps-scroll-up +This event fires when scrolling upwards. + +### ps-scroll-down +This event fires when scrolling downwards. + +### ps-scroll-left +This event fires when scrolling to the left. + +### ps-scroll-right +This event fires when scrolling to the right. + +You can listen to these events either with vanilla JavaScript +```javascript +document.addEventListener('ps-scroll-x', function () { + // ... +} +``` +or with jQuery +```javascript +$(document).on('ps-scroll-x', function () { + // ... +} +``` + ## Contribution #### Please read [Contributing](https://github.com/noraesae/perfect-scrollbar/wiki/Contributing) in the wiki before making any contribution. From 6c5b9d249eb7480ee907ef7b49bb84e18e883fed Mon Sep 17 00:00:00 2001 From: DanielApt Date: Thu, 24 Sep 2015 09:53:59 +0100 Subject: [PATCH 3/4] Add missing parentheses --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b70d6df..46e5f78 100644 --- a/README.md +++ b/README.md @@ -338,13 +338,13 @@ You can listen to these events either with vanilla JavaScript ```javascript document.addEventListener('ps-scroll-x', function () { // ... -} +}) ``` or with jQuery ```javascript $(document).on('ps-scroll-x', function () { // ... -} +}) ``` ## Contribution From 39893fc6f2da5568aa8cccb9f47364bb33eecb26 Mon Sep 17 00:00:00 2001 From: DanielApt Date: Thu, 24 Sep 2015 11:02:33 +0100 Subject: [PATCH 4/4] Add example for events --- examples/events.html | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 examples/events.html diff --git a/examples/events.html b/examples/events.html new file mode 100644 index 0000000..6de5cff --- /dev/null +++ b/examples/events.html @@ -0,0 +1,70 @@ + + + + + perfect-scrollbar example + + + + + +
+
+
+
+ +

Axis

+ +

Direction

+ + +