Compare commits

...

61 Commits
0.2.2 ... 0.4.1

Author SHA1 Message Date
Hyunje Alex Jun
5124a27113 Release 0.4.1.
Patch notes
1. Wrap core functionality in an each function.
2. Use scrollHeight and scrollWidth for content size.
3. IE fixes.
4. Bug fixes.
2013-06-27 11:26:21 +09:00
Hyunje Alex Jun
fa5e6cb38c Add version number in minified sources.
Version number is parsed from package.json.
Before release, the version number have '-dev' postfix.
2013-06-18 18:54:09 +09:00
Hyunje Alex Jun
dd89f14243 Add contrib-clean to Grunt.
We should clean 'min' directory before build.
2013-06-18 18:46:40 +09:00
Hyunje Alex Jun
7e5b225d61 Display an old version requirement.
This reverts commit f7d953d1eb2e3315d6b6b9d1f9ed217eaa22be6d.

And add 'for old versions' mark to the requirement.
2013-06-18 16:19:10 +09:00
Hyunje Alex Jun
e35920f10e Update README.
Add 'IE Support'.
2013-06-16 18:31:29 +09:00
Hyunje Alex Jun
4f6463114c Merge the patches of @maoziliang.
Includes IE fixes.
2013-06-16 17:59:21 +09:00
Hyunje Alex Jun
f02f5e89b7 Fix ie6 scrollbar position problem.
This patch is in fact contributed by the idea of @maoziliang.
2013-06-16 17:56:40 +09:00
Hyunje Alex Jun
21d5d4ab63 Separate the function updating the css of scrollbars. 2013-06-16 17:45:37 +09:00
maoziliang
e833f42d02 Fixed the scrollbar height for xp sp3 ie6
set 'font-size:0' for the scrollbar
2013-06-16 17:22:18 +09:00
maoziliang
a52d55957d Add hover handlers for ie6.
Use scripts to add '.hover' class on the `.ps-container` and both
scrollbars when then mouse is over them because :hover is not supported
except 'a' element.
2013-06-16 17:13:20 +09:00
maoziliang
e93d67e754 Add feature to suport ie.
For ie browser, the `.ps-container` element will add extra class `ie`
and `ie<version>`, like `ie6`, `ie7`, `ie8`, etc.
2013-06-16 17:00:12 +09:00
maoziliang
37210ee453 Add a sample based on text content 2013-06-16 16:49:30 +09:00
Hyunje Alex Jun
6021ec016e Update README.
The link to Contributing wiki page is added.
2013-06-16 00:30:43 +09:00
Hyunje Alex Jun
9be4a1a85f Minify source files with the new build system.
From now, the build can be done with 'grunt build'.
2013-06-16 00:30:43 +09:00
Hyunje Alex Jun
f65c9cb0bb Add files for Grunt. 2013-06-16 00:30:43 +09:00
Hyunje Alex Jun
29a0c13c65 Add csslintrc. 2013-06-15 22:04:50 +09:00
Hyunje Alex Jun
d8c961ee32 Csslint the css file. 2013-06-15 22:04:50 +09:00
Hyunje Alex Jun
a4d8487ee3 Remove build shell script.
We'll use grunt to build the scripts.
The shell script is no more used.
2013-06-15 20:59:26 +09:00
Hyunje Alex Jun
ff55090cd3 Add node_modules in gitignore. 2013-06-15 20:59:07 +09:00
Hyunje Alex Jun
7bc05bbda1 Refactor jshint files.
We'll use grunt, and jshintignore is useless.
Remove comments in jshintrc to be parsed in grunt.
2013-06-15 20:49:22 +09:00
Hyunje Alex Jun
3b1c37440e Inhance the scroll logic with mobile touches.
The scroll works only when the user touch and scroll the wrapper div
with just one touch. By this patch, the zoom function will not be
prevented by scrolling content.
2013-06-14 21:57:24 +09:00
Hyunje Alex Jun
aeab94c7d6 Fix the wrong indents in example pages. 2013-06-14 21:39:53 +09:00
Hyunje Alex Jun
eb8f28cd26 JSHint the code.
Missing space.
2013-06-14 21:38:33 +09:00
Hyunje Alex Jun
d5ef529438 Modify README.md.
The requirement that force just one content element is gone.
2013-06-14 21:36:47 +09:00
Hyunje Alex Jun
34a505d319 Remove $content.
It's not used anymore.
2013-06-14 21:35:32 +09:00
Hyunje Alex Jun
a8db04e41d Merge pull request #36 from zenozeng/master
Use prop('scrollWidth') and prop('scrollHeight') instead of outerWidth() and outerHeight() to get the content size.
2013-06-14 05:32:44 -07:00
Zeno Zeng
d14dfd307e use scrollHeight & scrollWidth to avoid getting the wrong size of the content 2013-06-14 10:13:30 +08:00
Hyunje Alex Jun
de6e4d59b0 Merge pull request #34 from itsdrewmiller/master
pull request for the fix provided in issue 16, for both vertical and horizontal scrolling
2013-06-12 09:29:49 -07:00
itsdrewmiller
351631cfa7 Fixing jumpiness for large scrolls
https://github.com/noraesae/perfect-scrollbar/issues/16
2013-06-12 12:57:43 -03:00
Hyunje Alex Jun
2f6432d263 Merge pull request #30 from maoziliang/master
Update the destroy method. Unbind listeners by event namespace.
2013-06-01 20:40:34 -07:00
maoziliang
3410cf89be update the destroy method. unbind listeners by event namespace.
This will be convenient for adding new event bind in the file. Do not
worry about forgetting to unbind it.
2013-06-02 11:16:33 +08:00
Hyunje Alex Jun
b89660f959 Merge pull request #26 from ahmadsherif/master
Wrap core functionality in an each function.
2013-05-22 18:46:32 -07:00
Ahmad Sherif
d5dd3422cf Wrap core functionality in an each function
If we have many DOM elements that match the PerfectScrollbar selector,
then all elemets get scrolled if one of them is scrolled.
2013-05-22 11:48:51 +02:00
Hyunje Alex Jun
c6c087275c Release 0.3.4.
Patch notes
1. Fix the bug that scrollbars don't stop at the end.
2. Code refactoring.
2013-05-18 12:43:38 +09:00
Hyunje Alex Jun
4613c3daee Code refactoring. 2013-05-18 12:41:15 +09:00
Hyunje Alex Jun
667c61d2c3 Add jshint files. 2013-05-18 12:39:26 +09:00
Hyunje Alex Jun
4012ce9c8c Prevent scrollbar x from moving out of the container. 2013-05-18 12:21:20 +09:00
Hyunje Alex Jun
9734a18d01 Merge pull request #19 from EtnasSoft/master
Fixed bug with the Mouse Wheel and the right scroll bar.
2013-05-17 20:18:19 -07:00
etnassoft
4f49b0fa7f Fix bug with mouse wheel 2013-03-21 11:21:20 +01:00
Hyunje Alex Jun
9d6728e3ff Release 0.3.3.
Patch notes
1. Apply jshint.
2. Fix jQuery plugin site version problem.
2013-03-14 15:47:20 +09:00
Hyunje Alex Jun
69c37268a1 Apply jshint. 2013-03-14 15:46:12 +09:00
Hyunje Alex Jun
960468fc9e Release 0.3.2.
Patch notes
1. Optional parameter support.
 - wheelSpeed
 - wheelPropagation
2. Example codes added.
2013-03-14 15:14:38 +09:00
Hyunje Alex Jun
42d528a839 Update README.md
Optional parameter support.
2013-03-14 13:44:51 +09:00
Hyunje Alex Jun
26e9ff1cac Example codes added by @GregDThomas. 2013-03-14 11:49:50 +09:00
GregDThomas
38b8b818e8 See issue #10 - provide support for optional settings, including prevention of the mousewheel event and the speed of scrolling 2013-03-14 11:36:57 +09:00
Hyunje Alex Jun
938f3134d7 Release 0.3.1.
Patch notes
1. Mobile touch support.
2. Scrolling logic enhancement.
3. Bug fix.
2013-02-16 00:23:49 +09:00
Hyunje Alex Jun
aa213398f3 Enhance scroll preventDefault logic.
Now scroll preventDefault works more like default browser scroll.
When the scroll leaches top, bottom, left and right end, don't
prevent default scrolling. For sure, when the content size is
smaller than the container size, also don't prevent default scrolling.
2013-02-16 00:17:23 +09:00
Hyunje Alex Jun
1cdbc9509f Fix missed ';'
In JavaScript, it's the convension that ';' is placed
at the end of statement
2013-02-15 23:58:57 +09:00
David
627b6a6b81 Take into account padding and margins on content
Changed the height and widths calculations of the content div to
include any padding and/or margins.

outerHeight(true) is changed to outerHeight(false).
outerWidth is changed as same.
Fixed by noraesae.
2013-02-15 23:44:20 +09:00
Hyunje Alex Jun
0099bb556c Supports the mobile touch scrolling.
Using touch events, support mobile scrolling with touch.
2013-02-12 22:37:45 +09:00
Hyunje Alex Jun
2e1e9f2f75 Release 0.2.5.
Patch notes
1. Bug fix.
2. Include min version with jquery-mousewheel.
2013-02-08 10:38:43 +09:00
Hyunje Alex Jun
f3b6fd520c Modify build script to uglifyjs2.
Upgrade to uglifyjs2 and add shell script to create
a min version source that includes jquery-mousewheel.
2013-02-08 10:36:01 +09:00
Hyunje Alex Jun
a6bb9d02a3 Include jquery-mousewheel in src. 2013-02-08 10:35:34 +09:00
Hyunje Alex Jun
639f369d33 Merge pull request #2 from davidkethel/patch-2
Ensure div is at top/left when scroll bars removed
2013-02-07 17:07:19 -08:00
David
dacb601f9f Update src/perfect_scrollbar.js
Ensure the panel is at the top after an update where the scroll bars
are removed. Other wise it is possible to get stuck midway down a panel
with no way of scrolling.
2013-02-07 14:29:44 +10:00
Hyunje Alex Jun
0c9dc8dbb4 Merge pull request #1 from davidkethel/patch-1
Just a couple of small grammar changes
2013-02-06 05:44:16 -08:00
David
f32e32485b Just a couple of small grammar changes 2013-02-06 20:02:02 +10:00
Hyunje Alex Jun
a4bee31597 Update README.md
Add the way how to scroll to somewhere.
2013-01-28 14:00:49 +09:00
Hyunje Alex Jun
bd9e96be12 Release 0.2.4.
Release to jquery plugins.
2013-01-28 13:52:25 +09:00
Hyunje Alex Jun
1bd0c102db IE support. 2012-11-10 17:30:09 +09:00
Hyunje Alex Jun
36ae8c4059 Add .gitignore. 2012-11-10 13:44:08 +09:00
21 changed files with 887 additions and 199 deletions

3
.csslintrc Normal file
View File

@@ -0,0 +1,3 @@
{
"adjoining-classes": false
}

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.DS_Store
node_modules

60
.jshintrc Normal file
View File

@@ -0,0 +1,60 @@
{
"passfail" : false,
"maxerr" : 100,
"browser" : true,
"node" : true,
"rhino" : false,
"couch" : false,
"wsh" : false,
"jquery" : true,
"prototypejs" : false,
"mootools" : false,
"dojo" : false,
"predef" : [
"require",
"define"
],
"debug" : false,
"devel" : true,
"es5" : true,
"strict" : false,
"globalstrict" : true,
"asi" : false,
"laxbreak" : false,
"bitwise" : true,
"boss" : false,
"curly" : true,
"eqeqeq" : true,
"eqnull" : false,
"evil" : false,
"expr" : false,
"forin" : false,
"immed" : true,
"latedef" : true,
"loopfunc" : false,
"noarg" : true,
"regexp" : true,
"regexdash" : false,
"scripturl" : true,
"shadow" : false,
"supernew" : false,
"undef" : true,
"newcap" : true,
"noempty" : false,
"nonew" : true,
"nomen" : false,
"onevar" : false,
"plusplus" : false,
"sub" : false,
"trailing" : true,
"white" : true,
"indent" : 2
}

86
Gruntfile.js Normal file
View File

@@ -0,0 +1,86 @@
'use strict';
module.exports = function (grunt) {
// Project configuration.
grunt.initConfig({
// Metadata.
pkg: grunt.file.readJSON('perfect-scrollbar.jquery.json'),
version: grunt.file.readJSON('package.json').version,
banner: '/*! <%= pkg.title || pkg.name %> - v<%= version %>\n' +
'<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
clean: {
files: ['min']
},
// Task configuration.
uglify: {
options: {
banner: '<%= banner %>'
},
min: {
files: {
'min/perfect-scrollbar-<%= version %>.min.js': ['src/perfect-scrollbar.js'],
'min/perfect-scrollbar-<%= version %>.with-mousewheel.min.js': [
'src/perfect-scrollbar.js',
'src/jquery.mousewheel.js'
]
}
},
},
jshint: {
gruntfile: {
options: {
jshintrc: '.jshintrc'
},
src: 'Gruntfile.js'
},
src: {
options: {
jshintrc: '.jshintrc'
},
src: 'src/perfect-scrollbar.js'
}
},
csslint: {
strict: {
options: {
csslintrc: '.csslintrc',
import: 2
},
src: ['src/perfect-scrollbar.css']
}
},
cssmin: {
options: {
banner: '<%= banner %>'
},
minify: {
expand: true,
cwd: 'src/',
src: ['perfect-scrollbar.css'],
dest: 'min/',
ext: '-<%= version %>.min.css'
}
}
});
// 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.registerTask('default', 'List commands', function () {
grunt.log.writeln("");
grunt.log.writeln("Run 'grunt lint' to lint the source files");
grunt.log.writeln("Run 'grunt build' to minify the source files");
});
grunt.registerTask('lint', ['jshint', 'csslint']);
grunt.registerTask('build', ['clean', 'uglify', 'cssmin']);
};

View File

@@ -39,13 +39,30 @@ It's cool, isn't it?
Requirements
------------
To make this plugin *perfect*, some requirements was not avoidable. But they're all very trivial and there's nothing to worry.
To make this plugin *perfect*, some requirements were not avoidable. But they're all very trivial and there's nothing to worry about.
* there must be the *one* content element(like div) for the container.
* the container must have a 'position' css style.
* the scrollbar's position must be 'absolute'.
* the scrollbar-x must have a 'bottom' css style, and the scrollbar-y must have a 'right' css style.
The requirement below is for perfect-scrollbar &lt;= 0.3.4
* there must be the *one* content element(like div) for the container.
Optional parameters
-------------------
perfect-scrollbar supports optional parameters.
### wheelSpeed
The scroll speed applied to mousewheel event.
Default: 10
### wheelPropagation
If this option is true, when the scroll reach the end of the side, mousewheel event will be propagated to parent element.
Default: false
How to Use
----------
@@ -63,6 +80,15 @@ When the html document is like above, just use like this:
```javascript
$('#Demo').perfectScrollbar();
```
With optional parameters:
```javascript
$("#Demo").perfectScrollbar({
wheelSpeed: 20,
wheelPropagation: true
})
```
If the size of your container or content changes:
```javascript
$('#Demo').perfectScrollbar('update');
@@ -72,6 +98,12 @@ If you want to destory the scrollbar:
$('#Demo').perfectScrollbar('destroy');
```
If you want to scroll to somewhere, just use scroll-top css and update.
```javascript
$("#Demo").scrollTop(0);
$("#Demo").perfectScrollbar('update');
```
Very helpful friends
--------------------
@@ -82,13 +114,27 @@ If you want to make this plugin's update function more responsive, [jquery-resiz
Contribution
------------
#### Please read [Contributing](https://github.com/noraesae/perfect-scrollbar/wiki/Contributing) in the wiki before making any contibution.
I *really* welcome contributions! Please feel free to fork and issue pull requests when...
* You have a very nice idea to improve this plugin!
* You found a bug!
* You're good at English and can help my bad English!
Also you can just open issues, and I can look into them.
For IE problems, please refer to [IE Support](https://github.com/noraesae/perfect-scrollbar#ie-support)
IE Support
----------
This plugin supports old IE browsers in the **minimum** range. The plugin is tested in IEs >= IE6 and works(not well, but works).
**But the project will not accept the patches to fix IE problems in IE 6/7/8.**
From jQuery 2.0, jQuery also will not support IE 6/7/8. I also think that supporting old browsers really breaks the web development conventions.
When old IEs should be supported, please fork the project and make patches personally.
License
-------

3
build
View File

@@ -1,3 +0,0 @@
#!/bin/sh
uglifyjs src/perfect-scrollbar.js > min/perfect-scrollbar.min.js
cleancss src/perfect-scrollbar.css -o min/perfect-scrollbar.min.css

BIN
examples/azusa.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<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.8.0/jquery.min.js"></script>
<script src="../src/jquery.mousewheel.js"></script>
<script src="../src/perfect-scrollbar.js"></script>
<style>
.contentHolder { position:relative; margin:0px auto; padding:0px; width: 600px; height: 400px; overflow: hidden; }
.contentHolder .content { background-image: url('./azusa.jpg'); width: 1280px; height: 720px; }
.spacer { text-align:center }
</style>
<script>
jQuery(document).ready(function ($) {
"use strict";
$('#Default').perfectScrollbar();
});
</script>
</head>
<body>
<div id="Default" class="contentHolder">
<div class="content">
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>perfect-scrollbar example - use wheelPropagation to control propagation of scrolling at extremities</title>
<link href="../src/perfect-scrollbar.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="../src/jquery.mousewheel.js"></script>
<script src="../src/perfect-scrollbar.js"></script>
<style>
.contentHolder { position:relative; margin:0px auto; padding:0px; width: 600px; height: 400px; overflow: hidden; }
.contentHolder .content { background-image: url('./azusa.jpg'); width: 1280px; height: 720px; }
.spacer { text-align:center }
</style>
<script>
jQuery(document).ready(function ($) {
"use strict";
$('#Default').perfectScrollbar();
$('#NoWheelPropagation').perfectScrollbar({wheelPropagation:true});
});
</script>
</head>
<body>
<h1 style="text-align:center">Default; wheelPropagation:false</h1>
<div id="Default" class="contentHolder">
<div class="content">
</div>
</div>
<h1 style="text-align:center">wheelPropagation:true</h1>
<div id="NoWheelPropagation" class="contentHolder">
<div class="content">
</div>
</div>
<div class="spacer">
Note<br>that<br>there<br>is<br>plenty<br>of<br>text<br>after<br>the<br>image<br>to<br>ensure<br>that<br>it<br>is<br>possible<br>to<br>down<br>
after<br>the<br>bottom<br>of<br>the<br>image<br>has<br>been<br>reached<br>to<br>enable<br>the<br>wheel<br>propagation<br>to<br>be<br>tested<br>
</div>
</body>
</html>

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>perfect-scrollbar example - use wheelSpeed to change speed of scrolling</title>
<link href="../src/perfect-scrollbar.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="../src/jquery.mousewheel.js"></script>
<script src="../src/perfect-scrollbar.js"></script>
<style>
.contentHolder { position:relative; margin:0px auto; padding:0px; width: 600px; height: 400px; overflow: hidden; }
.contentHolder .content { background-image: url('./azusa.jpg'); width: 1280px; height: 720px; }
.spacer { text-align:center }
</style>
<script>
jQuery(document).ready(function ($) {
"use strict";
$('#Default').perfectScrollbar();
$('#FastWheelSpeed').perfectScrollbar({wheelSpeed:100});
$('#SlowWheelSpeed').perfectScrollbar({wheelSpeed:1});
});
</script>
</head>
<body>
<h1 style="text-align:center">Default; wheelSpeed:10</h1>
<div id="Default" class="contentHolder">
<div class="content">
</div>
</div>
<h1 style="text-align:center">Fast: wheelSpeed:100</h1>
<div id="FastWheelSpeed" class="contentHolder">
<div class="content">
</div>
</div>
<h1 style="text-align:center">Slow: wheelSpeed:1</h1>
<div id="SlowWheelSpeed" class="contentHolder">
<div class="content">
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,45 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Ul-content</title>
<link href="../src/perfect-scrollbar.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="../src/jquery.mousewheel.js"></script>
<script src="../src/perfect-scrollbar.js"></script>
<style>
#description {
border: 1px solid gray;
height:150px;
width: 400px;
overflow: hidden;
position: absolute;
}
</style>
<script type="text/javascript">
$(document).ready(function ($) {
$('#description').perfectScrollbar({
wheelSpeed: 20,
wheelPropagation: false
});
});
</script>
</head>
<body>
<div id="description" class="wrapper">
<div>
<p>The command takes options applicable</p>
<p>The command takes options applicable</p>
<p>The command takes options applicable</p>
<p>The command takes options applicable</p>
<p>The command takes options applicable</p>
<p>The command takes options applicable</p>
<p>The command takes options applicable</p>
<p>The command takes options applicable</p>
<p>The command takes options applicable</p>
<p>The command takes options applicable</p>
</div>
</div>
</body>
</html>

5
min/perfect-scrollbar-0.4.1.min.css vendored Normal file
View File

@@ -0,0 +1,5 @@
/*! perfect-scrollbar - v0.4.1
* http://noraesae.github.com/perfect-scrollbar/
* Copyright (c) 2013 HyeonJe Jun; Licensed MIT */
.ps-container .ps-scrollbar-x{position:absolute;bottom:3px;height:8px;background-color:#aaa;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;opacity:0;filter:alpha(opacity=0);-o-transition:opacity .2s linear;-webkit-transition:opacity.2s linear;-moz-transition:opacity .2s linear;transition:opacity .2s linear}.ps-container.ie6 .ps-scrollbar-x{font-size:0}.ps-container:hover .ps-scrollbar-x,.ps-container.hover .ps-scrollbar-x{opacity:.6;filter:alpha(opacity=60)}.ps-container .ps-scrollbar-x:hover,.ps-container .ps-scrollbar-x.hover{opacity:.9;filter:alpha(opacity=90);cursor:default}.ps-container .ps-scrollbar-x.in-scrolling{opacity:.9;filter:alpha(opacity=90)}.ps-container .ps-scrollbar-y{position:absolute;right:3px;width:8px;background-color:#aaa;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;opacity:0;filter:alpha(opacity=0);-o-transition:opacity .2s linear;-webkit-transition:opacity.2s linear;-moz-transition:opacity .2s linear;transition:opacity .2s linear}.ps-container.ie .ps-scrollbar-y{font-size:0}.ps-container:hover .ps-scrollbar-y,.ps-container.hover .ps-scrollbar-y{opacity:.6;filter:alpha(opacity=60)}.ps-container .ps-scrollbar-y:hover,.ps-container .ps-scrollbar-y.hover{opacity:.9;filter:alpha(opacity=90);cursor:default}.ps-container .ps-scrollbar-y.in-scrolling{opacity:.9;filter:alpha(opacity=90)}

4
min/perfect-scrollbar-0.4.1.min.js vendored Normal file
View File

@@ -0,0 +1,4 @@
/*! perfect-scrollbar - v0.4.1
* http://noraesae.github.com/perfect-scrollbar/
* Copyright (c) 2013 HyeonJe Jun; Licensed MIT */
(function(e){var t={wheelSpeed:10,wheelPropagation:!1};e.fn.perfectScrollbar=function(o,r){return this.each(function(){var l=e.extend(!0,{},t);if("object"==typeof o?e.extend(!0,l,o):r=o,"update"===r)return e(this).data("perfect-scrollbar-update")&&e(this).data("perfect-scrollbar-update")(),e(this);if("destroy"===r)return e(this).data("perfect-scrollbar-destroy")&&e(this).data("perfect-scrollbar-destroy")(),e(this);if(e(this).data("perfect-scrollbar"))return e(this).data("perfect-scrollbar");var n,s,a,c,i,p,f,u,d=e(this).addClass("ps-container"),h=e("<div class='ps-scrollbar-x'></div>").appendTo(d),g=e("<div class='ps-scrollbar-y'></div>").appendTo(d),v=parseInt(h.css("bottom"),10),b=parseInt(g.css("right"),10),m=function(){var e=parseInt(u*c/s,10);d.scrollTop(e),h.css({bottom:v-e})},w=function(){var e=parseInt(p*a/n,10);d.scrollLeft(e),g.css({right:b-e})},T=function(){h.css({left:p+d.scrollLeft(),bottom:v-d.scrollTop(),width:i}),g.css({top:u+d.scrollTop(),right:b-d.scrollLeft(),height:f})},C=function(){n=d.width(),s=d.height(),a=d.prop("scrollWidth"),c=d.prop("scrollHeight"),a>n?(i=parseInt(n*n/a,10),p=parseInt(d.scrollLeft()*n/a,10)):(i=0,p=0,d.scrollLeft(0)),c>s?(f=parseInt(s*s/c,10),u=parseInt(d.scrollTop()*s/c,10)):(f=0,u=0,d.scrollTop(0)),u>=s-f&&(u=s-f),p>=n-i&&(p=n-i),T()},I=function(e,t){var o=e+t,r=n-i;p=0>o?0:o>r?r:o,h.css({left:p+d.scrollLeft()})},L=function(e,t){var o=e+t,r=s-f;u=0>o?0:o>r?r:o,g.css({top:u+d.scrollTop()})},y=function(){var t,o;h.bind("mousedown.perfect-scroll",function(e){o=e.pageX,t=h.position().left,h.addClass("in-scrolling"),e.stopPropagation(),e.preventDefault()}),e(document).bind("mousemove.perfect-scroll",function(e){h.hasClass("in-scrolling")&&(w(),I(t,e.pageX-o),e.stopPropagation(),e.preventDefault())}),e(document).bind("mouseup.perfect-scroll",function(){h.hasClass("in-scrolling")&&h.removeClass("in-scrolling")})},P=function(){var t,o;g.bind("mousedown.perfect-scroll",function(e){o=e.pageY,t=g.position().top,g.addClass("in-scrolling"),e.stopPropagation(),e.preventDefault()}),e(document).bind("mousemove.perfect-scroll",function(e){g.hasClass("in-scrolling")&&(m(),L(t,e.pageY-o),e.stopPropagation(),e.preventDefault())}),e(document).bind("mouseup.perfect-scroll",function(){g.hasClass("in-scrolling")&&g.removeClass("in-scrolling")})},D=function(){var e=function(e,t){var o=d.scrollTop();if(0===o&&t>0&&0===e)return!l.wheelPropagation;if(o>=c-s&&0>t&&0===e)return!l.wheelPropagation;var r=d.scrollLeft();return 0===r&&0>e&&0===t?!l.wheelPropagation:r>=a-n&&e>0&&0===t?!l.wheelPropagation:!0};d.bind("mousewheel.perfect-scroll",function(t,o,r,n){d.scrollTop(d.scrollTop()-n*l.wheelSpeed),d.scrollLeft(d.scrollLeft()+r*l.wheelSpeed),C(),e(r,n)&&t.preventDefault()})},X=function(){var t=function(e,t){d.scrollTop(d.scrollTop()-t),d.scrollLeft(d.scrollLeft()-e),C()},o={},r=0,l={},n=null,s=!1;e(window).bind("touchstart.perfect-scroll",function(){s=!0}),e(window).bind("touchend.perfect-scroll",function(){s=!1}),d.bind("touchstart.perfect-scroll",function(e){var t=e.originalEvent.targetTouches[0];o.pageX=t.pageX,o.pageY=t.pageY,r=(new Date).getTime(),null!==n&&clearInterval(n),e.stopPropagation()}),d.bind("touchmove.perfect-scroll",function(e){if(!s&&1===e.originalEvent.targetTouches.length){var n=e.originalEvent.targetTouches[0],a={};a.pageX=n.pageX,a.pageY=n.pageY;var c=a.pageX-o.pageX,i=a.pageY-o.pageY;t(c,i),o=a;var p=(new Date).getTime();l.x=c/(p-r),l.y=i/(p-r),r=p,e.preventDefault()}}),d.bind("touchend.perfect-scroll",function(){n=setInterval(function(){return.01>Math.abs(l.x)&&.01>Math.abs(l.y)?(clearInterval(n),void 0):(t(30*l.x,30*l.y),l.x*=.8,l.y*=.8,void 0)},10)})},Y=function(){h.remove(),g.remove(),d.unbind(".perfect-scroll"),e(window).unbind(".perfect-scroll"),d.data("perfect-scrollbar",null),d.data("perfect-scrollbar-update",null),d.data("perfect-scrollbar-destroy",null)},x=function(t){d.addClass("ie").addClass("ie"+t);var o=function(){var t=function(){e(this).addClass("hover")},o=function(){e(this).removeClass("hover")};d.bind("mouseenter.perfect-scroll",t).bind("mouseleave.perfect-scroll",o),h.bind("mouseenter.perfect-scroll",t).bind("mouseleave.perfect-scroll",o),g.bind("mouseenter.perfect-scroll",t).bind("mouseleave.perfect-scroll",o)},r=function(){T=function(){h.css({left:p+d.scrollLeft(),bottom:v,width:i}),g.css({top:u+d.scrollTop(),right:b,height:f}),h.hide().show(),g.hide().show()},m=function(){var e=parseInt(u*c/s,10);d.scrollTop(e),h.css({bottom:v}),h.hide().show()},w=function(){var e=parseInt(p*a/n,10);d.scrollLeft(e),g.hide().show()}};6===t&&(o(),r())},S=/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent),A=function(){var e=navigator.userAgent.toLowerCase().match(/(msie) ([\w.]+)/);e&&"msie"===e[1]&&x(parseInt(e[2],10)),C(),y(),P(),S&&X(),d.mousewheel&&D(),d.data("perfect-scrollbar",d),d.data("perfect-scrollbar-update",C),d.data("perfect-scrollbar-destroy",Y)};return A(),d})}})(jQuery);

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
.ps-container .ps-scrollbar-x{position:absolute;bottom:3px;height:8px;background-color:#aaa;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity.2s linear;-moz-transition:opacity .2s linear;transition:opacity .2s linear}.ps-container:hover .ps-scrollbar-x{opacity:.6;filter:alpha(opacity=60)}.ps-container .ps-scrollbar-x:hover{opacity:.9;filter:alpha(opacity=90);cursor:default}.ps-container .ps-scrollbar-x.in-scrolling{opacity:.9;filter:alpha(opacity=90)}.ps-container .ps-scrollbar-y{position:absolute;right:3px;width:8px;background-color:#aaa;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;opacity:0;-webkit-transition:opacity.2s linear;-moz-transition:opacity .2s linear;transition:opacity .2s linear}.ps-container:hover .ps-scrollbar-y{opacity:.6;filter:alpha(opacity=60)}.ps-container .ps-scrollbar-y:hover{opacity:.9;filter:alpha(opacity=90);cursor:default}.ps-container .ps-scrollbar-y.in-scrolling{opacity:.9;filter:alpha(opacity=90)}

View File

@@ -1,3 +0,0 @@
/* Copyright (c) 2012 HyeonJe Jun (http://github.com/noraesae)
* Licensed under the MIT License
*/(function(e){e.fn.perfectScrollbar=function(t){if(t==="update")return e(this).data("perfect_scrollbar_update")&&e(this).data("perfect_scrollbar_update")(),e(this);if(t==="destroy")return e(this).data("perfect_scrollbar_destroy")&&e(this).data("perfect_scrollbar_destroy")(),e(this);if(e(this).data("perfect_scrollbar"))return e(this).data("perfect_scrollbar");var n=e(this).addClass("ps-container"),r=e(this).children(),i=e("<div class='ps-scrollbar-x'></div>").appendTo(n),s=e("<div class='ps-scrollbar-y'></div>").appendTo(n),o,u,a,f,l,c,h=parseInt(i.css("bottom")),p,d,v=parseInt(s.css("right")),m=function(){var e=parseInt(d*f/u);n.scrollTop(e),i.css({bottom:h-e})},g=function(){var e=parseInt(c*a/o);n.scrollLeft(e),s.css({right:v-e})},y=function(){o=n.width(),u=n.height(),a=r.width(),f=r.height(),o<a?(l=parseInt(o*o/a),c=parseInt(n.scrollLeft()*o/a)):(l=0,c=0),u<f?(p=parseInt(u*u/f),d=parseInt(n.scrollTop()*u/f)):(p=0,scrollbar_y_left=0),i.css({left:c+n.scrollLeft(),bottom:h-n.scrollTop(),width:l}),s.css({top:d+n.scrollTop(),right:v-n.scrollLeft(),height:p})},b=function(e,t){var r=e+t,s=o-l;r<0?c=0:r>s?c=s:c=r,i.css({left:c+n.scrollLeft()})},w=function(e,t){var r=e+t,i=u-p;r<0?d=0:r>i?d=i:d=r,s.css({top:d+n.scrollTop()})},E=function(){var t,n;i.bind("mousedown.perfect-scroll",function(e){n=e.pageX,t=i.position().left,i.addClass("in-scrolling"),e.stopPropagation(),e.preventDefault()}),e(window).bind("mousemove.perfect-scroll",function(e){i.hasClass("in-scrolling")&&(b(t,e.pageX-n),g(),e.stopPropagation(),e.preventDefault())}),e(window).bind("mouseup.perfect-scroll",function(e){i.hasClass("in-scrolling")&&i.removeClass("in-scrolling")})},S=function(){var t,n;s.bind("mousedown.perfect-scroll",function(e){n=e.pageY,t=s.position().top,s.addClass("in-scrolling"),e.stopPropagation(),e.preventDefault()}),e(window).bind("mousemove.perfect-scroll",function(e){s.hasClass("in-scrolling")&&(w(t,e.pageY-n),m(),e.stopPropagation(),e.preventDefault())}),e(window).bind("mouseup.perfect-scroll",function(e){s.hasClass("in-scrolling")&&s.removeClass("in-scrolling")})},x=function(){n.mousewheel(function(e,t,r,i){n.scrollTop(n.scrollTop()-i*10),n.scrollLeft(n.scrollLeft()+r*10),y(),(f>u||a>o)&&e.preventDefault()})},T=function(){i.remove(),s.remove(),n.unbind("mousewheel"),e(window).unbind("mousemove.perfect-scroll"),e(window).unbind("mouseup.perfect-scroll"),n.data("perfect_scrollbar",null),n.data("perfect_scrollbar_update",null),n.data("perfect_scrollbar_destroy",null)},N=function(){y(),E(),S(),n.mousewheel&&x(),n.data("perfect_scrollbar",n),n.data("perfect_scrollbar_update",y),n.data("perfect_scrollbar_destroy",T)};return N(),n}})(jQuery);

15
package.json Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "perfect-scrollbar",
"version": "0.4.1",
"engines": {
"node": ">= 0.8.0"
},
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.1.1",
"grunt-contrib-uglify": "~0.1.1",
"grunt-contrib-cssmin": "~0.6.1",
"grunt-contrib-csslint": "~0.1.2",
"grunt-contrib-clean": "~0.4.1"
}
}

View File

@@ -0,0 +1,37 @@
{
"name": "perfect-scrollbar",
"title": "perfect-scrollbar",
"description": "Tiny but perfect jquery scrollbar plugin.",
"version": "0.4.1",
"author": {
"name": "HyeonJe Jun",
"email": "noraesae@yuiazu.net",
"url": "https://github.com/noraesae/"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/noraesae/perfect-scrollbar#license"
}
],
"dependencies": {
"jquery": ">=1.8"
},
"keywords": [
"ui",
"scroll",
"scrollbar"
],
"homepage": "http://noraesae.github.com/perfect-scrollbar/",
"docs": "https://github.com/noraesae/perfect-scrollbar/",
"download": "http://noraesae.github.com/perfect-scrollbar/",
"demo": "http://noraesae.github.com/perfect-scrollbar/",
"bugs": "https://github.com/noraesae/perfect-scrollbar/issues/",
"maintainers": [
{
"name": "HyeonJe Jun",
"email": "noraesae@yuiazu.net",
"url": "https://github.com/noraesae/"
}
]
}

84
src/jquery.mousewheel.js Normal file
View File

@@ -0,0 +1,84 @@
/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
* Licensed under the MIT License (LICENSE.txt).
*
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
* Thanks to: Seamus Leahy for adding deltaX and deltaY
*
* Version: 3.0.6
*
* Requires: 1.2.2+
*/
(function($) {
var types = ['DOMMouseScroll', 'mousewheel'];
if ($.event.fixHooks) {
for ( var i=types.length; i; ) {
$.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
}
}
$.event.special.mousewheel = {
setup: function() {
if ( this.addEventListener ) {
for ( var i=types.length; i; ) {
this.addEventListener( types[--i], handler, false );
}
} else {
this.onmousewheel = handler;
}
},
teardown: function() {
if ( this.removeEventListener ) {
for ( var i=types.length; i; ) {
this.removeEventListener( types[--i], handler, false );
}
} else {
this.onmousewheel = null;
}
}
};
$.fn.extend({
mousewheel: function(fn) {
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
},
unmousewheel: function(fn) {
return this.unbind("mousewheel", fn);
}
});
function handler(event) {
var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
event = $.event.fix(orgEvent);
event.type = "mousewheel";
// Old school scrollwheel delta
if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }
if ( orgEvent.detail ) { delta = -orgEvent.detail/3; }
// New school multidimensional scroll (touchpads) deltas
deltaY = delta;
// Gecko
if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
deltaY = 0;
deltaX = -1*delta;
}
// Webkit
if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
// Add event and delta to the front of the arguments
args.unshift(event, delta, deltaX, deltaY);
return ($.event.dispatch || $.event.handle).apply(this, args);
}
})(jQuery);

View File

@@ -3,22 +3,29 @@
bottom: 3px; /* there must be 'bottom' for ps-scrollbar-x */
height: 8px;
background-color: #aaa;
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
opacity: 0;
filter: alpha(opacity = 0);
-o-transition: opacity .2s linear;
-webkit-transition: opacity.2s linear;
-moz-transition: opacity .2s linear;
transition: opacity .2s linear;
}
.ps-container:hover .ps-scrollbar-x {
.ps-container.ie6 .ps-scrollbar-x {
font-size: 0; /* fixed scrollbar height in xp sp3 ie6 */
}
.ps-container:hover .ps-scrollbar-x,
.ps-container.hover .ps-scrollbar-x {
opacity: 0.6;
filter: alpha(opacity = 60);
}
.ps-container .ps-scrollbar-x:hover {
.ps-container .ps-scrollbar-x:hover,
.ps-container .ps-scrollbar-x.hover {
opacity: 0.9;
filter: alpha(opacity = 90);
cursor:default;
@@ -34,21 +41,29 @@
right: 3px; /* there must be 'right' for ps-scrollbar-y */
width: 8px;
background-color: #aaa;
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
opacity: 0;
filter: alpha(opacity = 0);
-o-transition: opacity .2s linear;
-webkit-transition: opacity.2s linear;
-moz-transition: opacity .2s linear;
transition: opacity .2s linear;
}
.ps-container:hover .ps-scrollbar-y {
.ps-container.ie .ps-scrollbar-y {
font-size: 0; /* fixed scrollbar height in xp sp3 ie6 */
}
.ps-container:hover .ps-scrollbar-y,
.ps-container.hover .ps-scrollbar-y {
opacity: 0.6;
filter: alpha(opacity = 60);
}
.ps-container .ps-scrollbar-y:hover {
.ps-container .ps-scrollbar-y:hover,
.ps-container .ps-scrollbar-y.hover {
opacity: 0.9;
filter: alpha(opacity = 90);
cursor: default;

View File

@@ -1,206 +1,384 @@
/* Copyright (c) 2012 HyeonJe Jun (http://github.com/noraesae)
* Licensed under the MIT License
*/
((function($) {
$.fn.perfectScrollbar = function(option) {
if(option === 'update') {
if($(this).data('perfect_scrollbar_update')) {
$(this).data('perfect_scrollbar_update')();
}
return $(this);
((function ($) {
// The default settings for the plugin
var defaultSettings = {
wheelSpeed: 10,
wheelPropagation: false
};
$.fn.perfectScrollbar = function (suppliedSettings, option) {
return this.each(function () {
// Use the default settings
var settings = $.extend(true, {}, defaultSettings);
if (typeof suppliedSettings === "object") {
// But over-ride any supplied
$.extend(true, settings, suppliedSettings);
} else {
// If no settings were supplied, then the first param must be the option
option = suppliedSettings;
}
if (option === 'update') {
if ($(this).data('perfect-scrollbar-update')) {
$(this).data('perfect-scrollbar-update')();
}
else if(option === 'destroy') {
if($(this).data('perfect_scrollbar_destroy')) {
$(this).data('perfect_scrollbar_destroy')();
}
return $(this);
return $(this);
}
else if (option === 'destroy') {
if ($(this).data('perfect-scrollbar-destroy')) {
$(this).data('perfect-scrollbar-destroy')();
}
return $(this);
}
if ($(this).data('perfect-scrollbar')) {
// if there's already perfect-scrollbar
return $(this).data('perfect-scrollbar');
}
var $this = $(this).addClass('ps-container'),
$scrollbarX = $("<div class='ps-scrollbar-x'></div>").appendTo($this),
$scrollbarY = $("<div class='ps-scrollbar-y'></div>").appendTo($this),
containerWidth,
containerHeight,
contentWidth,
contentHeight,
scrollbarXWidth,
scrollbarXLeft,
scrollbarXBottom = parseInt($scrollbarX.css('bottom'), 10),
scrollbarYHeight,
scrollbarYTop,
scrollbarYRight = parseInt($scrollbarY.css('right'), 10);
var updateContentScrollTop = function () {
var scrollTop = parseInt(scrollbarYTop * contentHeight / containerHeight, 10);
$this.scrollTop(scrollTop);
$scrollbarX.css({bottom: scrollbarXBottom - scrollTop});
};
var updateContentScrollLeft = function () {
var scrollLeft = parseInt(scrollbarXLeft * contentWidth / containerWidth, 10);
$this.scrollLeft(scrollLeft);
$scrollbarY.css({right: scrollbarYRight - scrollLeft});
};
var updateScrollbarCss = function () {
$scrollbarX.css({left: scrollbarXLeft + $this.scrollLeft(), bottom: scrollbarXBottom - $this.scrollTop(), width: scrollbarXWidth});
$scrollbarY.css({top: scrollbarYTop + $this.scrollTop(), right: scrollbarYRight - $this.scrollLeft(), height: scrollbarYHeight});
};
var updateBarSizeAndPosition = function () {
containerWidth = $this.width();
containerHeight = $this.height();
contentWidth = $this.prop('scrollWidth');
contentHeight = $this.prop('scrollHeight');
if (containerWidth < contentWidth) {
scrollbarXWidth = parseInt(containerWidth * containerWidth / contentWidth, 10);
scrollbarXLeft = parseInt($this.scrollLeft() * containerWidth / contentWidth, 10);
}
else {
scrollbarXWidth = 0;
scrollbarXLeft = 0;
$this.scrollLeft(0);
}
if (containerHeight < contentHeight) {
scrollbarYHeight = parseInt(containerHeight * containerHeight / contentHeight, 10);
scrollbarYTop = parseInt($this.scrollTop() * containerHeight / contentHeight, 10);
}
else {
scrollbarYHeight = 0;
scrollbarYTop = 0;
$this.scrollTop(0);
}
if($(this).data('perfect_scrollbar')) {
// if there's already perfect_scrollbar
return $(this).data('perfect_scrollbar');
if (scrollbarYTop >= containerHeight - scrollbarYHeight) {
scrollbarYTop = containerHeight - scrollbarYHeight;
}
if (scrollbarXLeft >= containerWidth - scrollbarXWidth) {
scrollbarXLeft = containerWidth - scrollbarXWidth;
}
var $this = $(this).addClass('ps-container'),
$content = $(this).children(),
$scrollbar_x = $("<div class='ps-scrollbar-x'></div>").appendTo($this),
$scrollbar_y = $("<div class='ps-scrollbar-y'></div>").appendTo($this),
container_width,
container_height,
content_width,
content_height,
scrollbar_x_width,
scrollbar_x_left,
scrollbar_x_bottom = parseInt($scrollbar_x.css('bottom')),
scrollbar_y_height,
scrollbar_y_top,
scrollbar_y_right = parseInt($scrollbar_y.css('right'));
updateScrollbarCss();
};
var updateContentScrollTop = function() {
var scroll_top = parseInt(scrollbar_y_top * content_height / container_height);
$this.scrollTop(scroll_top);
$scrollbar_x.css({bottom: scrollbar_x_bottom - scroll_top});
var moveBarX = function (currentLeft, deltaX) {
var newLeft = currentLeft + deltaX,
maxLeft = containerWidth - scrollbarXWidth;
if (newLeft < 0) {
scrollbarXLeft = 0;
}
else if (newLeft > maxLeft) {
scrollbarXLeft = maxLeft;
}
else {
scrollbarXLeft = newLeft;
}
$scrollbarX.css({left: scrollbarXLeft + $this.scrollLeft()});
};
var moveBarY = function (currentTop, deltaY) {
var newTop = currentTop + deltaY,
maxTop = containerHeight - scrollbarYHeight;
if (newTop < 0) {
scrollbarYTop = 0;
}
else if (newTop > maxTop) {
scrollbarYTop = maxTop;
}
else {
scrollbarYTop = newTop;
}
$scrollbarY.css({top: scrollbarYTop + $this.scrollTop()});
};
var bindMouseScrollXHandler = function () {
var currentLeft,
currentPageX;
$scrollbarX.bind('mousedown.perfect-scroll', function (e) {
currentPageX = e.pageX;
currentLeft = $scrollbarX.position().left;
$scrollbarX.addClass('in-scrolling');
e.stopPropagation();
e.preventDefault();
});
$(document).bind('mousemove.perfect-scroll', function (e) {
if ($scrollbarX.hasClass('in-scrolling')) {
updateContentScrollLeft();
moveBarX(currentLeft, e.pageX - currentPageX);
e.stopPropagation();
e.preventDefault();
}
});
$(document).bind('mouseup.perfect-scroll', function (e) {
if ($scrollbarX.hasClass('in-scrolling')) {
$scrollbarX.removeClass('in-scrolling');
}
});
};
var bindMouseScrollYHandler = function () {
var currentTop,
currentPageY;
$scrollbarY.bind('mousedown.perfect-scroll', function (e) {
currentPageY = e.pageY;
currentTop = $scrollbarY.position().top;
$scrollbarY.addClass('in-scrolling');
e.stopPropagation();
e.preventDefault();
});
$(document).bind('mousemove.perfect-scroll', function (e) {
if ($scrollbarY.hasClass('in-scrolling')) {
updateContentScrollTop();
moveBarY(currentTop, e.pageY - currentPageY);
e.stopPropagation();
e.preventDefault();
}
});
$(document).bind('mouseup.perfect-scroll', function (e) {
if ($scrollbarY.hasClass('in-scrolling')) {
$scrollbarY.removeClass('in-scrolling');
}
});
};
// bind handlers
var bindMouseWheelHandler = function () {
var shouldPreventDefault = function (deltaX, deltaY) {
var scrollTop = $this.scrollTop();
if (scrollTop === 0 && deltaY > 0 && deltaX === 0) {
return !settings.wheelPropagation;
}
else if (scrollTop >= contentHeight - containerHeight && deltaY < 0 && deltaX === 0) {
return !settings.wheelPropagation;
}
var scrollLeft = $this.scrollLeft();
if (scrollLeft === 0 && deltaX < 0 && deltaY === 0) {
return !settings.wheelPropagation;
}
else if (scrollLeft >= contentWidth - containerWidth && deltaX > 0 && deltaY === 0) {
return !settings.wheelPropagation;
}
return true;
};
var updateContentScrollLeft = function() {
var scroll_left = parseInt(scrollbar_x_left * content_width / container_width);
$this.scrollLeft(scroll_left);
$scrollbar_y.css({right: scrollbar_y_right - scroll_left});
$this.bind('mousewheel.perfect-scroll', function (e, delta, deltaX, deltaY) {
$this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));
$this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));
// update bar position
updateBarSizeAndPosition();
if (shouldPreventDefault(deltaX, deltaY)) {
e.preventDefault();
}
});
};
// bind mobile touch handler
var bindMobileTouchHandler = function () {
var applyTouchMove = function (differenceX, differenceY) {
$this.scrollTop($this.scrollTop() - differenceY);
$this.scrollLeft($this.scrollLeft() - differenceX);
// update bar position
updateBarSizeAndPosition();
};
var updateBarSizeAndPosition = function() {
container_width = $this.width();
container_height = $this.height();
content_width = $content.width();
content_height = $content.height();
if(container_width < content_width) {
scrollbar_x_width = parseInt(container_width * container_width / content_width);
scrollbar_x_left = parseInt($this.scrollLeft() * container_width / content_width);
}
else {
scrollbar_x_width = 0;
scrollbar_x_left = 0;
}
if(container_height < content_height) {
scrollbar_y_height = parseInt(container_height * container_height / content_height);
scrollbar_y_top = parseInt($this.scrollTop() * container_height / content_height);
}
else {
scrollbar_y_height = 0;
scrollbar_y_left = 0;
var startCoords = {},
startTime = 0,
speed = {},
breakingProcess = null,
inGlobalTouch = false;
$(window).bind("touchstart.perfect-scroll", function (e) {
inGlobalTouch = true;
});
$(window).bind("touchend.perfect-scroll", function (e) {
inGlobalTouch = false;
});
$this.bind("touchstart.perfect-scroll", function (e) {
var touch = e.originalEvent.targetTouches[0];
startCoords.pageX = touch.pageX;
startCoords.pageY = touch.pageY;
startTime = (new Date()).getTime();
if (breakingProcess !== null) {
clearInterval(breakingProcess);
}
e.stopPropagation();
});
$this.bind("touchmove.perfect-scroll", function (e) {
if (!inGlobalTouch && e.originalEvent.targetTouches.length === 1) {
var touch = e.originalEvent.targetTouches[0];
var currentCoords = {};
currentCoords.pageX = touch.pageX;
currentCoords.pageY = touch.pageY;
var differenceX = currentCoords.pageX - startCoords.pageX,
differenceY = currentCoords.pageY - startCoords.pageY;
applyTouchMove(differenceX, differenceY);
startCoords = currentCoords;
var currentTime = (new Date()).getTime();
speed.x = differenceX / (currentTime - startTime);
speed.y = differenceY / (currentTime - startTime);
startTime = currentTime;
e.preventDefault();
}
});
$this.bind("touchend.perfect-scroll", function (e) {
breakingProcess = setInterval(function () {
if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
clearInterval(breakingProcess);
return;
}
$scrollbar_x.css({left: scrollbar_x_left + $this.scrollLeft(), bottom: scrollbar_x_bottom - $this.scrollTop(), width: scrollbar_x_width});
$scrollbar_y.css({top: scrollbar_y_top + $this.scrollTop(), right: scrollbar_y_right - $this.scrollLeft(), height: scrollbar_y_height});
applyTouchMove(speed.x * 30, speed.y * 30);
speed.x *= 0.8;
speed.y *= 0.8;
}, 10);
});
};
var destroy = function () {
$scrollbarX.remove();
$scrollbarY.remove();
$this.unbind('.perfect-scroll');
$(window).unbind('.perfect-scroll');
$this.data('perfect-scrollbar', null);
$this.data('perfect-scrollbar-update', null);
$this.data('perfect-scrollbar-destroy', null);
};
var ieSupport = function (version) {
$this.addClass('ie').addClass('ie' + version);
var bindHoverHandlers = function () {
var mouseenter = function () {
$(this).addClass('hover');
};
var mouseleave = function () {
$(this).removeClass('hover');
};
$this.bind('mouseenter.perfect-scroll', mouseenter).bind('mouseleave.perfect-scroll', mouseleave);
$scrollbarX.bind('mouseenter.perfect-scroll', mouseenter).bind('mouseleave.perfect-scroll', mouseleave);
$scrollbarY.bind('mouseenter.perfect-scroll', mouseenter).bind('mouseleave.perfect-scroll', mouseleave);
};
var moveBarX = function(current_left, delta_x) {
var new_left = current_left + delta_x,
max_left = container_width - scrollbar_x_width;
var fixIe6ScrollbarPosition = function () {
updateScrollbarCss = function () {
$scrollbarX.css({left: scrollbarXLeft + $this.scrollLeft(), bottom: scrollbarXBottom, width: scrollbarXWidth});
$scrollbarY.css({top: scrollbarYTop + $this.scrollTop(), right: scrollbarYRight, height: scrollbarYHeight});
$scrollbarX.hide().show();
$scrollbarY.hide().show();
};
updateContentScrollTop = function () {
var scrollTop = parseInt(scrollbarYTop * contentHeight / containerHeight, 10);
$this.scrollTop(scrollTop);
$scrollbarX.css({bottom: scrollbarXBottom});
$scrollbarX.hide().show();
};
updateContentScrollLeft = function () {
var scrollLeft = parseInt(scrollbarXLeft * contentWidth / containerWidth, 10);
$this.scrollLeft(scrollLeft);
$scrollbarY.hide().show();
};
};
if(new_left < 0) {
scrollbar_x_left = 0;
}
else if(new_left > max_left) {
scrollbar_x_left = max_left;
}
else {
scrollbar_x_left = new_left;
}
$scrollbar_x.css({left: scrollbar_x_left + $this.scrollLeft()});
if (version === 6) {
bindHoverHandlers();
fixIe6ScrollbarPosition();
}
};
var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
var initialize = function () {
var ieMatch = navigator.userAgent.toLowerCase().match(/(msie) ([\w.]+)/);
if (ieMatch && ieMatch[1] === 'msie') {
// must be executed at first, because 'ieSupport' may addClass to the container
ieSupport(parseInt(ieMatch[2], 10));
}
var moveBarY = function(current_top, delta_y) {
var new_top = current_top + delta_y,
max_top = container_height - scrollbar_y_height;
updateBarSizeAndPosition();
bindMouseScrollXHandler();
bindMouseScrollYHandler();
if (isMobile) {
bindMobileTouchHandler();
}
if ($this.mousewheel) {
bindMouseWheelHandler();
}
$this.data('perfect-scrollbar', $this);
$this.data('perfect-scrollbar-update', updateBarSizeAndPosition);
$this.data('perfect-scrollbar-destroy', destroy);
};
if(new_top < 0) {
scrollbar_y_top = 0;
}
else if(new_top > max_top) {
scrollbar_y_top = max_top;
}
else {
scrollbar_y_top = new_top;
}
$scrollbar_y.css({top: scrollbar_y_top + $this.scrollTop()});
};
// initialize
initialize();
var bindMouseScrollXHandler = function() {
var current_left,
current_page_x;
$scrollbar_x.bind('mousedown.perfect-scroll', function(e) {
current_page_x = e.pageX;
current_left = $scrollbar_x.position().left;
$scrollbar_x.addClass('in-scrolling');
e.stopPropagation();
e.preventDefault();
});
$(window).bind('mousemove.perfect-scroll', function(e) {
if($scrollbar_x.hasClass('in-scrolling')) {
moveBarX(current_left, e.pageX - current_page_x);
updateContentScrollLeft();
e.stopPropagation();
e.preventDefault();
}
});
$(window).bind('mouseup.perfect-scroll', function(e) {
if($scrollbar_x.hasClass('in-scrolling')) {
$scrollbar_x.removeClass('in-scrolling');
}
});
};
var bindMouseScrollYHandler = function() {
var current_top,
current_page_y;
$scrollbar_y.bind('mousedown.perfect-scroll', function(e) {
current_page_y = e.pageY;
current_top = $scrollbar_y.position().top;
$scrollbar_y.addClass('in-scrolling');
e.stopPropagation();
e.preventDefault();
});
$(window).bind('mousemove.perfect-scroll', function(e) {
if($scrollbar_y.hasClass('in-scrolling')) {
moveBarY(current_top, e.pageY - current_page_y);
updateContentScrollTop();
e.stopPropagation();
e.preventDefault();
}
});
$(window).bind('mouseup.perfect-scroll', function(e) {
if($scrollbar_y.hasClass('in-scrolling')) {
$scrollbar_y.removeClass('in-scrolling');
}
});
};
// bind handlers
var bindMouseWheelHandler = function() {
$this.mousewheel(function(e, delta, deltaX, deltaY) {
$this.scrollTop($this.scrollTop() - (deltaY * 10));
$this.scrollLeft($this.scrollLeft() + (deltaX * 10));
// update bar position
updateBarSizeAndPosition();
if(content_height > container_height || content_width > container_width) {
e.preventDefault();
}
});
};
var destroy = function() {
$scrollbar_x.remove();
$scrollbar_y.remove();
$this.unbind('mousewheel');
$(window).unbind('mousemove.perfect-scroll');
$(window).unbind('mouseup.perfect-scroll');
$this.data('perfect_scrollbar', null);
$this.data('perfect_scrollbar_update', null);
$this.data('perfect_scrollbar_destroy', null);
};
var initialize = function() {
updateBarSizeAndPosition();
bindMouseScrollXHandler();
bindMouseScrollYHandler();
if($this.mousewheel) bindMouseWheelHandler();
$this.data('perfect_scrollbar', $this);
$this.data('perfect_scrollbar_update', updateBarSizeAndPosition);
$this.data('perfect_scrollbar_destroy', destroy);
};
// initialize
initialize();
return $this;
};
return $this;
});
};
})(jQuery));