Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b959edbf78 | ||
|
|
c49cf7905e | ||
|
|
f4cb31f8d8 | ||
|
|
965e315b30 | ||
|
|
3e76ce9d3e | ||
|
|
2413028ad4 | ||
|
|
cc0fded8cb | ||
|
|
fbfe505408 | ||
|
|
c76aa08113 | ||
|
|
4d7f441d1f | ||
|
|
4f6ed64b17 | ||
|
|
2fe45b3a97 | ||
|
|
57b1404e29 | ||
|
|
bcfe954803 | ||
|
|
31434f81d4 | ||
|
|
8a3ed6d0b7 | ||
|
|
1dfbbe9e56 | ||
|
|
eb02d5ae65 | ||
|
|
6fbaa00403 | ||
|
|
c14feba0bf | ||
|
|
6fbfd5c90d | ||
|
|
eddd2c2731 | ||
|
|
c04b662a1b | ||
|
|
5ba86c2217 | ||
|
|
6e32d3ddce | ||
|
|
9f9f15f83c | ||
|
|
7e04a2e72b | ||
|
|
24b34d3dea | ||
|
|
e1910cde3e | ||
|
|
bbf3d4db9f | ||
|
|
3b134d6193 | ||
|
|
e9024292cd | ||
|
|
e4dda6f408 | ||
|
|
fd53ae0b48 | ||
|
|
66fd8bfd6a | ||
|
|
4aa28add99 | ||
|
|
d6ede33202 | ||
|
|
1c3b409d12 | ||
|
|
17e5f67519 | ||
|
|
002034fd54 | ||
|
|
8761735a54 | ||
|
|
c285521caa | ||
|
|
3d2d50c308 | ||
|
|
a0d39e1b49 | ||
|
|
e288476ba0 | ||
|
|
e9bc40bd37 | ||
|
|
0b8fe0ac0b | ||
|
|
a3676556b2 | ||
|
|
39893fc6f2 | ||
|
|
6c5b9d249e | ||
|
|
2ef7e81ce9 | ||
|
|
3b90c734e4 | ||
|
|
afebe908b1 | ||
|
|
6cbb4a9b9d | ||
|
|
51f33a44b5 | ||
|
|
8eac54d49f | ||
|
|
ed4e335978 | ||
|
|
272bb4983a | ||
|
|
f200bea4cc | ||
|
|
b1d7aa0e64 | ||
|
|
49e39f513d | ||
|
|
89f4226778 | ||
|
|
79f4cfcf5f | ||
|
|
158b113d18 | ||
|
|
6c642d8a47 | ||
|
|
f9f20eeb6f | ||
|
|
1f082a2e04 | ||
|
|
b19c5e0765 | ||
|
|
3dbf20a5d0 | ||
|
|
db855ceca1 | ||
|
|
84b74926e3 | ||
|
|
d6bd30f2da | ||
|
|
fc28ceb4ea | ||
|
|
ca4d835129 | ||
|
|
88b4e2fc19 | ||
|
|
de32082a62 | ||
|
|
7ba25d020c | ||
|
|
08d559561e | ||
|
|
046ce954fd | ||
|
|
a40ab40695 |
14
.editorconfig
Normal file
14
.editorconfig
Normal file
@@ -0,0 +1,14 @@
|
||||
# EditorConfig: http://editorconfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
# Indentation for JS & SCSS
|
||||
[*.{js, scss}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
38
.eslintrc
38
.eslintrc
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
.idea
|
||||
.idea
|
||||
|
||||
@@ -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
|
||||
|
||||
19
LICENSE
Normal file
19
LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
The MIT License (MIT) Copyright (c) 2016 Hyunje Alex Jun and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
148
README.md
148
README.md
@@ -46,6 +46,7 @@ I hope you love it!
|
||||
to update the size or position of the scrollbar, just update.
|
||||
* Additionally, perfect-scrollbar uses 'scrollTop' and 'scrollLeft',
|
||||
not absolute positioning or something messy.
|
||||
* perfect-scrollbar supports RTL perfectly on both WebKit and Gecko based browsers.
|
||||
|
||||
It's cool, isn't it?
|
||||
|
||||
@@ -199,6 +200,66 @@ $('#container').perfectScrollbar('update'); // Update
|
||||
$('#container').perfectScrollbar('destroy'); // Destroy
|
||||
```
|
||||
|
||||
## RequireJS usage
|
||||
|
||||
For RequireJS loader, no need to write shim, simply import two libs:
|
||||
|
||||
```javascript
|
||||
require.config({
|
||||
paths: {
|
||||
perfectScrollbarJQuery: '.../perfect-scrollbar.jquery',
|
||||
perfectScrollbar: '.../perfect-scrollbar',
|
||||
}
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
and load `perfectScrollbar` in the initialiser of your app:
|
||||
|
||||
```javascript
|
||||
// for vanilla JS:
|
||||
window.Ps = require('perfectScrollbar');
|
||||
|
||||
// for jQuery:
|
||||
require('perfectScrollbarJQuery');
|
||||
```
|
||||
|
||||
|
||||
## AngularJS + RequireJS usage
|
||||
|
||||
With the require.config settings above, at the beginning of your app module
|
||||
definition, you can have following code:
|
||||
|
||||
```javascript
|
||||
define([
|
||||
'angular',
|
||||
'perfectScrollbar',
|
||||
'perfectScrollbarJquery'
|
||||
],
|
||||
function (angular) {
|
||||
var myApp = angular.module('myApp', [])
|
||||
.run(function() {
|
||||
window.Ps = require('perfectScrollbar');
|
||||
require('perfectScrollbarJQuery');
|
||||
})
|
||||
return myApp;
|
||||
});
|
||||
```
|
||||
|
||||
And initialise perfectScrollbar in a controller:
|
||||
|
||||
```javascript
|
||||
// by vanilla JS:
|
||||
var container = document.getElementById('imgLoader');
|
||||
Ps.initialize(container);
|
||||
Ps.update(container);
|
||||
|
||||
// or by jQuery:
|
||||
var imgLoader = $("#imgLoader")
|
||||
imgLoader.perfectScrollbar();
|
||||
```
|
||||
|
||||
## Optional parameters
|
||||
|
||||
perfect-scrollbar supports optional parameters.
|
||||
@@ -247,6 +308,91 @@ 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**
|
||||
|
||||
### 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.
|
||||
**Default: 'default'**
|
||||
|
||||
**Example 1:**
|
||||
|
||||
Add `theme` parameter:
|
||||
```javascript
|
||||
Ps.initialize(container, {
|
||||
theme: 'my-theme-name'
|
||||
});
|
||||
```
|
||||
Create a class name prefixed with `.ps-theme-`. Include `ps-container()` mixin. It's recommended to use `map-merge()` to extend `$ps-theme-default` map with your custom styles.
|
||||
```css#
|
||||
.ps-theme-my-theme-name {
|
||||
@include ps-container(map-merge($ps-theme-default, (
|
||||
border-radius: 0,
|
||||
scrollbar-x-rail-height: 20px,
|
||||
scrollbar-x-height: 20px,
|
||||
scrollbar-y-rail-width: 20px,
|
||||
scrollbar-y-width: 20px,)
|
||||
));
|
||||
}
|
||||
```
|
||||
|
||||
**Example 2:**
|
||||
|
||||
Alternatively, if you don't want to create your own themes, but only modify the default one, you could simply overwrite `$ps-*` variables with your own values. In this case `theme` parameter is not required when calling `.initialize()` method. Remember do define your own variables before the `theme.scss` file is imported.
|
||||
|
||||
|
||||
## 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.
|
||||
@@ -280,7 +426,7 @@ For common problems there is a
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT) Copyright (c) 2015 Hyunje Alex Jun and other contributors.
|
||||
The MIT License (MIT) Copyright (c) 2016 Hyunje Alex Jun and other contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
27
examples/custom-theme.html
Normal file
27
examples/custom-theme.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<!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: 600px; height: 400px; overflow: auto; }
|
||||
.contentHolder .content { background-image: url('./azusa.jpg'); width: 1280px; height: 720px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="Default" class="contentHolder">
|
||||
<div class="content">
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var $ = document.querySelector.bind(document);
|
||||
window.onload = function () {
|
||||
Ps.initialize($('#Default'), {
|
||||
theme: 'big-and-ugly'
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
89
examples/events.html
Normal file
89
examples/events.html
Normal 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">…</span></p>
|
||||
|
||||
<p><strong>Direction</strong> <span id="direction">…</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>
|
||||
@@ -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>
|
||||
@@ -6,27 +6,39 @@
|
||||
<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: 600px; height: 400px; overflow: auto; }
|
||||
.contentHolder .content { background-image: url('./azusa.jpg'); width: 1280px; height: 720px; }
|
||||
.spacer { text-align:center }
|
||||
h1 { 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; }
|
||||
|
||||
.ps-scrollbar-x-rail {
|
||||
margin: 0 3px;
|
||||
.large-margin .ps-scrollbar-x-rail {
|
||||
margin: 0 25%;
|
||||
opacity: 0.5;
|
||||
background-color: #eee;
|
||||
}
|
||||
.ps-scrollbar-y-rail {
|
||||
margin: 3px 0;
|
||||
.large-margin .ps-scrollbar-y-rail {
|
||||
margin: 100px 0;
|
||||
opacity: 0.5;
|
||||
background-color: #eee;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="Default" class="contentHolder">
|
||||
<h1>Default</h1>
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>Margins</h1>
|
||||
<div class="container large-margin">
|
||||
<div class="content">
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var $ = document.querySelector.bind(document);
|
||||
window.onload = function () {
|
||||
Ps.initialize($('#Default'));
|
||||
[].forEach.call(document.querySelectorAll('.container'), function (el) {
|
||||
Ps.initialize(el);
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -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;
|
||||
|
||||
119
gulpfile.js
119
gulpfile.js
@@ -2,15 +2,18 @@
|
||||
|
||||
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')
|
||||
, autoprefixer = require('gulp-autoprefixer')
|
||||
, zip = require('gulp-zip');
|
||||
|
||||
var version = '/* perfect-scrollbar v' + require('./package').version + ' */\n';
|
||||
@@ -23,98 +26,90 @@ 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'
|
||||
];
|
||||
|
||||
var autoPrefixerConfig = {
|
||||
browsers: ['> 0%'], // '> 0%' forces autoprefixer to use all the possible prefixes. See https://github.com/ai/browserslist#queries for more details. IMO 'last 3 versions' would be good enough.
|
||||
cascade: false
|
||||
};
|
||||
|
||||
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.min';
|
||||
} else {
|
||||
path.basename = 'perfect-scrollbar.' + path.basename + '.min';
|
||||
}
|
||||
}))
|
||||
.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(autoprefixer(autoPrefixerConfig))
|
||||
.pipe(insert.prepend(version))
|
||||
.pipe(rename('perfect-scrollbar.css'))
|
||||
.pipe(gulp.dest('./dist/css'))
|
||||
.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(autoprefixer(autoPrefixerConfig))
|
||||
.pipe(insert.prepend(version))
|
||||
.pipe(rename('perfect-scrollbar.min.css'))
|
||||
.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({
|
||||
|
||||
3
index.js
3
index.js
@@ -1,6 +1,3 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
module.exports = require('./src/js/main');
|
||||
|
||||
3
jquery.js
vendored
3
jquery.js
vendored
@@ -1,6 +1,3 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
module.exports = require('./src/js/adaptor/jquery');
|
||||
|
||||
32
package.json
32
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "perfect-scrollbar",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.10",
|
||||
"description": "Minimalistic but perfect custom scrollbar plugin",
|
||||
"author": "Hyunje Alex Jun <me@noraesae.net>",
|
||||
"contributors": [
|
||||
@@ -24,24 +24,28 @@
|
||||
"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-autoprefixer": "^3.1.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",
|
||||
"release": "rm -rf dist && gulp && npm publish"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
|
||||
@@ -1,122 +1,3 @@
|
||||
// Colors
|
||||
$ps-rail-hover: #eee;
|
||||
$ps-bar-default: #aaa;
|
||||
$ps-bar-hover: #999;
|
||||
|
||||
// Helper mixins
|
||||
@mixin border-radius($r) {
|
||||
-webkit-border-radius: $r;
|
||||
-moz-border-radius: $r;
|
||||
-ms-border-radius: $r;
|
||||
border-radius: $r;
|
||||
}
|
||||
|
||||
@mixin transition($t...) {
|
||||
-webkit-transition: $t;
|
||||
-moz-transition: $t;
|
||||
-o-transition: $t;
|
||||
transition: $t;
|
||||
}
|
||||
|
||||
// Scrollbar mixins
|
||||
@mixin scrollbar-rail-default {
|
||||
display: none;
|
||||
position: absolute; /* please don't change 'position' */
|
||||
@include border-radius(4px);
|
||||
opacity: 0;
|
||||
@include transition(background-color .2s linear, opacity .2s linear);
|
||||
}
|
||||
|
||||
@mixin scrollbar-rail-hover {
|
||||
background-color: $ps-rail-hover;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
@mixin scrollbar-default {
|
||||
position: absolute; /* please don't change 'position' */
|
||||
background-color: $ps-bar-default;
|
||||
@include border-radius(4px);
|
||||
@include transition(background-color .2s linear);
|
||||
}
|
||||
|
||||
@mixin scrollbar-hover {
|
||||
background-color: $ps-bar-hover;
|
||||
}
|
||||
|
||||
@mixin in-scrolling {
|
||||
&.ps-in-scrolling {
|
||||
pointer-events: none;
|
||||
&.ps-x>.ps-scrollbar-x-rail{
|
||||
@include scrollbar-rail-hover;
|
||||
>.ps-scrollbar-x {
|
||||
@include scrollbar-hover;
|
||||
}
|
||||
}
|
||||
&.ps-y>.ps-scrollbar-y-rail {
|
||||
@include scrollbar-rail-hover;
|
||||
>.ps-scrollbar-y {
|
||||
@include scrollbar-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ps-container {
|
||||
overflow: hidden !important;
|
||||
|
||||
&.ps-active-x > .ps-scrollbar-x-rail,
|
||||
&.ps-active-y > .ps-scrollbar-y-rail {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@include in-scrolling;
|
||||
|
||||
>.ps-scrollbar-x-rail {
|
||||
@include scrollbar-rail-default;
|
||||
bottom: 3px; /* there must be 'bottom' for ps-scrollbar-x-rail */
|
||||
height: 8px;
|
||||
|
||||
>.ps-scrollbar-x {
|
||||
@include scrollbar-default;
|
||||
bottom: 0; /* there must be 'bottom' for ps-scrollbar-x */
|
||||
height: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
>.ps-scrollbar-y-rail {
|
||||
@include scrollbar-rail-default;
|
||||
right: 3px; /* there must be 'right' for ps-scrollbar-y-rail */
|
||||
width: 8px;
|
||||
|
||||
>.ps-scrollbar-y {
|
||||
@include scrollbar-default;
|
||||
right: 0; /* there must be 'right' for ps-scrollbar-y */
|
||||
width: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include in-scrolling;
|
||||
|
||||
>.ps-scrollbar-x-rail,
|
||||
>.ps-scrollbar-y-rail {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
>.ps-scrollbar-x-rail:hover {
|
||||
@include scrollbar-rail-hover;
|
||||
|
||||
>.ps-scrollbar-x {
|
||||
@include scrollbar-hover;
|
||||
}
|
||||
}
|
||||
|
||||
>.ps-scrollbar-y-rail:hover {
|
||||
@include scrollbar-rail-hover;
|
||||
|
||||
>.ps-scrollbar-y {
|
||||
@include scrollbar-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@import 'variables';
|
||||
@import 'mixins';
|
||||
@import 'themes';
|
||||
|
||||
115
src/css/mixins.scss
Normal file
115
src/css/mixins.scss
Normal file
@@ -0,0 +1,115 @@
|
||||
@mixin scrollbar-rail-default($theme) {
|
||||
display: none;
|
||||
position: absolute; /* please don't change 'position' */
|
||||
border-radius: map_get($theme, border-radius);
|
||||
opacity: map_get($theme, rail-default-opacity);
|
||||
transition: background-color .2s linear, opacity .2s linear;
|
||||
}
|
||||
|
||||
@mixin scrollbar-rail-hover($theme) {
|
||||
background-color: map_get($theme, rail-hover-bg);
|
||||
opacity: map_get($theme, rail-hover-opacity);
|
||||
}
|
||||
|
||||
@mixin scrollbar-default($theme) {
|
||||
position: absolute; /* please don't change 'position' */
|
||||
background-color: map_get($theme, bar-container-hover-bg);
|
||||
border-radius: map_get($theme, border-radius);
|
||||
transition: background-color .2s linear;
|
||||
}
|
||||
|
||||
@mixin scrollbar-hover($theme) {
|
||||
background-color: map_get($theme, bar-hover-bg);
|
||||
}
|
||||
|
||||
@mixin in-scrolling($theme) {
|
||||
&.ps-in-scrolling {
|
||||
pointer-events: none;
|
||||
&.ps-x > .ps-scrollbar-x-rail {
|
||||
@include scrollbar-rail-hover($theme);
|
||||
> .ps-scrollbar-x {
|
||||
@include scrollbar-hover($theme);
|
||||
}
|
||||
}
|
||||
&.ps-y > .ps-scrollbar-y-rail {
|
||||
@include scrollbar-rail-hover($theme);
|
||||
> .ps-scrollbar-y {
|
||||
@include scrollbar-hover($theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Layout and theme mixin
|
||||
@mixin ps-container($theme) {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
overflow: hidden !important;
|
||||
-ms-overflow-style: none;
|
||||
|
||||
// Edge
|
||||
@supports (-ms-overflow-style: none) {
|
||||
overflow: auto !important;
|
||||
}
|
||||
// IE10+
|
||||
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
|
||||
overflow: auto !important;
|
||||
}
|
||||
|
||||
&.ps-active-x > .ps-scrollbar-x-rail,
|
||||
&.ps-active-y > .ps-scrollbar-y-rail {
|
||||
display: block;
|
||||
background-color: map_get($theme, bar-bg);
|
||||
}
|
||||
|
||||
@include in-scrolling($theme);
|
||||
|
||||
> .ps-scrollbar-x-rail {
|
||||
@include scrollbar-rail-default($theme);
|
||||
bottom: map_get($theme, scrollbar-x-rail-bottom); /* there must be 'bottom' for ps-scrollbar-x-rail */
|
||||
height: map_get($theme, scrollbar-x-rail-height);
|
||||
|
||||
> .ps-scrollbar-x {
|
||||
@include scrollbar-default($theme);
|
||||
bottom: map_get($theme, scrollbar-x-bottom); /* there must be 'bottom' for ps-scrollbar-x */
|
||||
height: map_get($theme, scrollbar-x-height);
|
||||
}
|
||||
}
|
||||
|
||||
> .ps-scrollbar-y-rail {
|
||||
@include scrollbar-rail-default($theme);
|
||||
right: map_get($theme, scrollbar-y-rail-right); /* there must be 'right' for ps-scrollbar-y-rail */
|
||||
width: map_get($theme, scrollbar-y-rail-width);
|
||||
|
||||
> .ps-scrollbar-y {
|
||||
@include scrollbar-default($theme);
|
||||
right: map_get($theme, scrollbar-y-right); /* there must be 'right' for ps-scrollbar-y */
|
||||
width: map_get($theme, scrollbar-y-width);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include in-scrolling($theme);
|
||||
|
||||
> .ps-scrollbar-x-rail,
|
||||
> .ps-scrollbar-y-rail {
|
||||
opacity: map_get($theme, rail-container-hover-opacity);
|
||||
}
|
||||
|
||||
> .ps-scrollbar-x-rail:hover {
|
||||
@include scrollbar-rail-hover($theme);
|
||||
|
||||
> .ps-scrollbar-x {
|
||||
@include scrollbar-hover($theme);
|
||||
}
|
||||
}
|
||||
|
||||
> .ps-scrollbar-y-rail:hover {
|
||||
@include scrollbar-rail-hover($theme);
|
||||
|
||||
> .ps-scrollbar-y {
|
||||
@include scrollbar-hover($theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
src/css/themes.scss
Normal file
23
src/css/themes.scss
Normal file
@@ -0,0 +1,23 @@
|
||||
$ps-theme-default: (
|
||||
border-radius: $ps-border-radius,
|
||||
rail-default-opacity: $ps-rail-default-opacity,
|
||||
rail-container-hover-opacity: $ps-rail-container-hover-opacity,
|
||||
rail-hover-opacity: $ps-rail-hover-opacity,
|
||||
bar-bg: $ps-bar-bg,
|
||||
bar-container-hover-bg: $ps-bar-container-hover-bg,
|
||||
bar-hover-bg: $ps-bar-hover-bg,
|
||||
rail-hover-bg: $ps-rail-hover-bg,
|
||||
scrollbar-x-rail-bottom: $ps-scrollbar-x-rail-bottom,
|
||||
scrollbar-x-rail-height: $ps-scrollbar-x-rail-height,
|
||||
scrollbar-x-bottom: $ps-scrollbar-x-bottom,
|
||||
scrollbar-x-height: $ps-scrollbar-x-height,
|
||||
scrollbar-y-rail-right: $ps-scrollbar-y-rail-right,
|
||||
scrollbar-y-rail-width: $ps-scrollbar-y-rail-width,
|
||||
scrollbar-y-right: $ps-scrollbar-y-right,
|
||||
scrollbar-y-width: $ps-scrollbar-y-width,
|
||||
);
|
||||
|
||||
// Default theme
|
||||
.ps-container {
|
||||
@include ps-container($ps-theme-default);
|
||||
}
|
||||
22
src/css/variables.scss
Normal file
22
src/css/variables.scss
Normal file
@@ -0,0 +1,22 @@
|
||||
// Colors
|
||||
$ps-border-radius: 4px !default;
|
||||
|
||||
$ps-rail-default-opacity: 0 !default;
|
||||
$ps-rail-container-hover-opacity: 0.6 !default;
|
||||
$ps-rail-hover-opacity: 0.9 !default;
|
||||
|
||||
$ps-bar-bg: transparent !default;
|
||||
$ps-bar-container-hover-bg: #aaa !default;
|
||||
$ps-bar-hover-bg: #999 !default;
|
||||
$ps-rail-hover-bg: #eee !default;
|
||||
|
||||
// Sizes
|
||||
$ps-scrollbar-x-rail-bottom: 3px !default;
|
||||
$ps-scrollbar-x-rail-height: 8px !default;
|
||||
$ps-scrollbar-x-bottom: 0 !default;
|
||||
$ps-scrollbar-x-height: 8px !default;
|
||||
|
||||
$ps-scrollbar-y-rail-right: 3px !default;
|
||||
$ps-scrollbar-y-rail-width: 8px !default;
|
||||
$ps-scrollbar-y-right: 0 !default;
|
||||
$ps-scrollbar-y-width: 8px !default;
|
||||
@@ -1,6 +1,3 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var ps = require('../main');
|
||||
|
||||
3
src/js/adaptor/jquery.js
vendored
3
src/js/adaptor/jquery.js
vendored
@@ -1,6 +1,3 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var ps = require('../main')
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
function oldAdd(element, className) {
|
||||
@@ -38,7 +35,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(' ');
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'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 +36,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 +49,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 +65,7 @@ exports.matches = function (element, query) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.remove = function (element) {
|
||||
DOM.remove = function (element) {
|
||||
if (typeof element.remove !== 'undefined') {
|
||||
element.remove();
|
||||
} else {
|
||||
@@ -75,3 +74,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;
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var EventElement = function (element) {
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
module.exports = (function () {
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var cls = require('./class')
|
||||
, d = require('./dom');
|
||||
|
||||
exports.toInt = function (x) {
|
||||
if (typeof x === 'string') {
|
||||
return parseInt(x, 10);
|
||||
} else {
|
||||
return ~~x;
|
||||
}
|
||||
return parseInt(x, 10) || 0;
|
||||
};
|
||||
|
||||
exports.clone = function (obj) {
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var destroy = require('./plugin/destroy')
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'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,
|
||||
theme: 'default'
|
||||
};
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var d = require('../lib/dom')
|
||||
@@ -10,6 +7,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);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
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,11 +11,13 @@ 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 = e.pageY - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength;
|
||||
var maxPositionTop = i.containerHeight - i.scrollbarYHeight;
|
||||
var positionTop = i.railYRatio * (e.pageY - window.pageYOffset - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength);
|
||||
var maxPositionTop = i.railYRatio * (i.railYHeight - i.scrollbarYHeight);
|
||||
var positionRatio = positionTop / maxPositionTop;
|
||||
|
||||
if (positionRatio < 0) {
|
||||
@@ -26,16 +26,19 @@ 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 = e.pageX - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength;
|
||||
console.log(e.pageX, i.scrollbarXRail.offsetLeft);
|
||||
var maxPositionLeft = i.containerWidth - i.scrollbarXWidth;
|
||||
var positionLeft = i.railXRatio * (e.pageX - window.pageXOffset - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength);
|
||||
var maxPositionLeft = i.railXRatio * (i.railXWidth - i.scrollbarXWidth);
|
||||
var positionRatio = positionLeft / maxPositionLeft;
|
||||
|
||||
if (positionRatio < 0) {
|
||||
@@ -44,8 +47,10 @@ function bindClickRailHandler(element, i) {
|
||||
positionRatio = 1;
|
||||
}
|
||||
|
||||
element.scrollLeft = (i.contentWidth - i.containerWidth) * positionRatio;
|
||||
updateScroll(element, 'left', ((i.contentWidth - i.containerWidth) * positionRatio) - i.negativeScrollAdjustment);
|
||||
updateGeometry(element);
|
||||
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
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;
|
||||
var currentPageX = null;
|
||||
|
||||
function updateScrollLeft(deltaX) {
|
||||
var newLeft = currentLeft + deltaX;
|
||||
var maxLeft = i.containerWidth - i.scrollbarXWidth;
|
||||
var newLeft = currentLeft + (deltaX * i.railXRatio);
|
||||
var maxLeft = Math.max(0, i.scrollbarXRail.getBoundingClientRect().left) + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth));
|
||||
|
||||
if (newLeft < 0) {
|
||||
i.scrollbarXLeft = 0;
|
||||
@@ -24,8 +22,8 @@ function bindMouseScrollXHandler(element, i) {
|
||||
i.scrollbarXLeft = newLeft;
|
||||
}
|
||||
|
||||
var scrollLeft = h.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - i.scrollbarXWidth));
|
||||
element.scrollLeft = scrollLeft;
|
||||
var scrollLeft = h.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))) - i.negativeScrollAdjustment;
|
||||
updateScroll(element, 'left', scrollLeft);
|
||||
}
|
||||
|
||||
var mouseMoveHandler = function (e) {
|
||||
@@ -42,7 +40,7 @@ function bindMouseScrollXHandler(element, i) {
|
||||
|
||||
i.event.bind(i.scrollbarX, 'mousedown', function (e) {
|
||||
currentPageX = e.pageX;
|
||||
currentLeft = h.toInt(d.css(i.scrollbarX, 'left'));
|
||||
currentLeft = h.toInt(d.css(i.scrollbarX, 'left')) * i.railXRatio;
|
||||
h.startScrolling(element, 'x');
|
||||
|
||||
i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
|
||||
@@ -58,8 +56,8 @@ function bindMouseScrollYHandler(element, i) {
|
||||
var currentPageY = null;
|
||||
|
||||
function updateScrollTop(deltaY) {
|
||||
var newTop = currentTop + deltaY;
|
||||
var maxTop = i.containerHeight - i.scrollbarYHeight;
|
||||
var newTop = currentTop + (deltaY * i.railYRatio);
|
||||
var maxTop = Math.max(0, i.scrollbarYRail.getBoundingClientRect().top) + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight));
|
||||
|
||||
if (newTop < 0) {
|
||||
i.scrollbarYTop = 0;
|
||||
@@ -69,8 +67,8 @@ function bindMouseScrollYHandler(element, i) {
|
||||
i.scrollbarYTop = newTop;
|
||||
}
|
||||
|
||||
var scrollTop = h.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - i.scrollbarYHeight));
|
||||
element.scrollTop = scrollTop;
|
||||
var scrollTop = h.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight)));
|
||||
updateScroll(element, 'top', scrollTop);
|
||||
}
|
||||
|
||||
var mouseMoveHandler = function (e) {
|
||||
@@ -87,7 +85,7 @@ function bindMouseScrollYHandler(element, i) {
|
||||
|
||||
i.event.bind(i.scrollbarY, 'mousedown', function (e) {
|
||||
currentPageY = e.pageY;
|
||||
currentTop = h.toInt(d.css(i.scrollbarY, 'top'));
|
||||
currentTop = h.toInt(d.css(i.scrollbarY, 'top')) * i.railYRatio;
|
||||
h.startScrolling(element, 'y');
|
||||
|
||||
i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var h = require('../../lib/helper')
|
||||
, d = require('../../lib/dom')
|
||||
, instances = require('../instances')
|
||||
, updateGeometry = require('../update-geometry');
|
||||
, updateGeometry = require('../update-geometry')
|
||||
, updateScroll = require('../update-scroll');
|
||||
|
||||
function bindKeyboardHandler(element, i) {
|
||||
var hovered = false;
|
||||
@@ -45,7 +44,10 @@ function bindKeyboardHandler(element, i) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hovered) {
|
||||
var focused = d.matches(i.scrollbarX, ':focus') ||
|
||||
d.matches(i.scrollbarY, ':focus');
|
||||
|
||||
if (!hovered && !focused) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -80,6 +82,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 +109,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);
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var h = require('../../lib/helper')
|
||||
, instances = require('../instances')
|
||||
, updateGeometry = require('../update-geometry');
|
||||
var instances = require('../instances')
|
||||
, updateGeometry = require('../update-geometry')
|
||||
, updateScroll = require('../update-scroll');
|
||||
|
||||
function bindMouseWheelHandler(element, i) {
|
||||
var shouldPrevent = false;
|
||||
@@ -80,13 +77,6 @@ function bindMouseWheelHandler(element, i) {
|
||||
}
|
||||
|
||||
function mousewheelHandler(e) {
|
||||
// FIXME: this is a quick fix for the select problem in FF and IE.
|
||||
// If there comes an effective way to deal with the problem,
|
||||
// this lines should be removed.
|
||||
if (!h.env.isWebKit && element.querySelector('select:focus')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var delta = getDeltaFromEvent(e);
|
||||
|
||||
var deltaX = delta[0];
|
||||
@@ -100,24 +90,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;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var instances = require('../instances')
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
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 +26,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
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'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 +31,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);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var cls = require('../lib/class')
|
||||
@@ -26,12 +23,16 @@ module.exports = function (element, userSettings) {
|
||||
var i = instances.add(element);
|
||||
|
||||
i.settings = h.extend(i.settings, userSettings);
|
||||
cls.add(element, 'ps-theme-' + i.settings.theme);
|
||||
|
||||
clickRailHandler(element);
|
||||
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);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var d = require('../lib/dom')
|
||||
var cls = require('../lib/class')
|
||||
, d = require('../lib/dom')
|
||||
, defaultSettings = require('./default-setting')
|
||||
, EventManager = require('../lib/event-manager')
|
||||
, guid = require('../lib/guid')
|
||||
@@ -21,11 +19,31 @@ function Instance(element) {
|
||||
i.contentHeight = null;
|
||||
|
||||
i.isRtl = d.css(element, 'direction') === "rtl";
|
||||
i.isNegativeScroll = (function () {
|
||||
var originalScrollLeft = element.scrollLeft;
|
||||
var result = null;
|
||||
element.scrollLeft = -1;
|
||||
result = element.scrollLeft < 0;
|
||||
element.scrollLeft = originalScrollLeft;
|
||||
return result;
|
||||
})();
|
||||
i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
|
||||
i.event = new EventManager();
|
||||
i.ownerDocument = element.ownerDocument || document;
|
||||
|
||||
function focus() {
|
||||
cls.add(element, 'ps-focus');
|
||||
}
|
||||
|
||||
function blur() {
|
||||
cls.remove(element, 'ps-focus');
|
||||
}
|
||||
|
||||
i.scrollbarXRail = d.appendTo(d.e('div', 'ps-scrollbar-x-rail'), element);
|
||||
i.scrollbarX = d.appendTo(d.e('div', 'ps-scrollbar-x'), i.scrollbarXRail);
|
||||
i.scrollbarX.setAttribute('tabindex', 0);
|
||||
i.event.bind(i.scrollbarX, 'focus', focus);
|
||||
i.event.bind(i.scrollbarX, 'blur', blur);
|
||||
i.scrollbarXActive = null;
|
||||
i.scrollbarXWidth = null;
|
||||
i.scrollbarXLeft = null;
|
||||
@@ -33,11 +51,18 @@ function Instance(element) {
|
||||
i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN
|
||||
i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : h.toInt(d.css(i.scrollbarXRail, 'top'));
|
||||
i.railBorderXWidth = h.toInt(d.css(i.scrollbarXRail, 'borderLeftWidth')) + h.toInt(d.css(i.scrollbarXRail, 'borderRightWidth'));
|
||||
// Set rail to display:block to calculate margins
|
||||
d.css(i.scrollbarXRail, 'display', 'block');
|
||||
i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight'));
|
||||
d.css(i.scrollbarXRail, 'display', '');
|
||||
i.railXWidth = null;
|
||||
i.railXRatio = null;
|
||||
|
||||
i.scrollbarYRail = d.appendTo(d.e('div', 'ps-scrollbar-y-rail'), element);
|
||||
i.scrollbarY = d.appendTo(d.e('div', 'ps-scrollbar-y'), i.scrollbarYRail);
|
||||
i.scrollbarY.setAttribute('tabindex', 0);
|
||||
i.event.bind(i.scrollbarY, 'focus', focus);
|
||||
i.event.bind(i.scrollbarY, 'blur', blur);
|
||||
i.scrollbarYActive = null;
|
||||
i.scrollbarYHeight = null;
|
||||
i.scrollbarYTop = null;
|
||||
@@ -46,8 +71,11 @@ function Instance(element) {
|
||||
i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : h.toInt(d.css(i.scrollbarYRail, 'left'));
|
||||
i.scrollbarYOuterWidth = i.isRtl ? h.outerWidth(i.scrollbarY) : null;
|
||||
i.railBorderYWidth = h.toInt(d.css(i.scrollbarYRail, 'borderTopWidth')) + h.toInt(d.css(i.scrollbarYRail, 'borderBottomWidth'));
|
||||
d.css(i.scrollbarYRail, 'display', 'block');
|
||||
i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom'));
|
||||
d.css(i.scrollbarYRail, 'display', '');
|
||||
i.railYHeight = null;
|
||||
i.railYRatio = null;
|
||||
}
|
||||
|
||||
function getId(element) {
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
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) {
|
||||
@@ -21,7 +19,7 @@ function getThumbSize(i, thumbSize) {
|
||||
function updateCss(element, i) {
|
||||
var xRailOffset = {width: i.railXWidth};
|
||||
if (i.isRtl) {
|
||||
xRailOffset.left = element.scrollLeft + i.containerWidth - i.contentWidth;
|
||||
xRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth - i.contentWidth;
|
||||
} else {
|
||||
xRailOffset.left = element.scrollLeft;
|
||||
}
|
||||
@@ -35,13 +33,13 @@ function updateCss(element, i) {
|
||||
var yRailOffset = {top: element.scrollTop, height: i.railYHeight};
|
||||
if (i.isScrollbarYUsingRight) {
|
||||
if (i.isRtl) {
|
||||
yRailOffset.right = i.contentWidth - element.scrollLeft - i.scrollbarYRight - i.scrollbarYOuterWidth;
|
||||
yRailOffset.right = i.contentWidth - (i.negativeScrollAdjustment + element.scrollLeft) - i.scrollbarYRight - i.scrollbarYOuterWidth;
|
||||
} else {
|
||||
yRailOffset.right = i.scrollbarYRight - element.scrollLeft;
|
||||
}
|
||||
} else {
|
||||
if (i.isRtl) {
|
||||
yRailOffset.left = element.scrollLeft + i.containerWidth * 2 - i.contentWidth - i.scrollbarYLeft - i.scrollbarYOuterWidth;
|
||||
yRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth * 2 - i.contentWidth - i.scrollbarYLeft - i.scrollbarYOuterWidth;
|
||||
} else {
|
||||
yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;
|
||||
}
|
||||
@@ -60,35 +58,44 @@ 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);
|
||||
}
|
||||
|
||||
if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) {
|
||||
i.scrollbarXActive = true;
|
||||
i.railXWidth = i.containerWidth - i.railXMarginWidth;
|
||||
i.railXRatio = i.containerWidth / i.railXWidth;
|
||||
i.scrollbarXWidth = getThumbSize(i, h.toInt(i.railXWidth * i.containerWidth / i.contentWidth));
|
||||
i.scrollbarXLeft = h.toInt(element.scrollLeft * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth));
|
||||
i.scrollbarXLeft = h.toInt((i.negativeScrollAdjustment + element.scrollLeft) * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth));
|
||||
} else {
|
||||
i.scrollbarXActive = false;
|
||||
i.scrollbarXWidth = 0;
|
||||
i.scrollbarXLeft = 0;
|
||||
element.scrollLeft = 0;
|
||||
}
|
||||
|
||||
if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) {
|
||||
i.scrollbarYActive = true;
|
||||
i.railYHeight = i.containerHeight - i.railYMarginHeight;
|
||||
i.railYRatio = i.containerHeight / i.railYHeight;
|
||||
i.scrollbarYHeight = getThumbSize(i, h.toInt(i.railYHeight * i.containerHeight / i.contentHeight));
|
||||
i.scrollbarYTop = h.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight));
|
||||
} else {
|
||||
i.scrollbarYActive = false;
|
||||
i.scrollbarYHeight = 0;
|
||||
i.scrollbarYTop = 0;
|
||||
element.scrollTop = 0;
|
||||
}
|
||||
|
||||
if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {
|
||||
@@ -100,6 +107,20 @@ module.exports = function (element) {
|
||||
|
||||
updateCss(element, i);
|
||||
|
||||
cls[i.scrollbarXActive ? 'add' : 'remove'](element, 'ps-active-x');
|
||||
cls[i.scrollbarYActive ? 'add' : 'remove'](element, 'ps-active-y');
|
||||
if (i.scrollbarXActive) {
|
||||
cls.add(element, 'ps-active-x');
|
||||
} else {
|
||||
cls.remove(element, 'ps-active-x');
|
||||
i.scrollbarXWidth = 0;
|
||||
i.scrollbarXLeft = 0;
|
||||
updateScroll(element, 'left', 0);
|
||||
}
|
||||
if (i.scrollbarYActive) {
|
||||
cls.add(element, 'ps-active-y');
|
||||
} else {
|
||||
cls.remove(element, 'ps-active-y');
|
||||
i.scrollbarYHeight = 0;
|
||||
i.scrollbarYTop = 0;
|
||||
updateScroll(element, 'top', 0);
|
||||
}
|
||||
};
|
||||
|
||||
98
src/js/plugin/update-scroll.js
Normal file
98
src/js/plugin/update-scroll.js
Normal file
@@ -0,0 +1,98 @@
|
||||
'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 = value = 0; // don't allow negative scroll
|
||||
element.dispatchEvent(yStartEvent);
|
||||
}
|
||||
|
||||
if (axis === 'left' && value <= 0) {
|
||||
element.scrollLeft = value = 0; // don't allow negative scroll
|
||||
element.dispatchEvent(xStartEvent);
|
||||
}
|
||||
|
||||
var i = instances.get(element);
|
||||
|
||||
if (axis === 'top' && value >= i.contentHeight - i.containerHeight) {
|
||||
element.scrollTop = value = i.contentHeight - i.containerHeight; // don't allow scroll past container
|
||||
element.dispatchEvent(yEndEvent);
|
||||
}
|
||||
|
||||
if (axis === 'left' && value >= i.contentWidth - i.containerWidth) {
|
||||
element.scrollLeft = value = i.contentWidth - i.containerWidth; // don't allow scroll past container
|
||||
element.dispatchEvent(xEndEvent);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,21 +1,37 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var d = require('../lib/dom')
|
||||
, h = require('../lib/helper')
|
||||
, instances = require('./instances')
|
||||
, updateGeometry = require('./update-geometry');
|
||||
, updateGeometry = require('./update-geometry')
|
||||
, updateScroll = require('./update-scroll');
|
||||
|
||||
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;
|
||||
|
||||
// Recalculate rail margins
|
||||
d.css(i.scrollbarXRail, 'display', 'block');
|
||||
d.css(i.scrollbarYRail, 'display', 'block');
|
||||
i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight'));
|
||||
i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom'));
|
||||
|
||||
// Hide scrollbars not to affect scrollWidth and scrollHeight
|
||||
d.css(i.scrollbarXRail, 'display', 'none');
|
||||
d.css(i.scrollbarYRail, 'display', 'none');
|
||||
|
||||
updateGeometry(element);
|
||||
|
||||
d.css(i.scrollbarXRail, 'display', 'block');
|
||||
d.css(i.scrollbarYRail, 'display', 'block');
|
||||
// Update top/left scroll to trigger events
|
||||
updateScroll(element, 'top', element.scrollTop);
|
||||
updateScroll(element, 'left', element.scrollLeft);
|
||||
|
||||
d.css(i.scrollbarXRail, 'display', '');
|
||||
d.css(i.scrollbarYRail, 'display', '');
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user