Compare commits

...

30 Commits
0.6.3 ... 0.6.6

Author SHA1 Message Date
Hyunje Alex Jun
d6ede33202 Release 0.6.6
1. Add custom events
2. Support higher Node.js versions
3. Add useSelectionScroll option
4. Bug fixes
2015-10-03 21:44:26 +09:00
Hyunje Alex Jun
1c3b409d12 Remove 'bump' and 'release' tasks from gulpfile.js
There is only one JSON left for the project and it's better to bump the
version manually.
2015-10-03 21:43:59 +09:00
Hyunje Alex Jun
17e5f67519 Make selection scroll optional
It's not essential but rather causes several problems.
2015-10-03 21:37:24 +09:00
Hyunje Alex Jun
002034fd54 Return an Array object from class.list
To fix #383
2015-10-03 21:21:56 +09:00
Hyunje Alex Jun
8761735a54 Update Travis CI and NPM configuration
To be compatible with their newest versions.
2015-10-03 21:16:23 +09:00
Hyunje Alex Jun
c285521caa Lint update-scroll.js
With the new .eslintrc
2015-10-03 20:45:38 +09:00
Hyunje Alex Jun
3d2d50c308 Update .eslintrc
To make it compatible with new versions of ESLint and specify other
options.
2015-10-03 20:44:38 +09:00
DanielApt
a0d39e1b49 Make sure scroll is at the start/end when the reach start/end event fires 2015-09-29 15:28:58 +01:00
DanielApt
e288476ba0 Update README.md with new events 2015-09-28 11:13:25 +01:00
DanielApt
e9bc40bd37 Update events example to show new reach events 2015-09-28 11:09:51 +01:00
DanielApt
0b8fe0ac0b Dispatch events when reaching start / end of axes 2015-09-28 11:08:59 +01:00
Jun
a3676556b2 Merge pull request #386 from DanielApt/events
Dispatch scroll events
2015-09-24 19:44:31 +09:00
DanielApt
39893fc6f2 Add example for events 2015-09-24 11:02:33 +01:00
DanielApt
6c5b9d249e Add missing parentheses 2015-09-24 09:53:59 +01:00
DanielApt
2ef7e81ce9 Add Events to the README 2015-09-23 21:05:28 +01:00
DanielApt
3b90c734e4 Dispatch custom scroll events with new updateScroll function 2015-09-23 20:49:37 +01:00
Hyunje Alex Jun
afebe908b1 NPM version bump.
https://github.com/npm/npm-registry-couchapp/issues/148
2015-08-18 04:16:20 +09:00
Hyunje Alex Jun
6cbb4a9b9d Release 0.6.5
1. Add shift+space support.
2. Bug fixes.
2015-08-18 03:54:56 +09:00
Hyunje Alex Jun
51f33a44b5 Remove unused garbage rails before append a new one.
This patch fixes #376.
2015-08-18 03:51:12 +09:00
Hyunje Alex Jun
8eac54d49f Add a queryChildren method to dom.js 2015-08-18 03:26:15 +09:00
Hyunje Alex Jun
ed4e335978 Declare a module object DOM in dom.js
To refer in the sibling methods.
2015-08-18 03:23:27 +09:00
Jun
272bb4983a Merge pull request #379 from srcn/master
Add shift+space support for keyboard
2015-08-17 21:43:02 +09:00
srcn
f200bea4cc add shift+space support for keyboard 2015-08-17 15:19:30 +03:00
Hyunje Alex Jun
b1d7aa0e64 Release 0.6.4
1. Add null-check for instances.
2. Add 'stopPropgationOnClick' option.
2015-07-25 02:28:12 +09:00
Hyunje Alex Jun
49e39f513d Update README.md 2015-07-25 02:26:55 +09:00
Jun
89f4226778 Merge pull request #366 from dorilla/feature/stop-propagation-on-click
Allow the clicking of a rail to propagate
2015-07-25 02:23:42 +09:00
Dan Maglasang
79f4cfcf5f Update README.md 2015-07-22 22:47:33 -04:00
Dan Maglasang
158b113d18 Allow the clicking of a rail to propagate 2015-07-22 22:43:38 -04:00
Hyunje Alex Jun
6c642d8a47 Just early return instead of throwing an error for no instance. 2015-07-14 12:22:40 +09:00
Hyunje Alex Jun
f9f20eeb6f Add null-check when updating or destroying an instance.
Throw an error when an instance is not found.
2015-07-07 15:25:16 +09:00
22 changed files with 444 additions and 186 deletions

View File

@@ -1,5 +1,5 @@
{
"env" : {
"env": {
"node": true,
"browser": true
},
@@ -7,14 +7,34 @@
"$": true,
"define": true
},
"rules" : {
"quotes": false,
"space-after-keywords": [2, "always", {"checkFunctionKeyword": true}],
"extends": "eslint:recommended",
"rules": {
"eqeqeq": 2,
"no-multi-spaces": 2,
"curly": 2,
"semi": 2,
"no-with": 2,
"strict": [2, "global"],
"radix": 2,
"no-use-before-define": 2,
"block-spacing": 2,
"brace-style": [2, "1tbs", {"allowSingleLine": true}],
"camelcase": 2,
"comma-spacing": [2, {"before": false, "after": true}],
"eol-last": 2,
"no-multiple-empty-lines": 2,
"indent": [2, 2],
"key-spacing": [2, {"beforeColon": false, "afterColon": true}],
"linebreak-style": [2, "unix"],
"new-parens": 2,
"no-trailing-spaces": 2,
"semi-spacing": 2,
"space-before-blocks": [2, "always"],
"brace-style": [2, "1tbs", { "allowSingleLine": false}],
"spaced-line-comment": [2, "always"],
"radix": [2, "always"],
"key-spacing": [2, "always", {"beforeColon": false, "afterColon": true}],
"no-multiple-empty-lines": [2, {max: 1}],
"space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
"space-in-parens": 2,
"space-infix-ops": 2,
"space-return-throw-case": 2,
"space-unary-ops": 2,
"spaced-comment": 2
}
}

View File

@@ -1,8 +1,7 @@
language: node_js
node_js:
- '0.10'
before_script:
- npm install -g gulp
- 0.12
- 4
deploy:
provider: releases
api_key:
@@ -13,5 +12,4 @@ deploy:
branch: master
tags: true
before_deploy:
- gulp
- gulp compress
- npm run before-deploy

View File

@@ -308,6 +308,61 @@ The number of pixels the content width can surpass the container width without e
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**
### stopPropagationOnClick
When set to false, when clicking on a rail, the click event will be allowed to propagate.
**Default: true**
### useSelectionScroll
When set to true, you can scroll the container by selecting text and move the cursor.
**Default: false**
## 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.
### ps-y-reach-start
This event fires when scrolling reaches the start of the y-axis.
### ps-y-reach-end
This event fires when scrolling reaches the end of the y-axis (useful for infinite scroll).
### ps-x-reach-start
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.
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.

89
examples/events.html Normal file
View File

@@ -0,0 +1,89 @@
<!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>
p {
text-align: center;
}
.container {
position: relative;
margin: 0px auto;
padding: 0px;
width: 600px;
height: 400px;
overflow: auto;
}
.container .content {
background-image: url('./azusa.jpg');
width: 1280px;
height: 720px;
}
</style>
</head>
<body>
<div class="container">
<div class="content">
</div>
</div>
<p><strong>Axis</strong> <span id="axis">&hellip;</span></p>
<p><strong>Direction</strong> <span id="direction">&hellip;</span></p>
<p><strong>Start / End</strong> <span id="start-end">(scroll to the start or end of an axis)</span></p>
<script>
var container = document.querySelector('.container')
, axis = document.getElementById('axis')
, direction = document.getElementById('direction')
, startEnd = document.getElementById('start-end');
Ps.initialize(container);
document.addEventListener('ps-scroll-y', function () {
axis.innerHTML = 'Y Axis';
});
document.addEventListener('ps-scroll-x', function () {
axis.innerHTML = 'X Axis';
});
document.addEventListener('ps-scroll-up', function () {
direction.innerHTML = 'up';
});
document.addEventListener('ps-scroll-down', function () {
direction.innerHTML = 'down';
});
document.addEventListener('ps-scroll-left', function () {
direction.innerHTML = 'left';
});
document.addEventListener('ps-scroll-right', function () {
direction.innerHTML = 'right';
});
document.addEventListener('ps-y-reach-start', function () {
startEnd.innerHTML = 'Reached start of <em>Y-Axis</em>';
});
document.addEventListener('ps-y-reach-end', function () {
startEnd.innerHTML = 'Reached end of <em>Y-Axis</em>';
});
document.addEventListener('ps-x-reach-start', function () {
startEnd.innerHTML = 'Reached start of <em>X-Axis</em>';
});
document.addEventListener('ps-x-reach-end', function () {
startEnd.innerHTML = 'Reached end of <em>X-Axis</em>'
});
</script>
</body>
</html>

View File

@@ -1,53 +0,0 @@
<!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>
#description {
border: 1px solid gray;
height:150px;
width: 400px;
overflow: auto;
position: relative;
}
#status { color: red; }
</style>
</head>
<body>
<div id="description" class="wrapper">
<p>Hello, world! 0</p>
<p>Hello, world! 1</p>
<p>Hello, world! 2</p>
<p>Hello, world! 3</p>
<p>Hello, world! 4</p>
<p>Hello, world! 5</p>
<p>Hello, world! 6</p>
<p>Hello, world! 7</p>
<p>Hello, world! 8</p>
<p>Hello, world! 9</p>
</div>
<div id="status">
</div>
<script type="text/javascript">
var $ = document.querySelector.bind(document);
window.onload = function () {
var container = $('#description');
var stat = $('#status');
Ps.initialize(container);
container.addEventListener('scroll', function (e) {
if(container.scrollTop === 0) {
stat.innerHTML = 'it reaches the top!';
}
else if (container.scrollTop === container.scrollHeight - container.clientHeight) {
stat.innerHTML = 'it reaches the end!';
} else {
stat.innerHTML = '';
}
});
};
</script>
</body>
</html>

View File

@@ -32,7 +32,9 @@
<script>
var $ = document.querySelector.bind(document);
window.onload = function () {
Ps.initialize($('#description'));
Ps.initialize($('#description'), {
useSelectionScroll: true
});
};
$('#redraw').addEventListener('click', function () {
var oldHtml = $('#description').innerHTML;

View File

@@ -2,14 +2,16 @@
var gulp = require('gulp')
, browserify = require('browserify')
, bump = require('gulp-bump')
, buffer = require('vinyl-buffer')
, connect = require('gulp-connect')
, del = require('del')
, eslint = require('gulp-eslint')
, insert = require('gulp-insert')
, path = require('path')
, rename = require('gulp-rename')
, rimraf = require('gulp-rimraf')
, sass = require('gulp-sass')
, transform = require('vinyl-transform')
, source = require('vinyl-source-stream')
, stream = require('event-stream')
, uglify = require('gulp-uglify')
, zip = require('gulp-zip');
@@ -23,63 +25,66 @@ gulp.task('lint', function () {
});
gulp.task('clean:js', function () {
return gulp.src('./dist/js/*.js', {read: false})
.pipe(rimraf());
return del(['./dist/js/*.js']);
});
gulp.task('clean:js:min', function () {
return gulp.src('./dist/js/min/*.js', {read: false})
.pipe(rimraf());
return del(['./dist/js/min/*.js']);
});
function browserified() {
return transform(function (filename) {
var b = browserify(filename);
return b.bundle();
});
}
var jsEntries = [
'./src/js/adaptor/global.js',
'./src/js/adaptor/jquery.js'
];
gulp.task('js', ['clean:js'], function () {
return gulp.src('./src/js/adaptor/*.js')
.pipe(browserified())
.pipe(insert.prepend(version))
.pipe(rename(function (path) {
if (path.basename === 'global') {
path.basename = 'perfect-scrollbar';
} else {
path.basename = 'perfect-scrollbar.' + path.basename;
}
}))
.pipe(gulp.dest('./dist/js'))
.pipe(connect.reload());
var tasks = jsEntries.map(function (src) {
return browserify([src]).bundle()
.pipe(source(path.basename(src)))
.pipe(buffer())
.pipe(insert.prepend(version))
.pipe(rename(function (path) {
if (path.basename === 'global') {
path.basename = 'perfect-scrollbar';
} else {
path.basename = 'perfect-scrollbar.' + path.basename;
}
}))
.pipe(gulp.dest('./dist/js'))
.pipe(connect.reload());
});
return stream.merge.apply(null, tasks);
});
gulp.task('js:min', ['clean:js:min'], function () {
return gulp.src('./src/js/adaptor/*.js')
.pipe(browserified())
.pipe(uglify())
.pipe(insert.prepend(version))
.pipe(rename(function (path) {
if (path.basename === 'global') {
path.basename = 'perfect-scrollbar.min';
} else {
path.basename = 'perfect-scrollbar.' + path.basename + '.min';
}
}))
.pipe(gulp.dest('./dist/js/min'));
var tasks = jsEntries.map(function (src) {
return browserify([src]).bundle()
.pipe(source(path.basename(src)))
.pipe(buffer())
.pipe(uglify())
.pipe(insert.prepend(version))
.pipe(rename(function (path) {
if (path.basename === 'global') {
path.basename = 'perfect-scrollbar';
} else {
path.basename = 'perfect-scrollbar.' + path.basename;
}
}))
.pipe(gulp.dest('./dist/js/min'))
.pipe(connect.reload());
});
return stream.merge.apply(null, tasks);
});
gulp.task('clean:css', function () {
return gulp.src('./dist/css/perfect-scrollbar.css', {read: false})
.pipe(rimraf());
return del(['./dist/css/perfect-scrollbar.css']);
});
gulp.task('clean:css:min', function () {
return gulp.src('./dist/css/perfect-scrollbar.min.css', {read: false})
.pipe(rimraf());
return del(['./dist/css/perfect-scrollbar.min.css']);
});
gulp.task('sass', ['clean:css'], function () {
gulp.task('css', ['clean:css'], function () {
return gulp.src('./src/css/main.scss')
.pipe(sass())
.pipe(insert.prepend(version))
@@ -88,7 +93,7 @@ gulp.task('sass', ['clean:css'], function () {
.pipe(connect.reload());
});
gulp.task('sass:min', ['clean:css:min'], function () {
gulp.task('css:min', ['clean:css:min'], function () {
return gulp.src('./src/css/main.scss')
.pipe(sass({outputStyle: 'compressed'}))
.pipe(insert.prepend(version))
@@ -96,25 +101,7 @@ gulp.task('sass:min', ['clean:css:min'], function () {
.pipe(gulp.dest('./dist/css'));
});
function bumpType() {
if (gulp.env.major) {
return 'major';
} else if (gulp.env.minor) {
return 'minor';
} else {
return 'patch';
}
}
gulp.task('bump', function () {
gulp.src('./*.json')
.pipe(bump({type: bumpType()}))
.pipe(gulp.dest('./'));
});
gulp.task('release', ['bump', 'build']);
gulp.task('build', ['js', 'js:min', 'sass', 'sass:min']);
gulp.task('build', ['js', 'js:min', 'css', 'css:min']);
gulp.task('connect', ['build'], function () {
connect.server({
@@ -125,7 +112,7 @@ gulp.task('connect', ['build'], function () {
gulp.task('watch', function () {
gulp.watch(['src/js/**/*'], ['js']);
gulp.watch(['src/css/**/*'], ['sass']);
gulp.watch(['src/css/**/*'], ['css']);
});
gulp.task('serve', ['connect', 'watch']);

View File

@@ -1,6 +1,6 @@
{
"name": "perfect-scrollbar",
"version": "0.6.3",
"version": "0.6.6",
"description": "Minimalistic but perfect custom scrollbar plugin",
"author": "Hyunje Alex Jun <me@noraesae.net>",
"contributors": [
@@ -24,24 +24,26 @@
"scrollbar"
],
"engines": {
"node": ">= 0.8.0"
"node": ">= 0.12.0"
},
"devDependencies": {
"browserify": "^8.1.1",
"gulp": "^3.8.10",
"gulp-bump": "^0.1.11",
"browserify": "^11.2.0",
"del": "^2.0.2",
"event-stream": "^3.3.1",
"gulp": "^3.9.0",
"gulp-connect": "^2.2.0",
"gulp-eslint": "^0.2.0",
"gulp-insert": "^0.4.0",
"gulp-rename": "^1.2.0",
"gulp-rimraf": "^0.1.1",
"gulp-sass": "^1.3.1",
"gulp-uglify": "^1.0.2",
"gulp-zip": "^2.0.2",
"vinyl-transform": "^1.0.0"
"gulp-eslint": "^1.0.0",
"gulp-insert": "^0.5.0",
"gulp-rename": "^1.2.2",
"gulp-sass": "^2.0.4",
"gulp-uglify": "^1.4.1",
"gulp-zip": "^3.0.2",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0"
},
"scripts": {
"test": "gulp"
"test": "gulp",
"before-deploy": "gulp && gulp compress"
},
"license": "MIT"
}

View File

@@ -38,7 +38,7 @@ exports.remove = function (element, className) {
exports.list = function (element) {
if (element.classList) {
return element.classList;
return Array.prototype.slice.apply(element.classList);
} else {
return element.className.split(' ');
}

View File

@@ -3,13 +3,15 @@
*/
'use strict';
exports.e = function (tagName, className) {
var DOM = {};
DOM.e = function (tagName, className) {
var element = document.createElement(tagName);
element.className = className;
return element;
};
exports.appendTo = function (child, parent) {
DOM.appendTo = function (child, parent) {
parent.appendChild(child);
return child;
};
@@ -37,7 +39,7 @@ function cssMultiSet(element, obj) {
return element;
}
exports.css = function (element, styleNameOrObject, styleValue) {
DOM.css = function (element, styleNameOrObject, styleValue) {
if (typeof styleNameOrObject === 'object') {
// multiple set with object
return cssMultiSet(element, styleNameOrObject);
@@ -50,7 +52,7 @@ exports.css = function (element, styleNameOrObject, styleValue) {
}
};
exports.matches = function (element, query) {
DOM.matches = function (element, query) {
if (typeof element.matches !== 'undefined') {
return element.matches(query);
} else {
@@ -66,7 +68,7 @@ exports.matches = function (element, query) {
}
};
exports.remove = function (element) {
DOM.remove = function (element) {
if (typeof element.remove !== 'undefined') {
element.remove();
} else {
@@ -75,3 +77,11 @@ exports.remove = function (element) {
}
}
};
DOM.queryChildren = function (element, selector) {
return Array.prototype.filter.call(element.childNodes, function (child) {
return DOM.matches(child, selector);
});
};
module.exports = DOM;

View File

@@ -4,15 +4,17 @@
'use strict';
module.exports = {
wheelSpeed: 1,
wheelPropagation: false,
swipePropagation: true,
minScrollbarLength: null,
maxScrollbarLength: null,
useBothWheelAxes: false,
useKeyboard: true,
minScrollbarLength: null,
scrollXMarginOffset: 0,
scrollYMarginOffset: 0,
stopPropagationOnClick: true,
suppressScrollX: false,
suppressScrollY: false,
scrollXMarginOffset: 0,
scrollYMarginOffset: 0
swipePropagation: true,
useBothWheelAxes: false,
useKeyboard: true,
useSelectionScroll: false,
wheelPropagation: false,
wheelSpeed: 1
};

View File

@@ -10,6 +10,10 @@ var d = require('../lib/dom')
module.exports = function (element) {
var i = instances.get(element);
if (!i) {
return;
}
i.event.unbindAll();
d.remove(i.scrollbarX);
d.remove(i.scrollbarY);

View File

@@ -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) {
@@ -13,7 +14,9 @@ function bindClickRailHandler(element, i) {
}
var stopPropagation = window.Event.prototype.stopPropagation.bind;
i.event.bind(i.scrollbarY, 'click', stopPropagation);
if (i.settings.stopPropagationOnClick) {
i.event.bind(i.scrollbarY, 'click', stopPropagation);
}
i.event.bind(i.scrollbarYRail, 'click', function (e) {
var halfOfScrollbarLength = h.toInt(i.scrollbarYHeight / 2);
var positionTop = i.railYRatio * (e.pageY - window.scrollY - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength);
@@ -26,13 +29,15 @@ 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();
});
i.event.bind(i.scrollbarX, 'click', stopPropagation);
if (i.settings.stopPropagationOnClick) {
i.event.bind(i.scrollbarX, 'click', stopPropagation);
}
i.event.bind(i.scrollbarXRail, 'click', function (e) {
var halfOfScrollbarLength = h.toInt(i.scrollbarXWidth / 2);
var positionLeft = i.railXRatio * (e.pageX - window.scrollX - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength);
@@ -45,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();

View File

@@ -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) {

View File

@@ -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;
@@ -80,6 +81,12 @@ function bindKeyboardHandler(element, i) {
deltaY = 90;
break;
case 32: // space bar
if (e.shiftKey) {
deltaY = 90;
} else {
deltaY = -90;
}
break;
case 34: // page down
deltaY = -90;
break;
@@ -101,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);

View File

@@ -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;
}

View File

@@ -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
}

View File

@@ -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);
}

View File

@@ -31,7 +31,10 @@ module.exports = function (element, userSettings) {
dragScrollbarHandler(element);
mouseWheelHandler(element);
nativeScrollHandler(element);
selectionHandler(element);
if (i.settings.useSelectionScroll) {
selectionHandler(element);
}
if (h.env.supportsTouch || h.env.supportsIePointer) {
touchHandler(element, h.env.supportsTouch, h.env.supportsIePointer);

View File

@@ -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) {
@@ -60,10 +61,23 @@ module.exports = function (element) {
i.contentWidth = element.scrollWidth;
i.contentHeight = element.scrollHeight;
var existingRails;
if (!element.contains(i.scrollbarXRail)) {
existingRails = d.queryChildren(element, '.ps-scrollbar-x-rail');
if (existingRails.length > 0) {
existingRails.forEach(function (rail) {
d.remove(rail);
});
}
d.appendTo(i.scrollbarXRail, element);
}
if (!element.contains(i.scrollbarYRail)) {
existingRails = d.queryChildren(element, '.ps-scrollbar-y-rail');
if (existingRails.length > 0) {
existingRails.forEach(function (rail) {
d.remove(rail);
});
}
d.appendTo(i.scrollbarYRail, element);
}
@@ -90,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) {

View File

@@ -0,0 +1,105 @@
/* 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')
, xStartEvent = document.createEvent('Event')
, xEndEvent = document.createEvent('Event')
, yStartEvent = document.createEvent('Event')
, yEndEvent = 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);
xStartEvent.initEvent('ps-x-reach-start', true, true);
xEndEvent.initEvent('ps-x-reach-end', true, true);
yStartEvent.initEvent('ps-y-reach-start', true, true);
yEndEvent.initEvent('ps-y-reach-end', 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 (axis === 'top' && value <= 0) {
element.scrollTop = 0;
element.dispatchEvent(yStartEvent);
return; // don't allow negative scroll
}
if (axis === 'left' && value <= 0) {
element.scrollLeft = 0;
element.dispatchEvent(xStartEvent);
return; // don't allow negative scroll
}
var i = instances.get(element);
if (axis === 'top' && value > i.contentHeight - i.containerHeight) {
element.scrollTop = i.contentHeight - i.containerHeight;
element.dispatchEvent(yEndEvent);
return; // don't allow scroll past container
}
if (axis === 'left' && value > i.contentWidth - i.containerWidth) {
element.scrollLeft = i.contentWidth - i.containerWidth;
element.dispatchEvent(xEndEvent);
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);
}
};

View File

@@ -11,6 +11,10 @@ var d = require('../lib/dom')
module.exports = function (element) {
var i = instances.get(element);
if (!i) {
return;
}
// Recalcuate negative scrollLeft adjustment
i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;