Improve scrolls behaviour

Migrate to nanoscroller 0.8.0
Fixed history scrollbar. Closes #341
Fixed mobile view infinite scroll. Closes #353
This commit is contained in:
Igor Zhukov 2014-06-30 17:30:42 +04:00
parent bafab6e250
commit afc066e3bc
11 changed files with 293 additions and 263 deletions

View File

@ -804,7 +804,7 @@ a.tg_radio_on:hover i.icon-radio {
}
.im_dialogs_col .nano > .pane {
.im_dialogs_col .nano > .nano-pane {
background : rgba(0,0,0,0.0);
width : 12px;
right: 0px;
@ -820,7 +820,7 @@ a.tg_radio_on:hover i.icon-radio {
-o-transition : none;
transition : none;
}
.im_dialogs_col .nano > .pane > .slider {
.im_dialogs_col .nano > .nano-pane > .nano-slider {
background: #A5B1B9;
margin: 0 5px;
-moz-border-radius : 0;
@ -1076,9 +1076,9 @@ a.im_dialog_selected .im_dialog_date {
.im_history_col {
}
.im_history_col .nano > .pane,
.contacts_modal_col .nano > .pane,
.im_dialogs_modal_col .nano > .pane {
.im_history_col .nano > .nano-pane,
.contacts_modal_col .nano > .nano-pane,
.im_dialogs_modal_col .nano > .nano-pane {
background : rgba(3,36,64,0.08);
width : 9px;
right: 0;
@ -1097,12 +1097,12 @@ a.im_dialog_selected .im_dialog_date {
transition : none;
}
.contacts_modal_col .nano > .pane {
.contacts_modal_col .nano > .nano-pane {
width: 6px;
right: 7px;
}
.im_dialogs_modal_col .nano > .pane {
.im_dialogs_modal_col .nano > .nano-pane {
width: 6px;
right: 2px;
}
@ -1110,13 +1110,13 @@ a.im_dialog_selected .im_dialog_date {
padding: 0 12px 0 12px;
}
.im_history_col .nano > .pane {
.im_history_col .nano > .nano-pane {
top: 10px;
right: 8px;
}
.im_history_col .nano > .pane > .slider,
.contacts_modal_col .nano > .pane > .slider,
.im_dialogs_modal_col .nano > .pane > .slider {
.im_history_col .nano > .nano-pane > .nano-slider,
.contacts_modal_col .nano > .nano-pane > .nano-slider,
.im_dialogs_modal_col .nano > .nano-pane > .nano-slider {
background : rgba(3,46,79,0.22);
margin: 0;
-moz-border-radius : 2px;
@ -1219,7 +1219,7 @@ a.im_dialog_selected .im_dialog_date {
.im_history_wrap {
overflow: hidden;
/*overflow: hidden;*/
/*overflow-y: scroll;*/
}
.im_history_scrollable_wrap {
@ -1251,11 +1251,13 @@ a.im_dialog_selected .im_dialog_date {
}
.im_history_typing_wrap {
margin-top: 13px;
height: 18px;
/*margin-top: 13px;*/
/*height: 18px;*/
line-height: 18px;
width: 100%;
margin-bottom: 13px;
height: 49px;
/*margin-bottom: 13px;*/
padding: 13px 0 18px;
overflow: hidden;
-webkit-user-select: none;
}
@ -2447,11 +2449,11 @@ img.chat_modal_participant_photo {
}
.emoji-menu .nano > .pane {
.emoji-menu .nano > .nano-pane {
background : rgba(255,255,255,0.0);
right: -2px;
}
.emoji-menu .nano > .pane > .slider {
.emoji-menu .nano > .nano-pane > .nano-slider {
background: #d1d1d1;
margin: 0 3px 0 4px;
}
@ -3261,7 +3263,7 @@ ce671b orange
padding: 14px 0;
}
.countries_modal_col .nano > .pane {
.countries_modal_col .nano > .nano-pane {
background : rgba(3,36,64,0.08);
width : 3px;
right: 6px;
@ -3274,7 +3276,7 @@ ce671b orange
-webkit-border-radius : 0;
border-radius : 0;
}
.countries_modal_col .nano > .pane > .slider {
.countries_modal_col .nano > .nano-pane > .nano-slider {
background : rgba(3,46,79,0.22);
margin: 0;
-moz-border-radius : 0;

View File

@ -135,7 +135,9 @@ html {
font-size: 14px;
color: #FFF;
white-space: nowrap;
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
margin: 0;
}
.navbar-quick-media-back h4 {
@ -268,14 +270,14 @@ html {
margin: 0 5px;
padding-bottom: 18px;
}
.im_history_col .nano > .pane {
.im_history_col .nano > .nano-pane {
top: 3px;
right: 3px;
width: 6px;
}
.im_history_col .nano > .pane > .slider,
.contacts_modal_col .nano > .pane > .slider,
.im_dialogs_modal_col .nano > .pane > .slider {
.im_history_col .nano > .nano-pane > .nano-slider,
.contacts_modal_col .nano > .nano-pane > .nano-slider,
.im_dialogs_modal_col .nano > .nano-pane > .nano-slider {
background : rgba(3,46,79,0.22);
border-radius: 3px;
margin: 0;
@ -305,11 +307,11 @@ html {
.im_dialogs_col {
margin-right: 0;
}
.im_page_peer_not_selected .im_dialogs_col_wrap .pane {
.im_page_peer_not_selected .im_dialogs_col_wrap .nano-pane {
width: 6px;
right: 3px;
}
.im_page_peer_not_selected .im_dialogs_col_wrap .pane > .slider {
.im_page_peer_not_selected .im_dialogs_col_wrap .nano-pane > .nano-slider {
background : rgba(3,46,79,0.22);
border-radius: 3px;
margin: 0;

View File

@ -254,6 +254,7 @@ angular.module('myApp.directives', ['myApp.filters'])
});
$(scrollableWrap).on('scroll', function (e) {
if (!element.is(':visible')) return;
// console.log('scroll', moreNotified);
if (!moreNotified && scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight - 300) {
// console.log('emit need more');
@ -421,13 +422,16 @@ angular.module('myApp.directives', ['myApp.filters'])
if (!atBottom && !options.my) {
return;
}
var curAnimated = animated && !$rootScope.idle.isIDLE,
var curAnimated = animated &&
!$rootScope.idle.isIDLE &&
historyMessagesEl.clientHeight > 0,
wasH;
if (!curAnimated) {
if (curAnimated) {
wasH = scrollableWrap.scrollHeight;
} else {
$(scrollable).css({bottom: 0});
$(scrollableWrap).addClass('im_history_to_bottom');
} else {
wasH = scrollableWrap.scrollHeight;
}
onContentLoaded(function () {
@ -450,7 +454,6 @@ angular.module('myApp.directives', ['myApp.filters'])
$(scrollable).css({bottom: ''});
scrollableWrap.scrollTop = scrollableWrap.scrollHeight;
updateBottomizer();
$(historyWrap).nanoScroller();
}
});
});
@ -501,15 +504,16 @@ angular.module('myApp.directives', ['myApp.filters'])
$scope.$on('ui_history_prepend', function () {
var sh = scrollableWrap.scrollHeight,
st = scrollableWrap.scrollTop,
pr = parseInt($(scrollableWrap).css('paddingRight')),
ch = scrollableWrap.clientHeight;
$(scrollableWrap).addClass('im_history_to_bottom');
scrollableWrap.scrollHeight; // Some strange Chrome bug workaround
$(scrollable).css({bottom: -(sh - st - ch)});
$(scrollable).css({bottom: -(sh - st - ch), marginLeft: -Math.ceil(pr / 2)});
onContentLoaded(function () {
$(scrollableWrap).removeClass('im_history_to_bottom');
$(scrollable).css({bottom: ''});
$(scrollable).css({bottom: '', marginLeft: ''});
scrollableWrap.scrollTop = st + scrollableWrap.scrollHeight - sh;
updateBottomizer();
@ -569,10 +573,9 @@ angular.module('myApp.directives', ['myApp.filters'])
var atBottom = true;
$(scrollableWrap).on('scroll', function (e) {
if ($(scrollableWrap).hasClass('im_history_to_bottom')) {
return cancelEvent(e);
}
if (curAnimation) {
if (!element.is(':visible') ||
$(scrollableWrap).hasClass('im_history_to_bottom') ||
curAnimation) {
return;
}
atBottom = scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight;
@ -607,9 +610,6 @@ angular.module('myApp.directives', ['myApp.filters'])
$(historyWrap).css({
height: historyH
});
$(historyEl).css({
minHeight: historyH - 44
});
updateBottomizer();
@ -626,8 +626,9 @@ angular.module('myApp.directives', ['myApp.filters'])
function updateBottomizer () {
$(historyMessagesEl).css({marginTop: 0});
if (historyMessagesEl.offsetHeight > 0 && historyMessagesEl.offsetHeight <= scrollableWrap.offsetHeight) {
$(historyMessagesEl).css({marginTop: (scrollableWrap.offsetHeight - historyMessagesEl.offsetHeight - 20 - 44) + 'px'});
var marginTop = scrollableWrap.offsetHeight - historyMessagesEl.offsetHeight - 20 - 49;
if (historyMessagesEl.offsetHeight > 0 && marginTop > 0) {
$(historyMessagesEl).css({marginTop: marginTop});
}
$(historyWrap).nanoScroller();
}
@ -741,7 +742,8 @@ angular.module('myApp.directives', ['myApp.filters'])
lastLength;
$(editorElement).on('keyup', function (e) {
var now = tsNow(),
length = (editorElement[richTextarea ? 'innerText' : 'value']).length;
length = (editorElement[richTextarea ? 'textContent' : 'value']).length;
if (now - lastTyping > 5000 && length != lastLength) {
lastTyping = now;
@ -1405,6 +1407,7 @@ angular.module('myApp.directives', ['myApp.filters'])
moreNotified = false;
$(scrollableWrap).on('scroll', function (e) {
if (!element.is(':visible')) return;
if (!moreNotified &&
scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight - 300) {
moreNotified = true;

View File

@ -15,7 +15,7 @@
<div my-contacts-list class="contacts_modal_col">
<div class="contacts_wrap nano" my-infinite-scroller>
<div class="contacts_scrollable_wrap content">
<div class="contacts_scrollable_wrap nano-content">
<ul class="contacts_modal_members_list nav nav-pills nav-stacked">

View File

@ -12,7 +12,7 @@
<div class="countries_modal_col" my-countries-list>
<div class="countries_wrap nano" my-infinite-scroller>
<div class="countries_scrollable_wrap content">
<div class="countries_scrollable_wrap nano-content">
<ul class="countries_modal_members_list nav nav-pills nav-stacked">

View File

@ -34,7 +34,7 @@
<div my-dialogs-list class="im_dialogs_col">
<div class="im_dialogs_wrap nano">
<div class="im_dialogs_scrollable_wrap content">
<div class="im_dialogs_scrollable_wrap nano-content">
<div class="im_dialogs_empty_wrap" ng-if="isEmpty.contacts">
<h3 class="im_dialogs_empty_header">No contacts yet</h3>
@ -153,7 +153,7 @@
<div class="im_history_wrap nano">
<div class="im_history_scrollable_wrap content">
<div class="im_history_scrollable_wrap nano-content">
<div class="im_history_scrollable">
<div class="im_history" ng-class="{im_history_selectable: selectActions}">

View File

@ -15,7 +15,7 @@
</div>
<div my-dialogs-list modal="true" class="im_dialogs_modal_col">
<div class="im_dialogs_wrap nano">
<div class="im_dialogs_scrollable_wrap content">
<div class="im_dialogs_scrollable_wrap nano-content">
<ul class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in dialogs track by dialogMessage.peerID"></li>
</ul>

View File

@ -15,7 +15,7 @@
<div my-contacts-list class="contacts_modal_col">
<div class="contacts_wrap nano" my-infinite-scroller>
<div class="contacts_scrollable_wrap content">
<div class="contacts_scrollable_wrap nano-content">
<ul class="contacts_modal_members_list nav nav-pills nav-stacked">

View File

@ -488,7 +488,7 @@
'<td><a class="emoji-menu-tab icon-grid"></a></td>' +
'</tr></table>').appendTo(this.$itemsTailWrap);
this.$itemsWrap = $('<div class="emoji-items-wrap nano"></div>').appendTo(this.$itemsTailWrap);
this.$items = $('<div class="emoji-items content">').appendTo(this.$itemsWrap);
this.$items = $('<div class="emoji-items nano-content">').appendTo(this.$itemsWrap);
$('<div class="emoji-menu-tail">').appendTo(this.$menu);
/*! MODIFICATION END */

View File

@ -5,7 +5,7 @@
height : 100%;
overflow : hidden;
}
.nano .content {
.nano > .nano-content {
position : absolute;
overflow : scroll;
overflow-x : hidden;
@ -14,23 +14,17 @@
bottom : 0;
left : 0;
}
.nano .content:focus {
.nano > .nano-content:focus {
outline: thin dotted;
}
.nano .content::-webkit-scrollbar {
.nano > .nano-content::-webkit-scrollbar {
visibility: hidden;
}
.has-scrollbar .content::-webkit-scrollbar {
.has-scrollbar > .nano-content::-webkit-scrollbar {
visibility: visible;
}
.nano .content::-moz-scrollbar {
visibility: hidden;
}
.has-scrollbar .content::-moz-scrollbar {
visibility: visible;
}
.nano > .pane {
background : rgba(0,0,0,.1);
.nano > .nano-pane {
background : rgba(0,0,0,.25);
position : absolute;
width : 10px;
right : 0;
@ -46,16 +40,16 @@
-webkit-border-radius : 5px;
border-radius : 5px;
}
.nano > .pane > .slider {
.nano > .nano-pane > .nano-slider {
background: #444;
background: rgba(0,0,0,.4);
background: rgba(0,0,0,.5);
position : relative;
margin : 0 1px;
-moz-border-radius : 3px;
-webkit-border-radius : 3px;
border-radius : 3px;
}
.nano:hover > .pane, .pane.active, .pane.flashed {
.nano:hover > .nano-pane, .nano-pane.active, .nano-pane.flashed {
visibility : visible\9; /* Target only IE7 and IE8 with this hack */
opacity : 0.99;
}

View File

@ -1,42 +1,43 @@
/*! nanoScrollerJS - v0.7.6 - 2013
/*! nanoScrollerJS - v0.8.0 - 2014
* http://jamesflorentino.github.com/nanoScrollerJS/
* Copyright (c) 2013 James Florentino; Licensed MIT */
* Copyright (c) 2014 James Florentino; Licensed MIT */
(function($, window, document) {
"use strict";
var BROWSER_IS_IE7, BROWSER_SCROLLBAR_WIDTH, DOMSCROLL, DOWN, DRAG, KEYDOWN, KEYUP, MOUSEDOWN, MOUSEMOVE, MOUSEUP, MOUSEWHEEL, NanoScroll, PANEDOWN, RESIZE, SCROLL, SCROLLBAR, TOUCHMOVE, UP, WHEEL, cAF, defaults, getBrowserScrollbarWidth, hasTransform, isFFWithBuggyScrollbar, rAF, transform, _elementStyle, _prefixStyle, _vendor;
defaults = {
/**
a classname for the pane element.
@property paneClass
@type String
@default 'pane'
@default 'nano-pane'
*/
paneClass: 'nano-pane',
paneClass: 'pane',
/**
a classname for the slider element.
@property sliderClass
@type String
@default 'slider'
@default 'nano-slider'
*/
sliderClass: 'nano-slider',
sliderClass: 'slider',
/**
a classname for the content element.
@property contentClass
@type String
@default 'content'
@default 'nano-content'
*/
contentClass: 'nano-content',
contentClass: 'content',
/**
a setting to enable native scrolling in iOS devices.
@property iOSNativeScrolling
@type Boolean
@default false
*/
iOSNativeScrolling: false,
/**
a setting to prevent the rest of the page being
scrolled when user scrolls the `.content` element.
@ -44,65 +45,65 @@
@type Boolean
@default false
*/
preventPageScrolling: false,
/**
a setting to disable binding to the resize event.
@property disableResize
@type Boolean
@default false
*/
disableResize: false,
/**
a setting to make the scrollbar always visible.
@property alwaysVisible
@type Boolean
@default false
*/
alwaysVisible: false,
/**
a default timeout for the `flash()` method.
@property flashDelay
@type Number
@default 1500
*/
flashDelay: 1500,
/**
a minimum height for the `.slider` element.
@property sliderMinHeight
@type Number
@default 20
*/
sliderMinHeight: 20,
/**
a maximum height for the `.slider` element.
@property sliderMaxHeight
@type Number
@default null
*/
sliderMaxHeight: null,
/**
an alternate document context.
@property documentContext
@type Document
@default null
*/
documentContext: null,
/**
an alternate window context.
@property windowContext
@type Window
@default null
*/
windowContext: null
};
/**
@property SCROLLBAR
@type String
@ -110,8 +111,8 @@
@final
@private
*/
SCROLLBAR = 'scrollbar';
/**
@property SCROLL
@type String
@ -119,16 +120,16 @@
@final
@private
*/
SCROLL = 'scroll';
/**
@property MOUSEDOWN
@type String
@final
@private
*/
MOUSEDOWN = 'mousedown';
/**
@property MOUSEMOVE
@type String
@ -136,16 +137,16 @@
@final
@private
*/
MOUSEMOVE = 'mousemove';
/**
@property MOUSEWHEEL
@type String
@final
@private
*/
MOUSEWHEEL = 'mousewheel';
/**
@property MOUSEUP
@type String
@ -153,16 +154,16 @@
@final
@private
*/
MOUSEUP = 'mouseup';
/**
@property RESIZE
@type String
@final
@private
*/
RESIZE = 'resize';
/**
@property DRAG
@type String
@ -170,8 +171,8 @@
@final
@private
*/
DRAG = 'drag';
/**
@property UP
@type String
@ -179,8 +180,8 @@
@final
@private
*/
UP = 'up';
/**
@property PANEDOWN
@type String
@ -188,8 +189,8 @@
@final
@private
*/
PANEDOWN = 'panedown';
/**
@property DOMSCROLL
@type String
@ -197,8 +198,8 @@
@final
@private
*/
DOMSCROLL = 'DOMMouseScroll';
/**
@property DOWN
@type String
@ -206,8 +207,8 @@
@final
@private
*/
DOWN = 'down';
/**
@property WHEEL
@type String
@ -215,8 +216,8 @@
@final
@private
*/
WHEEL = 'wheel';
/**
@property KEYDOWN
@type String
@ -224,8 +225,8 @@
@final
@private
*/
KEYDOWN = 'keydown';
/**
@property KEYUP
@type String
@ -233,8 +234,8 @@
@final
@private
*/
KEYUP = 'keyup';
/**
@property TOUCHMOVE
@type String
@ -242,8 +243,8 @@
@final
@private
*/
TOUCHMOVE = 'touchmove';
/**
@property BROWSER_IS_IE7
@type Boolean
@ -251,8 +252,8 @@
@final
@private
*/
BROWSER_IS_IE7 = window.navigator.appName === 'Microsoft Internet Explorer' && /msie 7./i.test(window.navigator.appVersion) && window.ActiveXObject;
/**
@property BROWSER_SCROLLBAR_WIDTH
@type Number
@ -260,7 +261,6 @@
@default null
@private
*/
BROWSER_SCROLLBAR_WIDTH = null;
rAF = window.requestAnimationFrame;
cAF = window.cancelAnimationFrame;
@ -288,6 +288,7 @@
};
transform = _prefixStyle('transform');
hasTransform = transform !== false;
/**
Returns browser's native scrollbar width
@method getBrowserScrollbarWidth
@ -295,7 +296,6 @@
@static
@private
*/
getBrowserScrollbarWidth = function() {
var outer, outerStyle, scrollbarWidth;
outer = document.createElement('div');
@ -323,13 +323,13 @@
}
return isOSXFF && +version > 23;
};
/**
@class NanoScroll
@param element {HTMLElement|Node} the main element
@param options {Object} nanoScroller's options
@constructor
*/
NanoScroll = (function() {
function NanoScroll(el, options) {
this.el = el;
@ -341,6 +341,7 @@
this.$content = this.$el.children("." + options.contentClass);
this.$content.attr('tabindex', this.options.tabIndex || 0);
this.content = this.$content[0];
this.previousPosition = 0;
if (this.options.iOSNativeScrolling && (this.el.style.WebkitOverflowScrolling != null)) {
this.nativeScrolling();
} else {
@ -351,16 +352,16 @@
this.reset();
}
/**
Prevents the rest of the page being scrolled
when user scrolls the `.content` element.
when user scrolls the `.nano-content` element.
@method preventScrolling
@param event {Event}
@param direction {String} Scroll direction (up or down)
@private
*/
NanoScroll.prototype.preventScrolling = function(e, direction) {
if (!this.isActive) {
return;
@ -379,13 +380,13 @@
}
};
/**
Enable iOS native scrolling
@method nativeScrolling
@private
*/
NanoScroll.prototype.nativeScrolling = function() {
this.$content.css({
WebkitOverflowScrolling: 'touch'
@ -394,6 +395,7 @@
this.isActive = true;
};
/**
Updates those nanoScroller properties that
are related to current scrollbar position.
@ -401,21 +403,28 @@
@private
*/
NanoScroll.prototype.updateScrollValues = function() {
var content;
var content, direction;
content = this.content;
this.maxScrollTop = content.scrollHeight - content.clientHeight;
this.prevScrollTop = this.contentScrollTop || 0;
this.contentScrollTop = content.scrollTop;
direction = this.contentScrollTop > this.previousPosition ? "down" : this.contentScrollTop < this.previousPosition ? "up" : "same";
this.previousPosition = this.contentScrollTop;
if (direction !== "same") {
this.$el.trigger('update', {
position: this.contentScrollTop,
maximum: this.maxScrollTop,
direction: direction
});
}
if (!this.iOSNativeScrolling) {
// console.log(this.maxScrollTop, this.contentScrollTop, this.maxSliderTop, this.maxScrollTop);
// console.trace();
this.maxSliderTop = this.paneHeight - this.sliderHeight;
this.sliderTop = this.maxScrollTop === 0 ? 0 : this.contentScrollTop * this.maxSliderTop / this.maxScrollTop;
}
};
/**
Updates CSS styles for current scroll position.
Uses CSS 2d transfroms and `window.requestAnimationFrame` if available.
@ -423,15 +432,11 @@
@private
*/
NanoScroll.prototype.setOnScrollStyles = function() {
var cssValue,
_this = this;
var cssValue;
if (hasTransform) {
cssValue = {};
cssValue[transform] = "translate(0, " + this.sliderTop + "px)";
// console.log(this.sliderTop, cssValue, this.scrollRAF, rAF);
} else {
cssValue = {
top: this.sliderTop
@ -439,65 +444,75 @@
}
if (rAF) {
if (!this.scrollRAF) {
this.scrollRAF = rAF(function() {
// console.log('raf called', cssValue);
this.scrollRAF = rAF((function(_this) {
return function() {
_this.scrollRAF = null;
_this.slider.css(cssValue);
});
};
})(this));
}
} else {
this.slider.css(cssValue);
}
};
/**
Creates event related methods
@method createEvents
@private
*/
NanoScroll.prototype.createEvents = function() {
var _this = this;
this.events = {
down: function(e) {
down: (function(_this) {
return function(e) {
_this.isBeingDragged = true;
_this.offsetY = e.pageY - _this.slider.offset().top;
_this.pane.addClass('active');
_this.doc.bind(MOUSEMOVE, _this.events[DRAG]).bind(MOUSEUP, _this.events[UP]);
return false;
},
drag: function(e) {
};
})(this),
drag: (function(_this) {
return function(e) {
_this.sliderY = e.pageY - _this.$el.offset().top - _this.offsetY;
_this.scroll();
_this.updateScrollValues();
if (_this.contentScrollTop >= _this.maxScrollTop && _this.prevScrollTop !== _this.maxScrollTop) {
_this.$el.trigger('scrollend');
} else if (_this.contentScrollTop === 0 && _this.prevScrollTop !== 0) {
_this.$el.trigger('scrolltop');
}
return false;
},
up: function(e) {
};
})(this),
up: (function(_this) {
return function(e) {
_this.isBeingDragged = false;
_this.pane.removeClass('active');
_this.doc.unbind(MOUSEMOVE, _this.events[DRAG]).unbind(MOUSEUP, _this.events[UP]);
return false;
},
resize: function(e) {
};
})(this),
resize: (function(_this) {
return function(e) {
_this.reset();
},
panedown: function(e) {
};
})(this),
panedown: (function(_this) {
return function(e) {
_this.sliderY = (e.offsetY || e.originalEvent.layerY) - (_this.sliderHeight * 0.5);
_this.scroll();
_this.events.down(e);
return false;
},
scroll: function(e) {
};
})(this),
scroll: (function(_this) {
return function(e) {
_this.updateScrollValues();
if (_this.isBeingDragged) {
return;
}
_this.updateScrollValues();
if (!_this.iOSNativeScrolling) {
_this.sliderY = _this.sliderTop;
_this.setOnScrollStyles();
@ -520,8 +535,10 @@
_this.$el.trigger('scrolltop');
}
}
},
wheel: function(e) {
};
})(this),
wheel: (function(_this) {
return function(e) {
var delta;
if (e == null) {
return;
@ -532,17 +549,18 @@
}
_this.scroll();
return false;
}
};
})(this)
};
};
/**
Adds event listeners with jQuery.
@method addEvents
@private
*/
NanoScroll.prototype.addEvents = function() {
var events;
this.removeEvents();
@ -557,13 +575,13 @@
this.$content.bind("" + SCROLL + " " + MOUSEWHEEL + " " + DOMSCROLL + " " + TOUCHMOVE, events[SCROLL]);
};
/**
Removes event listeners with jQuery.
@method removeEvents
@private
*/
NanoScroll.prototype.removeEvents = function() {
var events;
events = this.events;
@ -575,6 +593,7 @@
this.$content.unbind("" + SCROLL + " " + MOUSEWHEEL + " " + DOMSCROLL + " " + TOUCHMOVE, events[SCROLL]);
};
/**
Generates nanoScroller's scrollbar and elements for it.
@method generate
@ -582,12 +601,11 @@
@private
*/
NanoScroll.prototype.generate = function() {
var contentClass, cssRule, currentPadding, options, paneClass, sliderClass;
var contentClass, cssRule, currentPadding, options, pane, paneClass, sliderClass;
options = this.options;
paneClass = options.paneClass, sliderClass = options.sliderClass, contentClass = options.contentClass;
if (!this.$el.find("." + paneClass).length && !this.$el.find("." + sliderClass).length) {
if (!(pane = this.$el.children("." + paneClass)).length && !pane.children("." + sliderClass).length) {
this.$el.append("<div class=\"" + paneClass + "\"><div class=\"" + sliderClass + "\" /></div>");
}
this.pane = this.$el.children("." + paneClass);
@ -610,12 +628,12 @@
return this;
};
/**
@method restore
@private
*/
NanoScroll.prototype.restore = function() {
this.stopped = false;
if (!this.iOSNativeScrolling) {
@ -624,6 +642,7 @@
this.addEvents();
};
/**
Resets nanoScroller's scrollbar.
@method reset
@ -632,9 +651,8 @@
$(".nano").nanoScroller();
*/
NanoScroll.prototype.reset = function() {
var content, contentHeight, contentStyle, contentStyleOverflowY, paneBottom, paneHeight, paneOuterHeight, paneTop, parentMaxHeight, sliderHeight;
var content, contentHeight, contentPosition, contentStyle, contentStyleOverflowY, paneBottom, paneHeight, paneOuterHeight, paneTop, parentMaxHeight, right, sliderHeight;
if (this.iOSNativeScrolling) {
this.contentHeight = this.content.scrollHeight;
return;
@ -693,9 +711,20 @@
opacity: (this.options.alwaysVisible ? 1 : ''),
visibility: (this.options.alwaysVisible ? 'visible' : '')
});
contentPosition = this.$content.css('position');
if (contentPosition === 'static' || contentPosition === 'relative') {
right = parseInt(this.$content.css('right'), 10);
if (right) {
this.$content.css({
right: '',
marginRight: right
});
}
}
return this;
};
/**
@method scroll
@private
@ -703,7 +732,6 @@
$(".nano").nanoScroller({ scroll: 'top' });
*/
NanoScroll.prototype.scroll = function() {
if (!this.isActive) {
return;
@ -718,6 +746,7 @@
return this;
};
/**
Scroll at the bottom with an offset value
@method scrollBottom
@ -727,16 +756,16 @@
$(".nano").nanoScroller({ scrollBottom: value });
*/
NanoScroll.prototype.scrollBottom = function(offsetY) {
if (!this.isActive) {
return;
}
this.reset();
this.$content.scrollTop(this.contentHeight - this.$content.height() - offsetY).trigger(MOUSEWHEEL);
this.stop().restore();
return this;
};
/**
Scroll at the top with an offset value
@method scrollTop
@ -746,16 +775,16 @@
$(".nano").nanoScroller({ scrollTop: value });
*/
NanoScroll.prototype.scrollTop = function(offsetY) {
if (!this.isActive) {
return;
}
this.reset();
this.$content.scrollTop(+offsetY).trigger(MOUSEWHEEL);
this.stop().restore();
return this;
};
/**
Scroll to an element
@method scrollTo
@ -765,16 +794,15 @@
$(".nano").nanoScroller({ scrollTo: $('#a_node') });
*/
NanoScroll.prototype.scrollTo = function(node) {
if (!this.isActive) {
return;
}
this.reset();
this.scrollTop($(node).get(0).offsetTop);
this.scrollTop(this.$el.find(node).get(0).offsetTop);
return this;
};
/**
To stop the operation.
This option will tell the plugin to disable all event bindings and hide the gadget scrollbar from the UI.
@ -784,10 +812,10 @@
$(".nano").nanoScroller({ stop: true });
*/
NanoScroll.prototype.stop = function() {
if (cAF) {
if (cAF && this.scrollRAF) {
cAF(this.scrollRAF);
this.scrollRAF = null;
}
this.stopped = true;
this.removeEvents();
@ -797,6 +825,7 @@
return this;
};
/**
Destroys nanoScroller and restores browser's native scrollbar.
@method destroy
@ -805,7 +834,6 @@
$(".nano").nanoScroller({ destroy: true });
*/
NanoScroll.prototype.destroy = function() {
if (!this.stopped) {
this.stop();
@ -826,6 +854,7 @@
return this;
};
/**
To flash the scrollbar gadget for an amount of time defined in plugin settings (defaults to 1,5s).
Useful if you want to show the user (e.g. on pageload) that there is more content waiting for him.
@ -835,9 +864,7 @@
$(".nano").nanoScroller({ flash: true });
*/
NanoScroll.prototype.flash = function() {
var _this = this;
if (this.iOSNativeScrolling) {
return;
}
@ -846,9 +873,11 @@
}
this.reset();
this.pane.addClass('flashed');
setTimeout(function() {
setTimeout((function(_this) {
return function() {
_this.pane.removeClass('flashed');
}, this.options.flashDelay);
};
})(this), this.options.flashDelay);
return this;
};