Compare commits

...

17 Commits

Author SHA1 Message Date
IagoLast
f2b66c76ad 0.6.17 2018-05-10 16:01:24 +02:00
IagoLast
85009c34cd Add release scripts 2018-05-10 16:01:15 +02:00
Ivan Malagon
7e39eb3d68 Hotfix for IE & Firefox bug 2017-09-07 19:10:54 +02:00
Javier Álvarez Medina
085cd7abdd Merge pull request #2 from CartoDB/bug-in-microsoft-edge
Don't try to get the class attribute if function is not available
2017-03-01 15:37:18 +01:00
xavijam
6edd7a183c Don't try to get the class attribute if function is not available 2017-03-01 11:46:44 +01:00
Buti
735c6c0bf3 Merge pull request #1 from CartoDB/touchmove
Avoid to process touchmove event if target has class ps-prevent-touch…
2017-02-14 11:02:53 +01:00
nobuti
553756b346 Avoid to process touchmove event if target has class ps-prevent-touchmove.
This allow us to filter histogram widgets inside ps when touch events happen.
2017-02-13 15:53:34 +01:00
nobuti
4707acc287 Dom changed event.
Updated docs.
2017-01-18 20:14:23 +01:00
Buti
5f0a423128 Merge pull request #1 from nobuti/autoupdate
Autoupdate
2017-01-16 13:05:29 +01:00
nobuti
6d2c6ac8ec Removed old code. 2017-01-12 10:03:37 +01:00
nobuti
d1340f1b85 Debounce FTW. 2017-01-12 09:46:53 +01:00
nobuti
4a988b5a21 iframe resize handler based takes too memory. Back to window.resize old school. 2017-01-12 09:25:17 +01:00
nobuti
1a39d76e48 Better remove resizer. 2017-01-12 07:07:59 +01:00
nobuti
9fc34100df Wait until load to bind the resize handler. 2017-01-12 05:59:31 +01:00
nobuti
d74bdcccec Autoupdate.
It listens new elements addition and element resize in order to trigger the update method to redraw
the scroll.
2017-01-12 05:32:50 +01:00
Hyunje Jun
5f34edc8c7 Merge pull request #603 from luckyorange/master
Replaced obj.constructor with Array.isArray
2017-01-11 00:59:45 +09:00
Hayden Gascoigne
9c485584b9 Replaced obj.constructor with Array.isArray 2017-01-09 13:44:32 -06:00
11 changed files with 194 additions and 43 deletions

View File

@@ -121,7 +121,7 @@ keep in mind when you'd like to change the CSS files.
* the scrollbar's position must be 'absolute'.
* the scrollbar-x must have a 'bottom' css style, and the scrollbar-y
must have a 'right' css style.
Please keep in mind that perfect-scrollbar won't completely emulate native
scrolls. Scroll hooking is generally considered as bad practice, and
perfect-scrollbar should be used with care. Unless custom scroll is really needed,
@@ -288,52 +288,56 @@ imgLoader.perfectScrollbar();
perfect-scrollbar supports optional parameters.
### handlers
It is a list of handlers to use to scroll the element.
**Default**: `['click-rail', 'drag-scrollbar', 'keyboard', 'wheel', 'touch']`
It is a list of handlers to use to scroll the element.
**Default**: `['click-rail', 'drag-scrollbar', 'keyboard', 'wheel', 'touch']`
**Disabled by default**: `'selection'`
### wheelSpeed
The scroll speed applied to mousewheel event.
The scroll speed applied to mousewheel event.
**Default**: `1`
### wheelPropagation
If this option is true, when the scroll reaches the end of the side, mousewheel event will be propagated to parent element.
If this option is true, when the scroll reaches the end of the side, mousewheel event will be propagated to parent element.
**Default**: `false`
### swipePropagation
If this option is true, when the scroll reaches the end of the side, touch scrolling will be propagated to parent element.
If this option is true, when the scroll reaches the end of the side, touch scrolling will be propagated to parent element.
**Default**: `true`
### minScrollbarLength
When set to an integer value, the thumb part of the scrollbar will not shrink below that number of pixels.
When set to an integer value, the thumb part of the scrollbar will not shrink below that number of pixels.
**Default**: `null`
### maxScrollbarLength
When set to an integer value, the thumb part of the scrollbar will not expand over that number of pixels.
When set to an integer value, the thumb part of the scrollbar will not expand over that number of pixels.
**Default**: `null`
### useBothWheelAxes
When set to true, and only one (vertical or horizontal) scrollbar is visible then both vertical and horizontal scrolling will affect the scrollbar.
When set to true, and only one (vertical or horizontal) scrollbar is visible then both vertical and horizontal scrolling will affect the scrollbar.
**Default**: `false`
### suppressScrollX
When set to true, the scroll bar in X axis will not be available, regardless of the content width.
When set to true, the scroll bar in X axis will not be available, regardless of the content width.
**Default**: `false`
### suppressScrollY
When set to true, the scroll bar in Y axis will not be available, regardless of the content height.
When set to true, the scroll bar in Y axis will not be available, regardless of the content height.
**Default**: `false`
### scrollXMarginOffset
The number of pixels the content width can surpass the container width without enabling the X axis scroll bar. Allows some "wiggle room" or "offset break", so that X axis scroll bar is not enabled just because of a few pixels.
The number of pixels the content width can surpass the container width without enabling the X axis scroll bar. Allows some "wiggle room" or "offset break", so that X axis scroll bar is not enabled just because of a few pixels.
**Default**: `0`
### scrollYMarginOffset
The number of pixels the content height can surpass the container height without enabling the Y axis scroll bar. Allows some "wiggle room" or "offset break", so that Y axis scroll bar is not enabled just because of a few pixels.
The number of pixels the content height can surpass the container height without enabling the Y axis scroll bar. Allows some "wiggle room" or "offset break", so that Y axis scroll bar is not enabled just because of a few pixels.
**Default**: `0`
### autoupdate
When set to true, the scroll will be updated when an element is added or removed from the content.
**Default**: `true`
### theme
A string. It's a class name added to the container element. The class name is prepended with `ps-theme-`. So default theme class name is `ps-theme-default`. In order to create custom themes with scss use `ps-container($theme)` mixin, where `$theme` is a scss map.
A string. It's a class name added to the container element. The class name is prepended with `ps-theme-`. So default theme class name is `ps-theme-default`. In order to create custom themes with scss use `ps-container($theme)` mixin, where `$theme` is a scss map.
**Default**: `'default'`
**Example 1:**
@@ -396,6 +400,9 @@ This event fires when scrolling reaches the start of the x-axis.
### ps-x-reach-end
This event fires when scrolling reaches the end of the x-axis.
### ps-dom-change
This event fires when dom elements have been added to or removed from the content.
You can listen to these events either with vanilla JavaScript
```javascript
document.addEventListener('ps-scroll-x', function () {
@@ -413,7 +420,7 @@ $(document).on('ps-scroll-x', function () {
### Scrolling children inside perfect-scrollbar
You can natively scroll children inside `perfect-scrollbar` with the mouse-wheel. Scrolling automatically works if
You can natively scroll children inside `perfect-scrollbar` with the mouse-wheel. Scrolling automatically works if
the child is a `textarea`. All other elements need to have the `ps-child` class. This is demonstrated in [`/examples/children-native-scroll.html`](examples/children-native-scroll.html)
## IE Support

View File

@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>perfect-scrollbar example</title>
<link href="../dist/css/perfect-scrollbar.css" rel="stylesheet">
<script src="../dist/js/perfect-scrollbar.js"></script>
<style>
.contentHolder { position:relative; margin:0px auto; padding:0px; width: 80%; height: 400px; overflow: auto; }
.always-visible.contentHolder .content { background-image: url('./azusa.jpg'); width: 680px; height: 320px; }
.spacer { text-align:center }
.always-visible.ps-container > .ps-scrollbar-x-rail,
.always-visible.ps-container > .ps-scrollbar-y-rail {
opacity: 0.6;
}
</style>
</head>
<body>
<div id="Default" class="contentHolder always-visible">
<div id="Content" class="content">
</div>
</div>
<p style='text-align: center'>
<button onclick='addContent()'>Add new content!</button>
<button onclick='removeContent()'>Remove content!</button>
</p>
<script>
var i = 1;
var $ = document.querySelector.bind(document);
window.onload = function () {
Ps.initialize($('#Default'), {
autoupdate: true
});
};
var addContent = function () {
var newDiv = document.createElement('div');
newDiv.id = 'node' + i++;
var newContent = document.createTextNode('Hi there!');
newDiv.appendChild(newContent);
$('#Default').insertBefore(newDiv, $('#Content'));
};
var removeContent = function () {
if (i <= 1) return;
var node = $('#node' + --i);
node.parentNode.removeChild(node);
};
</script>
</body>
</html>

View File

@@ -1,6 +1,6 @@
{
"name": "perfect-scrollbar",
"version": "0.6.16",
"version": "0.6.17",
"description": "Minimalistic but perfect custom scrollbar plugin",
"author": "Hyunje Jun <me@noraesae.net>",
"contributors": [
@@ -57,7 +57,11 @@
"scripts": {
"test": "gulp",
"before-deploy": "gulp && gulp compress",
"release": "rm -rf dist && gulp && npm publish"
"release": "rm -rf dist && gulp && npm publish",
"bump": "npm version patch",
"bump:major": "npm version major",
"bump:minor": "npm version minor",
"postversion": "git push origin master --follow-tags"
},
"license": "MIT"
}

View File

@@ -14,7 +14,10 @@ DOM.appendTo = function (child, parent) {
};
function cssGet(element, styleName) {
return window.getComputedStyle(element)[styleName];
var style = window.getComputedStyle(element);
return style
? style[styleName]
: null;
}
function cssSet(element, styleName, styleValue) {

View File

@@ -10,7 +10,7 @@ var toInt = exports.toInt = function (x) {
var clone = exports.clone = function (obj) {
if (!obj) {
return null;
} else if (obj.constructor === Array) {
} else if (Array.isArray(obj)) {
return obj.map(clone);
} else if (typeof obj === 'object') {
var result = {};
@@ -23,6 +23,26 @@ var clone = exports.clone = function (obj) {
}
};
exports.debounce = function (func, wait, immediate) {
var timeout;
return function () {
var context = this;
var args = arguments;
var later = function () {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
};
exports.extend = function (original, source) {
var result = clone(original);
for (var key in source) {

View File

@@ -0,0 +1,30 @@
'use strict';
var update = require('./update');
var MutationObserver = window.MutationObserver;
var instances = require('./instances');
var createDOMEvent = function (name) {
var event = document.createEvent('Event');
event.initEvent(name, true, true);
return event;
};
module.exports = function (element) {
if (MutationObserver === null || MutationObserver === undefined) {
// MutationObserver is not supported
return;
}
var i = instances.get(element);
var onMutationObserver = function () {
update(element);
element.dispatchEvent(createDOMEvent('ps-dom-change'));
};
i.observer = new MutationObserver(onMutationObserver);
onMutationObserver();
var config = { childList: true, subtree: true };
i.observer.observe(element, config);
};

View File

@@ -12,5 +12,6 @@ module.exports = {
useBothWheelAxes: false,
wheelPropagation: false,
wheelSpeed: 1,
theme: 'default'
theme: 'default',
autoupdate: true
};

View File

@@ -11,6 +11,10 @@ module.exports = function (element) {
return;
}
if (i.observer) {
i.observer.disconnect();
}
i.event.unbindAll();
dom.remove(i.scrollbarX);
dom.remove(i.scrollbarY);

View File

@@ -88,32 +88,37 @@ function bindTouchHandler(element, i, supportsTouch, supportsIePointer) {
}
}
function touchMove(e) {
if (!inLocalTouch && i.settings.swipePropagation) {
touchStart(e);
}
if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
var touch = getTouch(e);
var target = e.target;
var className = target && target.getAttribute && target.getAttribute('class') || '';
var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};
var differenceX = currentOffset.pageX - startOffset.pageX;
var differenceY = currentOffset.pageY - startOffset.pageY;
applyTouchMove(differenceX, differenceY);
startOffset = currentOffset;
var currentTime = (new Date()).getTime();
var timeGap = currentTime - startTime;
if (timeGap > 0) {
speed.x = differenceX / timeGap;
speed.y = differenceY / timeGap;
startTime = currentTime;
if (!className.match(/ps-prevent-touchmove/)) {
if (!inLocalTouch && i.settings.swipePropagation) {
touchStart(e);
}
if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
var touch = getTouch(e);
if (shouldPreventDefault(differenceX, differenceY)) {
e.stopPropagation();
e.preventDefault();
var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};
var differenceX = currentOffset.pageX - startOffset.pageX;
var differenceY = currentOffset.pageY - startOffset.pageY;
applyTouchMove(differenceX, differenceY);
startOffset = currentOffset;
var currentTime = (new Date()).getTime();
var timeGap = currentTime - startTime;
if (timeGap > 0) {
speed.x = differenceX / timeGap;
speed.y = differenceY / timeGap;
startTime = currentTime;
}
if (shouldPreventDefault(differenceX, differenceY)) {
e.stopPropagation();
e.preventDefault();
}
}
}
}

View File

@@ -4,6 +4,8 @@ var _ = require('../lib/helper');
var cls = require('../lib/class');
var instances = require('./instances');
var updateGeometry = require('./update-geometry');
var autoupdate = require('./autoupdate');
var resizer = require('./resizer');
// Handlers
var handlers = {
@@ -34,4 +36,9 @@ module.exports = function (element, userSettings) {
nativeScrollHandler(element);
updateGeometry(element);
if (i.settings.autoupdate) {
autoupdate(element);
resizer(element);
}
};

15
src/js/plugin/resizer.js Normal file
View File

@@ -0,0 +1,15 @@
'use strict';
var update = require('./update');
var instances = require('./instances');
var _ = require('../lib/helper');
module.exports = function (element) {
var i = instances.get(element);
var onResize = function () {
update(element);
};
i.event.bind(window, 'resize', _.debounce(onResize, 60));
};