Compare commits

...

19 Commits
0.5.4 ... 0.5.7

Author SHA1 Message Date
Hyunje Alex Jun
3821413589 Release 0.5.7.
1. IE mouse pointer event bug fix.
2. Use scss for stylesheet.
3. Clear intervals when destroyed.
4. Bug fixes.
2014-11-05 19:02:45 +00:00
Hyunje Alex Jun
08a387d9c1 Add removable-list-element example. 2014-11-05 19:02:00 +00:00
Hyunje Alex Jun
1849e64122 Remove remaining inline display style.
It caused regression bugs.
2014-11-05 18:51:52 +00:00
Hyunje Alex Jun
f9c3dc0b20 Change name of variable breakingProcess.
It's too ambiguous to understand the purpose of the variable.
2014-10-31 19:25:43 +00:00
Hyunje Alex Jun
aa92487ed3 Clear intervals if the plugin is destroyed. 2014-10-31 19:25:13 +00:00
Hyunje Alex Jun
a3bf38ada2 Update README.md
Add FAQ.
2014-10-31 19:16:36 +00:00
Hyunje Alex Jun
d24f9bd41b Use scss for stylesheet.
We can build the scss source to .css and .min.css files with the
`grunt build` command.
2014-10-31 02:20:22 +00:00
Hyunje Alex Jun
5be50316ca Merge pull request #239 from darthmaim/bugfix_ie10_pointertype
Don't handle mouse pointer events as touch in IE10.
2014-10-30 18:21:43 +00:00
Konrad Liebig
94be67d998 Don't handle mouse pointer events as touch in IE10 2014-10-30 17:04:20 +01:00
Hyunje Alex Jun
17fd46a07d Release 0.5.6.
1. Add scrolling with selection.
2. Bug fixes.
2014-10-28 18:02:22 +00:00
Hyunje Alex Jun
f099448e44 Change how scrollbar rails are being hidden.
Inline CSS change is bad practice.
2014-10-28 18:01:23 +00:00
Hyunje Alex Jun
d0b97e4039 Add selection handler.
Now perfect-scrollbar supports scrolling by selection.
2014-10-28 17:49:16 +00:00
Hyunje Alex Jun
f2342f2678 Change the way to handle event class name.
Use factory pattern to handle it, instead of using + operator of
string.
2014-10-28 16:41:36 +00:00
Hyunje Alex Jun
967c30a5e4 Shouldn't prevent default for touchStart.
Default touch event shouldn't be prevented.
2014-10-28 14:33:07 +00:00
Hyunje Alex Jun
7cf8303b30 Release 0.5.5.
1. Bug fixes.
2014-10-24 12:06:04 +01:00
Hyunje Alex Jun
7dd6335965 Filter touch events not to be handled.
In IE 10/11, MSPointer event is fired by mouse. It shouldn't be handled.

Also, Exception has occurred with event.targetTouches, and this commit
fixed it too.
2014-10-24 12:03:55 +01:00
Hyunje Alex Jun
494d68fe02 Merge pull request #231 from suxxes/patch-1
Correction for railBorderYWidth calculation
2014-10-22 16:10:07 +01:00
Fedor
3dde3ebb0c Correction for railBorderYWidth calculation 2014-10-22 17:09:45 +04:00
Hyunje Alex Jun
12086573fc Update README.md
Add `npm` to install section.
2014-10-21 21:43:07 +01:00
11 changed files with 505 additions and 215 deletions

View File

@@ -1,6 +1,7 @@
'use strict';
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
// Project configuration.
grunt.initConfig({
@@ -38,15 +39,6 @@ module.exports = function (grunt) {
src: 'src/perfect-scrollbar.js'
}
},
csslint: {
strict: {
options: {
csslintrc: '.csslintrc',
'import': 2
},
src: ['src/perfect-scrollbar.css']
}
},
cssmin: {
options: {
banner: '<%= banner %>'
@@ -67,17 +59,16 @@ module.exports = function (grunt) {
createTag: false,
push: false
}
},
sass: {
dist: {
files: {
'src/perfect-scrollbar.css': 'src/perfect-scrollbar.scss'
}
}
}
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-csslint');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-bump');
grunt.registerTask('default', 'List commands', function () {
grunt.log.writeln("");
@@ -85,12 +76,11 @@ module.exports = function (grunt) {
grunt.log.writeln("Run 'grunt build' to minify the source files");
});
grunt.registerTask('lint', ['jshint', 'csslint']);
grunt.registerTask('build', ['clean', 'uglify', 'cssmin']);
grunt.registerTask('lint', ['jshint']);
grunt.registerTask('build', ['clean', 'uglify', 'sass', 'cssmin']);
grunt.registerTask('travis', ['lint']);
grunt.registerTask('release', 'Release a new version', function (arg) {
var bumpType = arg ? ':' + arg : '';
grunt.task.run(['lint', 'bump' + bumpType, 'build']);
});
};

View File

@@ -44,14 +44,20 @@ You can download the latest stable version with download links in [Github Page](
If you want to use the development version of the plugin, use the source files which are not minified. They're in the `src` directory. The development version may be unstable, but some known bugs can be fixed.
```
git clone https://github.com/noraesae/perfect-scrollbar.git
cd perfect-scrollbar/src
$ git clone https://github.com/noraesae/perfect-scrollbar.git
$ cd perfect-scrollbar/src
```
You can use [Bower](http://bower.io/) to install the plugin. The plugin is registered as `perfect-scrollbar`.
```
bower install perfect-scrollbar
$ bower install perfect-scrollbar
```
It's registered on [npm](https://www.npmjs.org/package/perfect-scrollbar) as `perfect-scrollbar`.
```
$ npm install perfect-scrollbar
```
You can also load it from [cdnjs](http://cdnjs.com/). It is registered as [`jquery.perfect-scrollbar`](http://www.cdnjs.com/libraries/jquery.perfect-scrollbar).
@@ -197,6 +203,8 @@ Helpdesk
If you have any idea to improve this project or any problem using this, please feel free to upload an [issue](https://github.com/noraesae/perfect-scrollbar/issues).
For the problems frequently asked, there's a [FAQ](https://github.com/noraesae/perfect-scrollbar/wiki/FAQ) wiki page. Please check the page before uploading an issue.
License
-------

View File

@@ -1,6 +1,6 @@
{
"name": "perfect-scrollbar",
"version": "0.5.4",
"version": "0.5.7",
"homepage": "http://noraesae.github.io/perfect-scrollbar/",
"authors": [
"Hyunje Alex Jun <me@noraesae.net>"

View File

@@ -0,0 +1,52 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>perfect-scrollbar example</title>
<link href="../src/perfect-scrollbar.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="../src/perfect-scrollbar.js"></script>
<style>
#test {
border: 1px solid gray;
max-height: 300px;
width: 400px;
overflow: hidden;
position: relative;
}
#test .element {
margin: 1px;
background-color: #cec;
height: 44px;
line-height: 44px;
}
</style>
<script type="text/javascript">
$(document).ready(function ($) {
var test = $('#test');
test.perfectScrollbar();
test.find('a').click(function () {
$(this).parent().remove();
test.perfectScrollbar('update');
});
});
</script>
</head>
<body>
<div id="test" class="wrapper">
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
<div class='element'>Hello! Click <a href='#'>here</a> to remove this!</div>
</div>
</body>
</html>

View File

@@ -1,5 +1,5 @@
/*! perfect-scrollbar - v0.5.4
/*! perfect-scrollbar - v0.5.7
* http://noraesae.github.com/perfect-scrollbar/
* Copyright (c) 2014 Hyunje Alex Jun; Licensed MIT */
.ps-container>.ps-scrollbar-x-rail{position:absolute;bottom:3px;height:8px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;opacity:0;filter:alpha(opacity=0);-o-transition:background-color .2s linear,opacity .2s linear;-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear}.ps-container:hover>.ps-scrollbar-x-rail{opacity:.6;filter:alpha(opacity=60)}.ps-container>.ps-scrollbar-x-rail:hover{background-color:#eee;opacity:.9;filter:alpha(opacity=90)}.ps-container>.ps-scrollbar-x-rail.in-scrolling{background-color:#eee;opacity:.9;filter:alpha(opacity=90)}.ps-container>.ps-scrollbar-y-rail{position:absolute;right:3px;width:8px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;opacity:0;filter:alpha(opacity=0);-o-transition:background-color .2s linear,opacity .2s linear;-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear}.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6;filter:alpha(opacity=60)}.ps-container>.ps-scrollbar-y-rail:hover{background-color:#eee;opacity:.9;filter:alpha(opacity=90)}.ps-container>.ps-scrollbar-y-rail.in-scrolling{background-color:#eee;opacity:.9;filter:alpha(opacity=90)}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;bottom:0;height:8px;background-color:#aaa;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-o-transition:background-color .2s linear;-webkit-transition:background-color.2s linear;-moz-transition:background-color .2s linear;transition:background-color .2s linear}.ps-container>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;right:0;width:8px;background-color:#aaa;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-o-transition:background-color .2s linear;-webkit-transition:background-color.2s linear;-moz-transition:background-color .2s linear;transition:background-color .2s linear}.ps-container>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999}
.ps-container.ps-active-x>.ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;border-radius:4px;opacity:0;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;bottom:3px;height:8px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#aaa;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;border-radius:4px;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;bottom:0;height:8px}.ps-container>.ps-scrollbar-x-rail.in-scrolling{background-color:#eee;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;border-radius:4px;opacity:0;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;right:3px;width:8px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#aaa;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;border-radius:4px;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;right:0;width:8px}.ps-container>.ps-scrollbar-y-rail.in-scrolling{background-color:#eee;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6;-ms-filter:"alpha(Opacity=60)";filter:alpha(opacity=60)}.ps-container:hover>.ps-scrollbar-x-rail.in-scrolling,.ps-container:hover>.ps-scrollbar-y-rail.in-scrolling{background-color:#eee;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail:hover{background-color:#eee;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:#eee;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999}

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +1,14 @@
{
"name": "perfect-scrollbar",
"version": "0.5.4",
"version": "0.5.7",
"description": "Tiny but perfect jquery scrollbar plugin.",
"author": "Hyunje Alex Jun <me@noraesae.net>",
"contributors": [{
"name": "Hyunje Alex Jun",
"email": "me@noraesae.net"
}],
"contributors": [
{
"name": "Hyunje Alex Jun",
"email": "me@noraesae.net"
}
],
"main": "src/perfect-scrollbar.js",
"repository": {
"type": "git",
@@ -30,7 +32,9 @@
"grunt-contrib-csslint": "~0.1.2",
"grunt-contrib-cssmin": "~0.6.1",
"grunt-contrib-jshint": "~0.1.1",
"grunt-contrib-uglify": "~0.1.1"
"grunt-contrib-uglify": "~0.1.1",
"grunt-sass": "^0.16.1",
"load-grunt-tasks": "^1.0.0"
},
"scripts": {
"test": "grunt travis --verbose"

View File

@@ -2,7 +2,7 @@
"name": "perfect-scrollbar",
"title": "perfect-scrollbar",
"description": "Tiny but perfect jquery scrollbar plugin.",
"version": "0.5.4",
"version": "0.5.7",
"author": {
"name": "Hyunje Alex Jun",
"email": "me@noraesae.net",

View File

@@ -1,99 +1,101 @@
.ps-container>.ps-scrollbar-x-rail {
position: absolute; /* please don't change 'position' */
bottom: 3px; /* there must be 'bottom' for ps-scrollbar-x-rail */
height: 8px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
opacity: 0;
filter: alpha(opacity=0);
-o-transition: background-color .2s linear, opacity .2s linear;
-webkit-transition: background-color .2s linear, opacity .2s linear;
-moz-transition: background-color .2s linear, opacity .2s linear;
transition: background-color .2s linear, opacity .2s linear;
}
.ps-container:hover>.ps-scrollbar-x-rail {
opacity: 0.6;
filter: alpha(opacity=60);
}
.ps-container>.ps-scrollbar-x-rail:hover {
background-color: #eee;
opacity: 0.9;
filter: alpha(opacity=90);
}
.ps-container>.ps-scrollbar-x-rail.in-scrolling {
background-color: #eee;
opacity: 0.9;
filter: alpha(opacity=90);
}
.ps-container>.ps-scrollbar-y-rail {
position: absolute; /* please don't change 'position' */
right: 3px; /* there must be 'right' for ps-scrollbar-y-rail */
width: 8px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
opacity: 0;
filter: alpha(opacity = 0);
-o-transition: background-color .2s linear, opacity .2s linear;
-webkit-transition: background-color .2s linear, opacity .2s linear;
-moz-transition: background-color .2s linear, opacity .2s linear;
transition: background-color .2s linear, opacity .2s linear;
}
.ps-container:hover>.ps-scrollbar-y-rail {
opacity: 0.6;
filter: alpha(opacity=60);
}
.ps-container>.ps-scrollbar-y-rail:hover {
background-color: #eee;
opacity: 0.9;
filter: alpha(opacity=90);
}
.ps-container>.ps-scrollbar-y-rail.in-scrolling {
background-color: #eee;
opacity: 0.9;
filter: alpha(opacity=90);
}
.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x {
position: absolute; /* please don't change 'position' */
bottom: 0; /* there must be 'bottom' for ps-scrollbar-x */
height: 8px;
.ps-container.ps-active-x > .ps-scrollbar-x-rail, .ps-container.ps-active-y > .ps-scrollbar-y-rail {
display: block; }
.ps-container > .ps-scrollbar-x-rail {
display: none;
position: absolute;
/* please don't change 'position' */
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
border-radius: 4px;
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
-webkit-transition: background-color 0.2s linear, opacity 0.2s linear;
-moz-transition: background-color 0.2s linear, opacity 0.2s linear;
-o-transition: background-color 0.2s linear, opacity 0.2s linear;
transition: background-color 0.2s linear, opacity 0.2s linear;
bottom: 3px;
/* there must be 'bottom' for ps-scrollbar-x-rail */
height: 8px; }
.ps-container > .ps-scrollbar-x-rail > .ps-scrollbar-x {
position: absolute;
/* please don't change 'position' */
background-color: #aaa;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
border-radius: 4px;
-o-transition: background-color .2s linear;
-webkit-transition: background-color.2s linear;
-moz-transition: background-color .2s linear;
transition: background-color .2s linear;
}
.ps-container>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x {
background-color: #999;
}
.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y {
position: absolute; /* please don't change 'position' */
right: 0; /* there must be 'right' for ps-scrollbar-y */
width: 8px;
-webkit-transition: background-color 0.2s linear;
-moz-transition: background-color 0.2s linear;
-o-transition: background-color 0.2s linear;
transition: background-color 0.2s linear;
bottom: 0;
/* there must be 'bottom' for ps-scrollbar-x */
height: 8px; }
.ps-container > .ps-scrollbar-x-rail.in-scrolling {
background-color: #eee;
opacity: 0.9;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)";
filter: alpha(opacity=90); }
.ps-container > .ps-scrollbar-y-rail {
display: none;
position: absolute;
/* please don't change 'position' */
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
border-radius: 4px;
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
-webkit-transition: background-color 0.2s linear, opacity 0.2s linear;
-moz-transition: background-color 0.2s linear, opacity 0.2s linear;
-o-transition: background-color 0.2s linear, opacity 0.2s linear;
transition: background-color 0.2s linear, opacity 0.2s linear;
right: 3px;
/* there must be 'right' for ps-scrollbar-y-rail */
width: 8px; }
.ps-container > .ps-scrollbar-y-rail > .ps-scrollbar-y {
position: absolute;
/* please don't change 'position' */
background-color: #aaa;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
border-radius: 4px;
-o-transition: background-color .2s linear;
-webkit-transition: background-color.2s linear;
-moz-transition: background-color .2s linear;
transition: background-color .2s linear;
}
.ps-container>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y {
background-color: #999;
}
-webkit-transition: background-color 0.2s linear;
-moz-transition: background-color 0.2s linear;
-o-transition: background-color 0.2s linear;
transition: background-color 0.2s linear;
right: 0;
/* there must be 'right' for ps-scrollbar-y */
width: 8px; }
.ps-container > .ps-scrollbar-y-rail.in-scrolling {
background-color: #eee;
opacity: 0.9;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)";
filter: alpha(opacity=90); }
.ps-container:hover > .ps-scrollbar-x-rail, .ps-container:hover > .ps-scrollbar-y-rail {
opacity: 0.6;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
filter: alpha(opacity=60); }
.ps-container:hover > .ps-scrollbar-x-rail.in-scrolling, .ps-container:hover > .ps-scrollbar-y-rail.in-scrolling {
background-color: #eee;
opacity: 0.9;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)";
filter: alpha(opacity=90); }
.ps-container:hover > .ps-scrollbar-x-rail:hover {
background-color: #eee;
opacity: 0.9;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)";
filter: alpha(opacity=90); }
.ps-container:hover > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x {
background-color: #999; }
.ps-container:hover > .ps-scrollbar-y-rail:hover {
background-color: #eee;
opacity: 0.9;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)";
filter: alpha(opacity=90); }
.ps-container:hover > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y {
background-color: #999; }

View File

@@ -39,20 +39,25 @@
includePadding: false
};
var getEventClassName = (function () {
var incrementingId = 0;
return function () {
var id = incrementingId;
incrementingId += 1;
return '.perfect-scrollbar-' + id;
var incrementingId = 0;
var eventClassFactory = function () {
var id = incrementingId++;
return function (eventName) {
var className = '.perfect-scrollbar-' + id;
if (typeof eventName === 'undefined') {
return className;
} else {
return eventName + className;
}
};
})();
};
$.fn.perfectScrollbar = function (suppliedSettings, option) {
return this.each(function () {
var settings = $.extend(true, {}, defaultSettings);
var $this = $(this);
var isPluginAlive = function () { return !!$this; };
if (typeof suppliedSettings === "object") {
// Override default settings with any supplied
@@ -92,7 +97,7 @@
var contentHeight;
var isRtl = $this.css('direction') === "rtl";
var eventClassName = getEventClassName();
var eventClass = eventClassFactory();
var ownerDocument = this.ownerDocument || document;
var $scrollbarXRail = $("<div class='ps-scrollbar-x-rail'>").appendTo($this);
@@ -113,7 +118,7 @@
var scrollbarYRight = int($scrollbarYRail.css('right'));
var isScrollbarYUsingRight = scrollbarYRight === scrollbarYRight; // !isNaN
var scrollbarYLeft = isScrollbarYUsingRight ? null : int($scrollbarYRail.css('left'));
var railBorderYWidth = int($scrollbarXRail.css('borderTopWidth')) + int($scrollbarXRail.css('borderBottomWidth'));
var railBorderYWidth = int($scrollbarYRail.css('borderTopWidth')) + int($scrollbarYRail.css('borderBottomWidth'));
function updateScrollTop(currentTop, deltaY) {
var newTop = currentTop + deltaY;
@@ -158,7 +163,7 @@
}
function updateCss() {
var xRailOffset = {width: containerWidth, display: scrollbarXActive ? "inherit" : "none"};
var xRailOffset = {width: containerWidth};
if (isRtl) {
xRailOffset.left = $this.scrollLeft() + containerWidth - contentWidth;
} else {
@@ -171,7 +176,7 @@
}
$scrollbarXRail.css(xRailOffset);
var railYOffset = {top: $this.scrollTop(), height: containerHeight, display: scrollbarYActive ? "inherit" : "none"};
var railYOffset = {top: $this.scrollTop(), height: containerHeight};
if (isScrollbarYUsingRight) {
if (isRtl) {
@@ -194,8 +199,8 @@
function updateGeometry() {
// Hide scrollbars not to affect scrollWidth and scrollHeight
$scrollbarXRail.hide();
$scrollbarYRail.hide();
$this.removeClass('ps-active-x');
$this.removeClass('ps-active-y');
containerWidth = settings.includePadding ? $this.innerWidth() : $this.width();
containerHeight = settings.includePadding ? $this.innerHeight() : $this.height();
@@ -235,22 +240,9 @@
if (scrollbarXActive) {
$this.addClass('ps-active-x');
} else {
$this.removeClass('ps-active-x');
}
if (scrollbarYActive) {
$this.addClass('ps-active-y');
} else {
$this.removeClass('ps-active-y');
}
// Show scrollbars if needed after updated
if (!settings.suppressScrollX) {
$scrollbarXRail.show();
}
if (!settings.suppressScrollY) {
$scrollbarYRail.show();
}
}
@@ -258,16 +250,18 @@
var currentLeft;
var currentPageX;
$scrollbarX.bind('mousedown' + eventClassName, function (e) {
var inScrolling = false;
$scrollbarX.bind(eventClass('mousedown'), function (e) {
currentPageX = e.pageX;
currentLeft = $scrollbarX.position().left;
$scrollbarXRail.addClass('in-scrolling');
inScrolling = true;
e.stopPropagation();
e.preventDefault();
});
$(ownerDocument).bind('mousemove' + eventClassName, function (e) {
if ($scrollbarXRail.hasClass('in-scrolling')) {
$(ownerDocument).bind(eventClass('mousemove'), function (e) {
if (inScrolling) {
updateScrollLeft(currentLeft, e.pageX - currentPageX);
updateGeometry();
e.stopPropagation();
@@ -275,8 +269,9 @@
}
});
$(ownerDocument).bind('mouseup' + eventClassName, function (e) {
if ($scrollbarXRail.hasClass('in-scrolling')) {
$(ownerDocument).bind(eventClass('mouseup'), function (e) {
if (inScrolling) {
inScrolling = false;
$scrollbarXRail.removeClass('in-scrolling');
}
});
@@ -289,16 +284,18 @@
var currentTop;
var currentPageY;
$scrollbarY.bind('mousedown' + eventClassName, function (e) {
var inScrolling = false;
$scrollbarY.bind(eventClass('mousedown'), function (e) {
currentPageY = e.pageY;
currentTop = $scrollbarY.position().top;
inScrolling = true;
$scrollbarYRail.addClass('in-scrolling');
e.stopPropagation();
e.preventDefault();
});
$(ownerDocument).bind('mousemove' + eventClassName, function (e) {
if ($scrollbarYRail.hasClass('in-scrolling')) {
$(ownerDocument).bind(eventClass('mousemove'), function (e) {
if (inScrolling) {
updateScrollTop(currentTop, e.pageY - currentPageY);
updateGeometry();
e.stopPropagation();
@@ -306,8 +303,9 @@
}
});
$(ownerDocument).bind('mouseup' + eventClassName, function (e) {
if ($scrollbarYRail.hasClass('in-scrolling')) {
$(ownerDocument).bind(eventClass('mouseup'), function (e) {
if (inScrolling) {
inScrolling = false;
$scrollbarYRail.removeClass('in-scrolling');
}
});
@@ -410,23 +408,23 @@
}
if (typeof window.onwheel !== "undefined") {
$this.bind('wheel' + eventClassName, mousewheelHandler);
$this.bind(eventClass('wheel'), mousewheelHandler);
} else if (typeof window.onmousewheel !== "undefined") {
$this.bind('mousewheel' + eventClassName, mousewheelHandler);
$this.bind(eventClass('mousewheel'), mousewheelHandler);
}
}
function bindKeyboardHandler() {
var hovered = false;
$this.bind('mouseenter' + eventClassName, function (e) {
$this.bind(eventClass('mouseenter'), function (e) {
hovered = true;
});
$this.bind('mouseleave' + eventClassName, function (e) {
$this.bind(eventClass('mouseleave'), function (e) {
hovered = false;
});
var shouldPrevent = false;
$(ownerDocument).bind('keydown' + eventClassName, function (e) {
$(ownerDocument).bind(eventClass('keydown'), function (e) {
if (e.isDefaultPrevented && e.isDefaultPrevented()) {
return;
}
@@ -498,8 +496,8 @@
function bindRailClickHandler() {
function stopPropagation(e) { e.stopPropagation(); }
$scrollbarY.bind('click' + eventClassName, stopPropagation);
$scrollbarYRail.bind('click' + eventClassName, function (e) {
$scrollbarY.bind(eventClass('click'), stopPropagation);
$scrollbarYRail.bind(eventClass('click'), function (e) {
var halfOfScrollbarLength = int(scrollbarYHeight / 2);
var positionTop = e.pageY - $scrollbarYRail.offset().top - halfOfScrollbarLength;
var maxPositionTop = containerHeight - scrollbarYHeight;
@@ -514,8 +512,8 @@
$this.scrollTop((contentHeight - containerHeight) * positionRatio);
});
$scrollbarX.bind('click' + eventClassName, stopPropagation);
$scrollbarXRail.bind('click' + eventClassName, function (e) {
$scrollbarX.bind(eventClass('click'), stopPropagation);
$scrollbarXRail.bind(eventClass('click'), function (e) {
var halfOfScrollbarLength = int(scrollbarXWidth / 2);
var positionLeft = e.pageX - $scrollbarXRail.offset().left - halfOfScrollbarLength;
var maxPositionLeft = containerWidth - scrollbarXWidth;
@@ -531,6 +529,106 @@
});
}
function bindSelectionHandler() {
function getRangeNode() {
var selection = window.getSelection ? window.getSelection() :
document.getSlection ? document.getSlection() : {rangeCount: 0};
if (selection.rangeCount === 0) {
return null;
} else {
return selection.getRangeAt(0).commonAncestorContainer;
}
}
var scrollingLoop = null;
var scrollDiff = {top: 0, left: 0};
function startScrolling() {
if (!scrollingLoop) {
scrollingLoop = setInterval(function () {
if (!isPluginAlive()) {
clearInterval(scrollingLoop);
return;
}
$this.scrollTop($this.scrollTop() + scrollDiff.top);
$this.scrollLeft($this.scrollLeft() + scrollDiff.left);
updateGeometry();
}, 50); // every .1 sec
}
}
function stopScrolling() {
if (scrollingLoop) {
clearInterval(scrollingLoop);
scrollingLoop = null;
}
$scrollbarXRail.removeClass('in-scrolling');
$scrollbarYRail.removeClass('in-scrolling');
}
var isSelected = false;
$(ownerDocument).bind(eventClass('selectionchange'), function (e) {
if ($.contains($this[0], getRangeNode())) {
isSelected = true;
} else {
isSelected = false;
stopScrolling();
}
});
$(window).bind(eventClass('mouseup'), function (e) {
if (isSelected) {
isSelected = false;
stopScrolling();
}
});
$(window).bind(eventClass('mousemove'), function (e) {
if (isSelected) {
var mousePosition = {x: e.pageX, y: e.pageY};
var containerOffset = $this.offset();
var containerGeometry = {
left: containerOffset.left,
right: containerOffset.left + $this.outerWidth(),
top: containerOffset.top,
bottom: containerOffset.top + $this.outerHeight()
};
if (mousePosition.x < containerGeometry.left + 3) {
scrollDiff.left = -5;
$scrollbarXRail.addClass('in-scrolling');
} else if (mousePosition.x > containerGeometry.right - 3) {
scrollDiff.left = 5;
$scrollbarXRail.addClass('in-scrolling');
} else {
scrollDiff.left = 0;
}
if (mousePosition.y < containerGeometry.top + 3) {
if (containerGeometry.top + 3 - mousePosition.y < 5) {
scrollDiff.top = -5;
} else {
scrollDiff.top = -20;
}
$scrollbarYRail.addClass('in-scrolling');
} else if (mousePosition.y > containerGeometry.bottom - 3) {
if (mousePosition.y - containerGeometry.bottom + 3 < 5) {
scrollDiff.top = 5;
} else {
scrollDiff.top = 20;
}
$scrollbarYRail.addClass('in-scrolling');
} else {
scrollDiff.top = 0;
}
if (scrollDiff.top === 0 && scrollDiff.left === 0) {
stopScrolling();
} else {
startScrolling();
}
}
});
}
function bindTouchHandler(supportsTouch, supportsIePointer) {
function applyTouchMove(differenceX, differenceY) {
$this.scrollTop($this.scrollTop() - differenceY);
@@ -542,8 +640,9 @@
var startOffset = {};
var startTime = 0;
var speed = {};
var breakingProcess = null;
var easingLoop = null;
var inGlobalTouch = false;
var inLocalTouch = false;
function globalTouchStart(e) {
inGlobalTouch = true;
@@ -560,23 +659,36 @@
return e.originalEvent;
}
}
function touchStart(e) {
var touch = getTouch(e);
startOffset.pageX = touch.pageX;
startOffset.pageY = touch.pageY;
startTime = (new Date()).getTime();
if (breakingProcess !== null) {
clearInterval(breakingProcess);
function shouldHandle(e) {
var event = e.originalEvent;
if (event.targetTouches && event.targetTouches.length === 1) {
return true;
}
if (event.pointerType && event.pointerType !== 'mouse' && event.pointerType !== event.MSPOINTER_TYPE_MOUSE) {
return true;
}
return false;
}
function touchStart(e) {
if (shouldHandle(e)) {
inLocalTouch = true;
e.stopPropagation();
e.preventDefault();
var touch = getTouch(e);
startOffset.pageX = touch.pageX;
startOffset.pageY = touch.pageY;
startTime = (new Date()).getTime();
if (easingLoop !== null) {
clearInterval(easingLoop);
}
e.stopPropagation();
}
}
function touchMove(e) {
if (!inGlobalTouch && e.originalEvent.targetTouches.length === 1) {
if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
var touch = getTouch(e);
var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};
@@ -601,55 +713,64 @@
}
}
function touchEnd(e) {
clearInterval(breakingProcess);
breakingProcess = setInterval(function () {
if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
clearInterval(breakingProcess);
return;
}
if (!inGlobalTouch && inLocalTouch) {
inLocalTouch = false;
applyTouchMove(speed.x * 30, speed.y * 30);
clearInterval(easingLoop);
easingLoop = setInterval(function () {
if (!isPluginAlive()) {
clearInterval(easingLoop);
return;
}
speed.x *= 0.8;
speed.y *= 0.8;
}, 10);
if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
clearInterval(easingLoop);
return;
}
applyTouchMove(speed.x * 30, speed.y * 30);
speed.x *= 0.8;
speed.y *= 0.8;
}, 10);
}
}
if (supportsTouch) {
$(window).bind("touchstart" + eventClassName, globalTouchStart);
$(window).bind("touchend" + eventClassName, globalTouchEnd);
$this.bind("touchstart" + eventClassName, touchStart);
$this.bind("touchmove" + eventClassName, touchMove);
$this.bind("touchend" + eventClassName, touchEnd);
$(window).bind(eventClass("touchstart"), globalTouchStart);
$(window).bind(eventClass("touchend"), globalTouchEnd);
$this.bind(eventClass("touchstart"), touchStart);
$this.bind(eventClass("touchmove"), touchMove);
$this.bind(eventClass("touchend"), touchEnd);
}
if (supportsIePointer) {
if (window.PointerEvent) {
$(window).bind("pointerdown" + eventClassName, globalTouchStart);
$(window).bind("pointerup" + eventClassName, globalTouchEnd);
$this.bind("pointerdown" + eventClassName, touchStart);
$this.bind("pointermove" + eventClassName, touchMove);
$this.bind("pointerup" + eventClassName, touchEnd);
$(window).bind(eventClass("pointerdown"), globalTouchStart);
$(window).bind(eventClass("pointerup"), globalTouchEnd);
$this.bind(eventClass("pointerdown"), touchStart);
$this.bind(eventClass("pointermove"), touchMove);
$this.bind(eventClass("pointerup"), touchEnd);
} else if (window.MSPointerEvent) {
$(window).bind("MSPointerDown" + eventClassName, globalTouchStart);
$(window).bind("MSPointerUp" + eventClassName, globalTouchEnd);
$this.bind("MSPointerDown" + eventClassName, touchStart);
$this.bind("MSPointerMove" + eventClassName, touchMove);
$this.bind("MSPointerUp" + eventClassName, touchEnd);
$(window).bind(eventClass("MSPointerDown"), globalTouchStart);
$(window).bind(eventClass("MSPointerUp"), globalTouchEnd);
$this.bind(eventClass("MSPointerDown"), touchStart);
$this.bind(eventClass("MSPointerMove"), touchMove);
$this.bind(eventClass("MSPointerUp"), touchEnd);
}
}
}
function bindScrollHandler() {
$this.bind('scroll' + eventClassName, function (e) {
$this.bind(eventClass('scroll'), function (e) {
updateGeometry();
});
}
function destroy() {
$this.unbind(eventClassName);
$(window).unbind(eventClassName);
$(ownerDocument).unbind(eventClassName);
$this.unbind(eventClass());
$(window).unbind(eventClass());
$(ownerDocument).unbind(eventClass());
$this.data('perfect-scrollbar', null);
$this.data('perfect-scrollbar-update', null);
$this.data('perfect-scrollbar-destroy', null);
@@ -659,6 +780,7 @@
$scrollbarYRail.remove();
// clean all variables
$this =
$scrollbarXRail =
$scrollbarYRail =
$scrollbarX =
@@ -680,7 +802,7 @@
isScrollbarYUsingRight =
scrollbarYLeft =
isRtl =
eventClassName = null;
eventClass = null;
}
var supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch);
@@ -692,6 +814,7 @@
bindMouseScrollXHandler();
bindMouseScrollYHandler();
bindRailClickHandler();
bindSelectionHandler();
bindMouseWheelHandler();
if (supportsTouch || supportsIePointer) {

111
src/perfect-scrollbar.scss Normal file
View File

@@ -0,0 +1,111 @@
// Helper mixins
@mixin opacity($o) {
$IEValue: $o * 100;
opacity: $o;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity="+$IEValue+")";
filter: alpha(opacity=$IEValue);
}
@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);
@include opacity(0);
@include transition(background-color .2s linear, opacity .2s linear);
}
@mixin scrollbar-rail-hover {
background-color: #eee;
@include opacity(0.9);
}
@mixin scrollbar-default {
position: absolute; /* please don't change 'position' */
background-color: #aaa;
@include border-radius(4px);
@include transition(background-color .2s linear);
}
@mixin scrollbar-hover {
background-color: #999;
}
@mixin in-scrolling {
&.in-scrolling {
@include scrollbar-rail-hover;
}
}
.ps-container {
&.ps-active-x > .ps-scrollbar-x-rail,
&.ps-active-y > .ps-scrollbar-y-rail {
display: block;
}
>.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;
}
@include in-scrolling;
}
>.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;
}
@include in-scrolling;
}
&:hover {
>.ps-scrollbar-x-rail,
>.ps-scrollbar-y-rail {
@include opacity(0.6);
@include in-scrolling;
}
>.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;
}
}
}
}