1/* jquery.nicescroll 2-- version 3.4.0 3-- copyright 2011-12-13 InuYaksa*2013 4-- licensed under the MIT 5-- 6-- http://areaaperta.com/nicescroll 7-- https://github.com/inuyaksa/jquery.nicescroll 8-- 9*/ 10 11(function(jQuery){ 12 13 // globals 14 var domfocus = false; 15 var mousefocus = false; 16 var zoomactive = false; 17 var tabindexcounter = 5000; 18 var ascrailcounter = 2000; 19 var globalmaxzindex = 0; 20 21 var $ = jQuery; // sandbox 22 23 // http://stackoverflow.com/questions/2161159/get-script-path 24 function getScriptPath() { 25 var scripts=document.getElementsByTagName('script'); 26 var path=scripts[scripts.length-1].src.split('?')[0]; 27 return (path.split('/').length>0) ? path.split('/').slice(0,-1).join('/')+'/' : ''; 28 } 29 var scriptpath = getScriptPath(); 30 31// derived by Paul Irish https://gist.github.com/paulirish/1579671 - thanks for your code! 32 33 if (!Array.prototype.forEach) { // JS 1.6 polyfill 34 Array.prototype.forEach = function(fn, scope) { 35 for(var i = 0, len = this.length; i < len; ++i) { 36 fn.call(scope, this[i], i, this); 37 } 38 } 39 } 40 41 var vendors = ['ms','moz','webkit','o']; 42 43 var setAnimationFrame = window.requestAnimationFrame||false; 44 var clearAnimationFrame = window.cancelAnimationFrame||false; 45 46 vendors.forEach(function(v){ 47 if (!setAnimationFrame) setAnimationFrame = window[v+'RequestAnimationFrame']; 48 if (!clearAnimationFrame) clearAnimationFrame = window[v+'CancelAnimationFrame']||window[v+'CancelRequestAnimationFrame']; 49 }); 50 51 var clsMutationObserver = window.MutationObserver || window.WebKitMutationObserver || false; 52 53 var _globaloptions = { 54 zindex:"auto", 55 cursoropacitymin:0, 56 cursoropacitymax:1, 57 cursorcolor:"#424242", 58 cursorwidth:"5px", 59 cursorborder:"1px solid #fff", 60 cursorborderradius:"5px", 61 scrollspeed:60, 62 mousescrollstep:8*3, 63 touchbehavior:false, 64 hwacceleration:true, 65 usetransition:true, 66 boxzoom:false, 67 dblclickzoom:true, 68 gesturezoom:true, 69 grabcursorenabled:true, 70 autohidemode:true, 71 background:"", 72 iframeautoresize:true, 73 cursorminheight:32, 74 preservenativescrolling:true, 75 railoffset:false, 76 bouncescroll:true, 77 spacebarenabled:true, 78 railpadding:{top:0,right:0,left:0,bottom:0}, 79 disableoutline:true, 80 horizrailenabled:true, 81 railalign:"right", 82 railvalign:"bottom", 83 enabletranslate3d:true, 84 enablemousewheel:true, 85 enablekeyboard:true, 86 smoothscroll:true, 87 sensitiverail:true, 88 enablemouselockapi:true, 89// cursormaxheight:false, 90 cursorfixedheight:false, 91 directionlockdeadzone:6, 92 hidecursordelay:400, 93 nativeparentscrolling:true, 94 enablescrollonselection:true, 95 overflowx:true, 96 overflowy:true, 97 cursordragspeed:0.3, 98 rtlmode:false, 99 cursordragontouch:false 100 } 101 102 var browserdetected = false; 103 104 var getBrowserDetection = function() { 105 106 if (browserdetected) return browserdetected; 107 108 var domtest = document.createElement('DIV'); 109 110 var d = {}; 111 112 d.haspointerlock = "pointerLockElement" in document || "mozPointerLockElement" in document || "webkitPointerLockElement" in document; 113 114 d.isopera = ("opera" in window); 115 d.isopera12 = (d.isopera&&("getUserMedia" in navigator)); 116 117 d.isie = (("all" in document) && ("attachEvent" in domtest) && !d.isopera); 118 d.isieold = (d.isie && !("msInterpolationMode" in domtest.style)); // IE6 and older 119 d.isie7 = d.isie&&!d.isieold&&(!("documentMode" in document)||(document.documentMode==7)); 120 d.isie8 = d.isie&&("documentMode" in document)&&(document.documentMode==8); 121 d.isie9 = d.isie&&("performance" in window)&&(document.documentMode>=9); 122 d.isie10 = d.isie&&("performance" in window)&&(document.documentMode>=10); 123 124 d.isie9mobile = /iemobile.9/i.test(navigator.userAgent); //wp 7.1 mango 125 if (d.isie9mobile) d.isie9 = false; 126 d.isie7mobile = (!d.isie9mobile&&d.isie7) && /iemobile/i.test(navigator.userAgent); //wp 7.0 127 128 d.ismozilla = ("MozAppearance" in domtest.style); 129 130 d.iswebkit = ("WebkitAppearance" in domtest.style); 131 132 d.ischrome = ("chrome" in window); 133 d.ischrome22 = (d.ischrome&&d.haspointerlock); 134 d.ischrome26 = (d.ischrome&&("transition" in domtest.style)); // issue with transform detection (maintain prefix) 135 136 d.cantouch = ("ontouchstart" in document.documentElement)||("ontouchstart" in window); // detection for Chrome Touch Emulation 137 d.hasmstouch = (window.navigator.msPointerEnabled||false); // IE10+ pointer events 138 139 d.ismac = /^mac$/i.test(navigator.platform); 140 141 d.isios = (d.cantouch && /iphone|ipad|ipod/i.test(navigator.platform)); 142 d.isios4 = ((d.isios)&&!("seal" in Object)); 143 144 d.isandroid = (/android/i.test(navigator.userAgent)); 145 146 d.trstyle = false;
147 d.hastransform = false; 148 d.hastranslate3d = false; 149 d.transitionstyle = false; 150 d.hastransition = false; 151 d.transitionend = false; 152 153 var check = ['transform','msTransform','webkitTransform','MozTransform','OTransform']; 154 for(var a=0;a<check.length;a++){ 155 if (typeof domtest.style[check[a]] != "undefined") { 156 d.trstyle = check[a]; 157 break; 158 } 159 } 160 d.hastransform = (d.trstyle != false); 161 if (d.hastransform) { 162 domtest.style[d.trstyle] = "translate3d(1px,2px,3px)"; 163 d.hastranslate3d = /translate3d/.test(domtest.style[d.trstyle]); 164 } 165 166 d.transitionstyle = false; 167 d.prefixstyle = ''; 168 d.transitionend = false; 169 var check = ['transition','webkitTransition','MozTransition','OTransition','OTransition','msTransition','KhtmlTransition']; 170 var prefix = ['','-webkit-','-moz-','-o-','-o','-ms-','-khtml-']; 171 var evs = ['transitionend','webkitTransitionEnd','transitionend','otransitionend','oTransitionEnd','msTransitionEnd','KhtmlTransitionEnd']; 172 for(var a=0;a<check.length;a++) { 173 if (check[a] in domtest.style) { 174 d.transitionstyle = check[a]; 175 d.prefixstyle = prefix[a]; 176 d.transitionend = evs[a]; 177 break; 178 } 179 } 180 if (d.ischrome26) { // use always prefix 181 d.prefixstyle = prefix[1]; 182 } 183 184 d.hastransition = (d.transitionstyle); 185 186 function detectCursorGrab() { 187 var lst = ['-moz-grab','-webkit-grab','grab']; 188 if ((d.ischrome&&!d.ischrome22)||d.isie) lst=[]; // force setting for IE returns false positive and chrome cursor bug 189 for(var a=0;a<lst.length;a++) { 190 var p = lst[a]; 191 domtest.style['cursor']=p; 192 if (domtest.style['cursor']==p) return p; 193 } 194 return 'url(http://www.google.com/intl/en_ALL/mapfiles/openhand.cur),n-resize'; // thank you google for custom cursor! 195 } 196 d.cursorgrabvalue = detectCursorGrab(); 197 198 d.hasmousecapture = ("setCapture" in domtest); 199 200 d.hasMutationObserver = (clsMutationObserver !== false); 201 202 domtest = null; //memory released 203 204 browserdetected = d; 205 206 return d; 207 } 208 209 var NiceScrollClass = function(myopt,me) { 210 211 var self = this; 212 213 this.version = '3.4.0'; 214 this.name = 'nicescroll'; 215 216 this.me = me; 217 218 this.opt = { 219 doc:$("body"), 220 win:false 221 }; 222 223 $.extend(this.opt,_globaloptions); 224 225// Options for internal use 226 this.opt.snapbackspeed = 80; 227 228 if (myopt||false) { 229 for(var a in self.opt) { 230 if (typeof myopt[a] != "undefined") self.opt[a] = myopt[a]; 231 } 232 } 233 234 this.doc = self.opt.doc; 235 this.iddoc = (this.doc&&this.doc[0])?this.doc[0].id||'':''; 236 this.ispage = /BODY|HTML/.test((self.opt.win)?self.opt.win[0].nodeName:this.doc[0].nodeName); 237 this.haswrapper = (self.opt.win!==false); 238 this.win = self.opt.win||(this.ispage?$(window):this.doc); 239 this.docscroll = (this.ispage&&!this.haswrapper)?$(window):this.win; 240 this.body = $("body"); 241 this.viewport = false; 242 243 this.isfixed = false; 244 245 this.iframe = false; 246 this.isiframe = ((this.doc[0].nodeName == 'IFRAME') && (this.win[0].nodeName == 'IFRAME')); 247 248 this.istextarea = (this.win[0].nodeName == 'TEXTAREA'); 249 250 this.forcescreen = false; //force to use screen position on events 251 252 this.canshowonmouseevent = (self.opt.autohidemode!="scroll"); 253 254// Events jump table 255 this.onmousedown = false; 256 this.onmouseup = false; 257 this.onmousemove = false; 258 this.onmousewheel = false; 259 this.onkeypress = false; 260 this.ongesturezoom = false; 261 this.onclick = false; 262 263// Nicescroll custom events 264 this.onscrollstart = false;
265 this.onscrollend = false; 266 this.onscrollcancel = false; 267 268 this.onzoomin = false; 269 this.onzoomout = false; 270 271// Let's start! 272 this.view = false; 273 this.page = false; 274 275 this.scroll = {x:0,y:0}; 276 this.scrollratio = {x:0,y:0}; 277 this.cursorheight = 20; 278 this.scrollvaluemax = 0; 279 280 this.checkrtlmode = false; 281 282 this.scrollrunning = false; 283 284 this.scrollmom = false; 285 286 this.observer = false; 287 this.observerremover = false; // observer on parent for remove detection 288 289 do { 290 this.id = "ascrail"+(ascrailcounter++); 291 } while (document.getElementById(this.id)); 292 293 this.rail = false; 294 this.cursor = false; 295 this.cursorfreezed = false; 296 this.selectiondrag = false; 297 298 this.zoom = false; 299 this.zoomactive = false; 300 301 this.hasfocus = false; 302 this.hasmousefocus = false; 303 304 this.visibility = true; 305 this.locked = false; 306 this.hidden = false; // rails always hidden 307 this.cursoractive = true; // user can interact with cursors 308 309 this.overflowx = self.opt.overflowx; 310 this.overflowy = self.opt.overflowy; 311 312 this.nativescrollingarea = false; 313 this.checkarea = 0; 314 315 this.events = []; // event list for unbind 316 317 this.saved = {}; 318 319 this.delaylist = {}; 320 this.synclist = {}; 321 322 this.lastdeltax = 0; 323 this.lastdeltay = 0; 324 325 this.detected = getBrowserDetection(); 326 327 var cap = $.extend({},this.detected); 328 329 this.canhwscroll = (cap.hastransform&&self.opt.hwacceleration); 330 this.ishwscroll = (this.canhwscroll&&self.haswrapper); 331 332 this.istouchcapable = false; // desktop devices with touch screen support 333 334//## Check Chrome desktop with touch support 335 if (cap.cantouch&&cap.ischrome&&!cap.isios&&!cap.isandroid) { 336 this.istouchcapable = true; 337 cap.cantouch = false; // parse normal desktop events 338 } 339 340//## Firefox 18 nightly build (desktop) false positive (or desktop with touch support) 341 if (cap.cantouch&&cap.ismozilla&&!cap.isios) { 342 this.istouchcapable = true; 343 cap.cantouch = false; // parse normal desktop events 344 } 345 346//## disable MouseLock API on user request 347 348 if (!self.opt.enablemouselockapi) { 349 cap.hasmousecapture = false; 350 cap.haspointerlock = false; 351 } 352 353 this.delayed = function(name,fn,tm,lazy) { 354 var dd = self.delaylist[name]; 355 var nw = (new Date()).getTime(); 356 if (!lazy&&dd&&dd.tt) return false; 357 if (dd&&dd.tt) clearTimeout(dd.tt); 358 if (dd&&dd.last+tm>nw&&!dd.tt) { 359 self.delaylist[name] = { 360 last:nw+tm, 361 tt:setTimeout(function(){self.delaylist[name].tt=0;fn.call();},tm) 362 } 363 } 364 else if (!dd||!dd.tt) { 365 self.delaylist[name] = { 366 last:nw, 367 tt:0 368 } 369 setTimeout(function(){fn.call();},0); 370 } 371 }; 372 373 this.debounced = function(name,fn,tm) { 374 var dd = self.delaylist[name]; 375 var nw = (new Date()).getTime(); 376 self.delaylist[name] = fn; 377 if (!dd) { 378 setTimeout(function(){var fn=self.delaylist[name];self.delaylist[name]=false;fn.call();},tm); 379 } 380 } 381 382 this.synched = function(name,fn) { 383 384 function requestSync() { 385 if (self.onsync) return; 386 setAnimationFrame(function(){ 387 self.onsync = false; 388 for(name in self.synclist){ 389 var fn = self.synclist[name]; 390 if (fn) fn.call(self); 391 self.synclist[name] = false; 392 } 393 }); 394 self.onsync = true; 395 }; 396 397 self.synclist[name] = fn; 398 requestSync(); 399 return name; 400 }; 401 402 this.unsynched = function(name) { 403 if (self.synclist[name]) self.synclist[name] = false; 404 } 405 406 this.css = function(el,pars) { // save & set 407 for(var n in pars) { 408 self.saved.css.push([el,n,el.css(n)]); 409 el.css(n,pars[n]); 410 } 411 }; 412 413 this.scrollTop = function(val) { 414 return (typeof val == "undefined") ? self.getScrollTop() : self.setScrollTop(val); 415 }; 416 417 this.scrollLeft = function(val) { 418 return (typeof val == "undefined") ? self.getScrollLeft() : self.setScrollLeft(val); 419 }; 420 421// derived by by Dan Pupius www.pupius.net 422 BezierClass = function(st,ed,spd,p1,p2,p3,p4) { 423 this.st = st; 424 this.ed = ed; 425 this.spd = spd; 426 427 this.p1 = p1||0; 428 this.p2 = p2||1; 429 this.p3 = p3||0; 430 this.p4 = p4||1; 431
432 this.ts = (new Date()).getTime(); 433 this.df = this.ed-this.st; 434 }; 435 BezierClass.prototype = { 436 B2:function(t){ return 3*t*t*(1-t) }, 437 B3:function(t){ return 3*t*(1-t)*(1-t) }, 438 B4:function(t){ return (1-t)*(1-t)*(1-t) }, 439 getNow:function(){ 440 var nw = (new Date()).getTime(); 441 var pc = 1-((nw-this.ts)/this.spd); 442 var bz = this.B2(pc) + this.B3(pc) + this.B4(pc); 443 return (pc<0) ? this.ed : this.st+Math.round(this.df*bz); 444 }, 445 update:function(ed,spd){ 446 this.st = this.getNow(); 447 this.ed = ed; 448 this.spd = spd; 449 this.ts = (new Date()).getTime(); 450 this.df = this.ed-this.st; 451 return this; 452 } 453 }; 454 455 if (this.ishwscroll) { 456 // hw accelerated scroll 457 this.doc.translate = {x:0,y:0,tx:"0px",ty:"0px"}; 458 459 //this one can help to enable hw accel on ios6 http://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/ 460 if (cap.hastranslate3d&&cap.isios) this.doc.css("-webkit-backface-visibility","hidden"); // prevent flickering http://stackoverflow.com/questions/3461441/ 461 462 //derived from http://stackoverflow.com/questions/11236090/ 463 function getMatrixValues() { 464 var tr = self.doc.css(cap.trstyle); 465 if (tr&&(tr.substr(0,6)=="matrix")) { 466 return tr.replace(/^.*\((.*)\)$/g, "$1").replace(/px/g,'').split(/, +/); 467 } 468 return false; 469 } 470
471 this.getScrollTop = function(last) { 472 if (!last) { 473 var mtx = getMatrixValues(); 474 if (mtx) return (mtx.length==16) ? -mtx[13] : -mtx[5]; //matrix3d 16 on IE10 475 if (self.timerscroll&&self.timerscroll.bz) return self.timerscroll.bz.getNow(); 476 } 477 return self.doc.translate.y; 478 }; 479 480 this.getScrollLeft = function(last) { 481 if (!last) { 482 var mtx = getMatrixValues(); 483 if (mtx) return (mtx.length==16) ? -mtx[12] : -mtx[4]; //matrix3d 16 on IE10 484 if (self.timerscroll&&self.timerscroll.bh) return self.timerscroll.bh.getNow(); 485 } 486 return self.doc.translate.x; 487 }; 488 489 if (document.createEvent) { 490 this.notifyScrollEvent = function(el) { 491 var e = document.createEvent("UIEvents"); 492 e.initUIEvent("scroll", false, true, window, 1); 493 el.dispatchEvent(e); 494 }; 495 } 496 else if (document.fireEvent) { 497 this.notifyScrollEvent = function(el) { 498 var e = document.createEventObject(); 499 el.fireEvent("onscroll"); 500 e.cancelBubble = true; 501 }; 502 } 503 else { 504 this.notifyScrollEvent = function(el,add) {}; //NOPE 505 } 506 507 if (cap.hastranslate3d&&self.opt.enabletranslate3d) { 508 this.setScrollTop = function(val,silent) { 509 self.doc.translate.y = val; 510 self.doc.translate.ty = (val*-1)+"px"; 511 self.doc.css(cap.trstyle,"translate3d("+self.doc.translate.tx+","+self.doc.translate.ty+",0px)"); 512 if (!silent) self.notifyScrollEvent(self.win[0]); 513 }; 514 this.setScrollLeft = function(val,silent) { 515 self.doc.translate.x = val; 516 self.doc.translate.tx = (val*-1)+"px"; 517 self.doc.css(cap.trstyle,"translate3d("+self.doc.translate.tx+","+self.doc.translate.ty+",0px)"); 518 if (!silent) self.notifyScrollEvent(self.win[0]); 519 }; 520 } else { 521 this.setScrollTop = function(val,silent) { 522 self.doc.translate.y = val; 523 self.doc.translate.ty = (val*-1)+"px"; 524 self.doc.css(cap.trstyle,"translate("+self.doc.translate.tx+","+self.doc.translate.ty+")"); 525 if (!silent) self.notifyScrollEvent(self.win[0]); 526 }; 527 this.setScrollLeft = function(val,silent) { 528 self.doc.translate.x = val; 529 self.doc.translate.tx = (val*-1)+"px"; 530 self.doc.css(cap.trstyle,"translate("+self.doc.translate.tx+","+self.doc.translate.ty+")"); 531 if (!silent) self.notifyScrollEvent(self.win[0]); 532 }; 533 } 534 } else { 535 // native scroll
536 this.getScrollTop = function() { 537 return self.docscroll.scrollTop(); 538 }; 539 this.setScrollTop = function(val) { 540 return self.docscroll.scrollTop(val); 541 }; 542 this.getScrollLeft = function() { 543 return self.docscroll.scrollLeft(); 544 }; 545 this.setScrollLeft = function(val) { 546 return self.docscroll.scrollLeft(val); 547 }; 548 } 549 550 this.getTarget = function(e) { 551 if (!e) return false; 552 if (e.target) return e.target; 553 if (e.srcElement) return e.srcElement; 554 return false; 555 }; 556 557 this.hasParent = function(e,id) { 558 if (!e) return false; 559 var el = e.target||e.srcElement||e||false; 560 while (el && el.id != id) { 561 el = el.parentNode||false; 562 } 563 return (el!==false); 564 }; 565 566 function getZIndex() { 567 var dom = self.win; 568 if ("zIndex" in dom) return dom.zIndex(); // use jQuery UI method when available 569 while (dom.length>0) { 570 if (dom[0].nodeType==9) return false; 571 var zi = dom.css('zIndex'); 572 if (!isNaN(zi)&&zi!=0) return parseInt(zi); 573 dom = dom.parent(); 574 } 575 return false; 576 }; 577 578//inspired by http://forum.jquery.com/topic/width-includes-border-width-when-set-to-thin-medium-thick-in-ie 579 var _convertBorderWidth = {"thin":1,"medium":3,"thick":5}; 580 function getWidthToPixel(dom,prop,chkheight) { 581 var wd = dom.css(prop); 582 var px = parseFloat(wd); 583 if (isNaN(px)) { 584 px = _convertBorderWidth[wd]||0; 585 var brd = (px==3) ? ((chkheight)?(self.win.outerHeight() - self.win.innerHeight()):(self.win.outerWidth() - self.win.innerWidth())) : 1; //DON'T TRUST CSS 586 if (self.isie8&&px) px+=1; 587 return (brd) ? px : 0; 588 } 589 return px; 590 }; 591 592 this.getOffset = function() { 593 if (self.isfixed) return {top:parseFloat(self.win.css('top')),left:parseFloat(self.win.css('left'))}; 594 if (!self.viewport) return self.win.offset(); 595 var ww = self.win.offset(); 596 var vp = self.viewport.offset(); 597 return {top:ww.top-vp.top+self.viewport.scrollTop(),left:ww.left-vp.left+self.viewport.scrollLeft()}; 598 }; 599 600 this.updateScrollBar = function(len) { 601 if (self.ishwscroll) { 602 self.rail.css({height:self.win.innerHeight()}); 603 if (self.railh) self.railh.css({width:self.win.innerWidth()}); 604 } else { 605 var wpos = self.getOffset(); 606 var pos = {top:wpos.top,left:wpos.left}; 607 pos.top+= getWidthToPixel(self.win,'border-top-width',true); 608 var brd = (self.win.outerWidth() - self.win.innerWidth())/2; 609 pos.left+= (self.rail.align) ? self.win.outerWidth() - getWidthToPixel(self.win,'border-right-width') - self.rail.width : getWidthToPixel(self.win,'border-left-width'); 610 611 var off = self.opt.railoffset; 612 if (off) { 613 if (off.top) pos.top+=off.top; 614 if (self.rail.align&&off.left) pos.left+=off.left; 615 } 616 617 if (!self.locked) self.rail.css({top:pos.top,left:pos.left,height:(len)?len.h:self.win.innerHeight()}); 618 619 if (self.zoom) { 620 self.zoom.css({top:pos.top+1,left:(self.rail.align==1) ? pos.left-20 : pos.left+self.rail.width+4}); 621 } 622 623 if (self.railh&&!self.locked) { 624 var pos = {top:wpos.top,left:wpos.left}; 625 var y = (self.railh.align) ? pos.top + getWidthToPixel(self.win,'border-top-width',true) + self.win.innerHeight() - self.railh.height : pos.top + getWidthToPixel(self.win,'border-top-width',true); 626 var x = pos.left + getWidthToPixel(self.win,'border-left-width'); 627 self.railh.css({top:y,left:x,width:self.railh.width}); 628 } 629 630 631 } 632 }; 633 634 this.doRailClick = function(e,dbl,hr) { 635 636 var fn,pg,cur,pos; 637 638// if (self.rail.drag&&self.rail.drag.pt!=1) return; 639 if (self.locked) return; 640// if (self.rail.drag) return; 641 642// self.cancelScroll(); 643 644 self.cancelEvent(e); 645 646 if (dbl) { 647 fn = (hr) ? self.doScrollLeft : self.doScrollTop; 648 cur = (hr) ? ((e.pageX - self.railh.offset().left - (self.cursorwidth/2)) *
648self.scrollratio.x) : ((e.pageY - self.rail.offset().top - (self.cursorheight/2)) * self.scrollratio.y); 649 fn(cur); 650 } else { 651// console.log(e.pageY); 652 fn = (hr) ? self.doScrollLeftBy : self.doScrollBy; 653 cur = (hr) ? self.scroll.x : self.scroll.y; 654 pos = (hr) ? e.pageX - self.railh.offset().left : e.pageY - self.rail.offset().top; 655 pg = (hr) ? self.view.w : self.view.h; 656 (cur>=pos) ? fn(pg) : fn(-pg); 657 } 658 659 } 660 661 self.hasanimationframe = (setAnimationFrame); 662 self.hascancelanimationframe = (clearAnimationFrame); 663 664 if (!self.hasanimationframe) { 665 setAnimationFrame=function(fn){return setTimeout(fn,15-Math.floor((+new Date)/1000)%16)}; // 1000/60)}; 666 clearAnimationFrame=clearInterval; 667 } 668 else if (!self.hascancelanimationframe) clearAnimationFrame=function(){self.cancelAnimationFrame=true}; 669 670 this.init = function() { 671 672 self.saved.css = []; 673 674 if (cap.isie7mobile) return true; // SORRY, DO NOT WORK! 675 676 if (cap.hasmstouch) self.css((self.ispage)?$("html"):self.win,{'-ms-touch-action':'none'}); 677 678 self.zindex = "auto"; 679 if (!self.ispage&&self.opt.zindex=="auto") { 680 self.zindex = getZIndex()||"auto"; 681 } else { 682 self.zindex = self.opt.zindex; 683 } 684 685 if (!self.ispage&&self.zindex!="auto") { 686 if (self.zindex>globalmaxzindex) globalmaxzindex=self.zindex; 687 } 688 689 if (self.isie&&self.zindex==0&&self.opt.zindex=="auto") { // fix IE auto == 0 690 self.zindex="auto"; 691 } 692 693/* 694 self.ispage = true; 695 self.haswrapper = true; 696// self.win = $(window); 697 self.docscroll = $("body"); 698// self.doc = $("body"); 699*/ 700 701 if (!self.ispage || (!cap.cantouch && !cap.isieold && !cap.isie9mobile)) { 702 703 var cont = self.docscroll; 704 if (self.ispage) cont = (self.haswrapper)?self.win:self.doc; 705 706 if (!cap.isie9mobile) self.css(cont,{'overflow-y':'hidden'}); 707 708 if (self.ispage&&cap.isie7) { 709 if (self.doc[0].nodeName=='BODY') self.css($("html"),{'overflow-y':'hidden'}); //IE7 double scrollbar issue 710 else if (self.doc[0].nodeName=='HTML') self.css($("body"),{'overflow-y':'hidden'}); //IE7 double scrollbar issue 711 } 712 713 if (cap.isios&&!self.ispage&&!self.haswrapper) self.css($("body"),{"-webkit-overflow-scrolling":"touch"}); //force hw acceleration 714 715 var cursor = $(document.createElement('div')); 716 cursor.css({ 717 position:"relative",top:0,"float":"right",width:self.opt.cursorwidth,height:"0px", 718 'background-color':self.opt.cursorcolor, 719 border:self.opt.cursorborder, 720 'background-clip':'padding-box', 721 '-webkit-border-radius':self.opt.cursorborderradius, 722 '-moz-border-radius':self.opt.cursorborderradius, 723 'border-radius':self.opt.cursorborderradius 724 }); 725 726 cursor.hborder = parseFloat(cursor.outerHeight() - cursor.innerHe
726ight()); 727 self.cursor = cursor; 728 729 var rail = $(document.createElement('div')); 730 rail.attr('id',self.id); 731 rail.addClass('nicescroll-rails'); 732 733 var v,a,kp = ["left","right"]; //"top","bottom" 734 for(var n in kp) { 735 a=kp[n]; 736 v = self.opt.railpadding[a]; 737 (v) ? rail.css("padding-"+a,v+"px") : self.opt.railpadding[a] = 0; 738 } 739 740 rail.append(cursor); 741 742 rail.width = Math.max(parseFloat(self.opt.cursorwidth),cursor.outerWidth()) + self.opt.railpadding['left'] + self.opt.railpadding['right']; 743 rail.css({width:rail.width+"px",'zIndex':self.zindex,"background":self.opt.background,cursor:"default"}); 744 745 rail.visibility = true; 746 rail.scrollable = true; 747 748 rail.align = (self.opt.railalign=="left") ? 0 : 1; 749 750 self.rail = rail; 751 752 self.rail.drag = false; 753 754 var zoom = false; 755 if (self.opt.boxzoom&&!self.ispage&&!cap.isieold) { 756 zoom = document.createElement('div'); 757 self.bind(zoom,"click",self.doZoom); 758 self.zoom = $(zoom); 759 self.zoom.css({"cursor":"pointer",'z-index':self.zindex,'backgroundImage':'url('+scriptpath+'zoomico.png)','height':18,'width':18,'backgroundPosition':'0px 0px'}); 760 if (self.opt.dblclickzoom) self.bind(self.win,"dblclick",self.doZoom); 761 if (cap.cantouch&&self.opt.gesturezoom) { 762 self.ongesturezoom = function(e) { 763 if (e.scale>1.5) self.doZoomIn(e); 764 if (e.scale<0.8) self.doZoomOut(e); 765 return self.cancelEvent(e); 766 }; 767 self.bind(self.win,"gestureend",self.ongesturezoom); 768 } 769 } 770 771// init HORIZ 772 773 self.railh = false; 774 775 if (self.opt.horizrailenabled) { 776 777 self.css(cont,{'overflow-x':'hidden'}); 778 779 var cursor = $(document.createElement('div')); 780 cursor.css({ 781 position:"relative",top:0,height:self.opt.cursorwidth,width:"0px", 782 'background-color':self.opt.cursorcolor, 783 border:self.opt.cursorborder, 784 'background-clip':'padding-box', 785 '-webkit-border-radius':self.opt.cursorborderradius, 786 '-moz-border-radius':self.opt.cursorborderradius, 787 'border-radius':self.opt.cursorborderradius 788 }); 789 790 cursor.wborder = parseFloat(cursor.outerWidth() - cursor.innerWidth()); 791 self.cursorh = cursor; 792 793 var railh = $(document.createElement('div')); 794 railh.attr('id',self.id+'-hr'); 795 railh.addClass('nicescroll-rails'); 796 railh.height = Math.max(parseFloat(self.opt.cursorwidth),cursor.outerHeight()); 797 railh.css({height:railh.height+"px",'zIndex':self.zindex,"background":self.opt.background}); 798 799 railh.append(cursor); 800 801 railh.visibility = true; 802 railh.scrollable = true; 803 804 railh.align = (self.opt.railvalign=="top") ? 0 : 1; 805 806 self.railh = railh; 807 808 self.railh.drag = false; 809 810 } 811 812// 813 814 if (self.ispage) { 815 rail.css({position:"fixed",top:"0px",height:"100%"}); 816 (rail.align) ? rail.css({right:"0px"}) : rail.css({left:"0px"}); 817 self.body.append(rail); 818 if (self.railh) { 819 railh.css({position:"fixed",left:"0px",width:"100%"}); 820 (railh.align) ? railh.css({bottom:"0px"}) : railh.css({top:"0px"}); 821 self.body.append(railh); 822 } 823 } else { 824 if (self.ishwscroll) { 825 if (self.win.css('position')=='static') self.css(self.win,{'position':'relative'}); 826 var bd = (self.win[0].nodeName == 'HTML') ? self.body : self.win; 827 if (self.zoom) { 828 self.zoom.css({position:"absolute",top:1,right:0,"margin-right":rail.width+4}); 829 bd.append(self.zoom); 830 } 831 rail.css({position:"absolute",top:0}); 832 (rail.align) ? rail.css({right:0}) : rail.css({left:0}); 833 bd.append(rail); 834 if (railh) { 835 railh.css({position:"absolute",left:0,bottom:0}); 836 (railh.align) ? railh.css({bottom:0}) : railh.css({top:0}); 837 bd.append(railh); 838 } 839 } else { 840 self.isfixed = (self.win.css("position")=="fixed"); 841 var rlpos = (self.isfixed) ? "fixed" : "absolute"; 842 843 if (!self.isfixed) self.viewport = self.getViewport(self.win[0]); 844 if (self.viewport) { 845 self.body = self.viewport; 846 if ((/relative|absolute/.test(self.viewport.css("position")))==false) self.css(self.viewport,{"position":"relative"}); 847 } 848 849 rail.css({position:rlpos}); 850 if (self.zoom) self.zoom.css({position:rlpos}); 851 self.updateScrollBar(); 852 self.body.append(rail); 853 if (self.zoom) self.body.append(self.zoom); 854 if (self.railh) { 855 railh.css({position:rlpos}); 856 self.body.append(railh); 857 } 858 } 859 860 if (cap.isios) self.css(self.win,{'-webkit-tap-highlight-color':'rgba(0,0,0,0)','-webkit-touch-callout':'none'}); // prevent grey layer on click 861 862 if (cap.isie&&self.opt.disableoutline) self.win.attr("hideFocus","true"); // IE, prevent dotted rectangle on focused div 863 if (cap.iswebkit&&self.opt.disableoutline) self.win.css({"outline":"none"}); 864 865 } 866 867 if (self.opt.autohidemode===false) { 868 self.autohidedom = false;
869 self.rail.css({opacity:self.opt.cursoropacitymax}); 870 if (self.railh) self.railh.css({opacity:self.opt.cursoropacitymax}); 871 } 872 else if (self.opt.autohidemode===true) { 873 self.autohidedom = $().add(self.rail); 874 if (cap.isie8) self.autohidedom=self.autohidedom.add(self.cursor); 875 if (self.railh) self.autohidedom=self.autohidedom.add(self.railh); 876 if (self.railh&&cap.isie8) self.autohidedom=self.autohidedom.add(self.cursorh); 877 } 878 else if (self.opt.autohidemode=="scroll") { 879 self.autohidedom = $().add(self.rail); 880 if (self.railh) self.autohidedom=self.autohidedom.add(self.railh); 881 } 882 else if (self.opt.autohidemode=="cursor") { 883 self.autohidedom = $().add(self.cursor); 884 if (self.railh) self.autohidedom=self.autohidedom.add(self.cursorh); 885 } 886 else if (self.opt.autohidemode=="hidden") { 887 self.autohidedom = false; 888 self.hide(); 889 self.locked = false; 890 } 891 892 if (cap.isie9mobile) { 893 894 self.scrollmom = new ScrollMomentumClass2D(self); 895 896 /* 897 var trace = function(msg) { 898 var db = $("#debug"); 899 if (isNaN(msg)&&(typeof msg != "string")) { 900 var x = []; 901 for(var a in msg) { 902 x.push(a+":"+msg[a]); 903 } 904 msg ="{"+x.join(",")+"}"; 905 } 906 if (db.children().length>0) { 907 db.children().eq(0).before("<div>"+msg+"</div>"); 908 } else { 909 db.append("<div>"+msg+"</div>"); 910 } 911 } 912 window.onerror = function(msg,url,ln) { 913 trace("ERR: "+msg+" at "+ln); 914 } 915*/ 916 917 self.onmangotouch = function(e) { 918 var py = self.getScrollTop(); 919 var px = self.getScrollLeft(); 920 921 if ((py == self.scrollmom.lastscrolly)&&(px == self.scrollmom.lastscrollx)) return true; 922// $("#debug").html('DRAG:'+py); 923 924 var dfy = py-self.mangotouch.sy; 925 var dfx = px-self.mangotouch.sx; 926 var df = Math.round(Math.sqrt(Math.pow(dfx,2)+Math.pow(dfy,2))); 927 if (df==0) return; 928 929 var dry = (dfy<0)?-1:1; 930 var drx = (dfx<0)?-1:1; 931 932 var tm = +new Date(); 933 if (self.mangotouch.lazy) clearTimeout(self.mangotouch.lazy); 934 935 if (((tm-self.mangotouch.tm)>80)||(self.mangotouch.dry!=dry)||(self.mangotouch.drx!=drx)) { 936// trace('RESET+'+(tm-self.mangotouch.tm)); 937 self.scrollmom.stop(); 938 self.scrollmom.reset(px,py); 939 self.mangotouch.sy = py; 940 self.mangotouch.ly = py; 941 self.mangotouch.sx = px; 942 self.mangotouch.lx = px; 943 self.mangotouch.dry = dry; 944 self.mangotouch.drx = drx; 945 self.mangotouch.tm = tm; 946 } else { 947 948 self.scrollmom.stop(); 949 self.scrollmom.update(self.mangotouch.sx-dfx,self.mangotouch.sy-dfy); 950 var gap = tm - self.mangotouch.tm; 951 self.mangotouch.tm = tm; 952 953// trace('MOVE:'+df+" - "+gap); 954 955 var ds = Math.max(Math.abs(self.mangotouch.ly-py),Math.abs(self.mangotouch.lx-px)); 956 self.mangotouch.ly = py; 957 self.mangotouch.lx = px; 958 959 if (ds>2) { 960 self.mangotouch.lazy = setTimeout(function(){ 961// trace('END:'+ds+'+'+gap); 962 self.mangotouch.lazy = false; 963 self.mangotouch.dry = 0; 964 self.mangotouch.drx = 0; 965 self.mangotouch.tm = 0; 966 self.scrollmom.doMomentum(30); 967 },100); 968 } 969 } 970 } 971 972 var top = self.getScrollTop(); 973 var lef = self.getScrollLeft(); 974 self.mangotouch = {sy:top,ly:top,dry:0,sx:lef,lx:lef,drx:0,lazy:false,tm:0}; 975 976 self.bind(self.docscroll,"scroll",self.onmangotouch); 977 978 } else { 979 980 if (cap.cantouch||self.istouchcapable||self.opt.touchbehavior||cap.hasmstouch) { 981 982 self.scrollmom = new ScrollMomentumClass2D(self); 983 984 self.ontouchstart = function(e) { 985 if (e.pointerType&&e.pointerType!=2) return false;
986 987 if (!self.locked) { 988 989 if (cap.hasmstouch) { 990 var tg = (e.target) ? e.target : false; 991 while (tg) { 992 var nc = $(tg).getNiceScroll(); 993 if ((nc.length>0)&&(nc[0].me == self.me)) break; 994 if (nc.length>0) return false; 995 if ((tg.nodeName=='DIV')&&(tg.id==self.id)) break; 996 tg = (tg.parentNode) ? tg.parentNode : false; 997 } 998 } 999 1000 self.cancelScroll(); 1001 1002 var tg = self.getTarget(e); 1003 1004 if (tg) { 1005 var skp = (/INPUT/i.test(tg.nodeName))&&(/range/i.test(tg.type)); 1006 if (skp) return self.stopPropagation(e); 1007 } 1008 1009 if (!("clientX" in e) && ("changedTouches" in e)) { 1010 e.clientX = e.changedTouches[0].clientX; 1011 e.clientY = e.changedTouches[0].clientY; 1012 } 1013 1014 if (self.forcescreen) { 1015 var le = e; 1016 var e = {"original":(e.original)?e.original:e}; 1017 e.clientX = le.screenX; 1018 e.clientY = le.screenY; 1019 } 1020 1021 self.rail.drag = {x:e.clientX,y:e.clientY,sx:self.scroll.x,sy:self.scroll.y,st:self.getScrollTop(),sl:self.getScrollLeft(),pt:2,dl:false}; 1022 1023 if (self.ispage||!self.opt.directionlockdeadzone) { 1024 self.rail.drag.dl = "f"; 1025 } else { 1026 1027 var view = { 1028 w:$(window).width(), 1029 h:$(window).height() 1030 }; 1031 1032 var page = { 1033 w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth), 1034 h:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight) 1035 } 1036 1037 var maxh = Math.max(0,page.h - view.h); 1038 var maxw = Math.max(0,page.w - view.w); 1039 1040 if (!self.rail.scrollable&&self.railh.scrollable) self.rail.drag.ck = (maxh>0) ? "v" : false; 1041 else if (self.rail.scrollable&&!self.railh.scrollable) self.rail.drag.ck = (maxw>0) ? "h" : false; 1042 else self.rail.drag.ck = false; 1043 if (!self.rail.drag.ck) self.rail.drag.dl = "f"; 1044 } 1045 1046 if (self.opt.touchbehavior&&self.isiframe&&cap.isie) { 1047 var wp = self.win.position(); 1048 self.rail.drag.x+=wp.left; 1049 self.rail.drag.y+=wp.top; 1050 } 1051 1052 self.hasmoving = false; 1053 self.lastmouseup = false; 1054 self.scrollmom.reset(e.clientX,e.clientY); 1055 if (!cap.cantouch&&!this.istouchcapable&&!cap.hasmstouch) { 1056 1057 var ip = (tg)?/INPUT|SELECT|TEXTAREA/i.test(tg.nodeName):false; 1058 if (!ip) { 1059 if (!self.ispage&&cap.hasmousecapture) tg.setCapture(); 1060 return self.cancelEvent(e); 1061 } 1062 if (/SUBMIT|CANCEL|BUTTON/i.test($(tg).attr('type'))) { 1063 pc = {"tg":tg,"click":false}; 1064 self.preventclick = pc; 1065 } 1066 1067 } 1068 } 1069 1070 }; 1071 1072 self.ontouchend = function(e) { 1073 if (e.pointerType&&e.pointerType!=2) return false; 1074 if (self.rail.drag&&(self.rail.drag.pt==2)) { 1075 self.scrollmom.doMomentum(); 1076 self.rail.drag = false; 1077 if (self.hasmoving) { 1078 self.hasmoving = false; 1079 self.lastmouseup = true; 1080 self.hideCursor(); 1081 if (cap.hasmousecapture) document.releaseCapture(); 1082 if (!cap.cantouch) return self.cancelEvent(e); 1083 } 1084 } 1085 1086 }; 1087 1088 var moveneedoffset = (self.opt.touchbehavior&&self.isiframe&&!cap.hasmousecapture); 1089 1090 self.ontouchmove = function(e,byiframe) { 1091 1092 if (e.pointerType&&e.pointerType!=2) return false;
1093 1094 if (self.rail.drag&&(self.rail.drag.pt==2)) { 1095 if (cap.cantouch&&(typeof e.original == "undefined")) return true; // prevent ios "ghost" events by clickable elements 1096 1097 self.hasmoving = true; 1098 1099 if (self.preventclick&&!self.preventclick.click) { 1100 self.preventclick.click = self.preventclick.tg.onclick||false; 1101 self.preventclick.tg.onclick = self.onpreventclick; 1102 } 1103 1104 var ev = $.extend({"original":e},e); 1105 e = ev; 1106 1107 if (("changedTouches" in e)) { 1108 e.clientX = e.changedTouches[0].clientX; 1109 e.clientY = e.changedTouches[0].clientY; 1110 } 1111 1112 if (self.forcescreen) { 1113 var le = e; 1114 var e = {"original":(e.original)?e.original:e}; 1115 e.clientX = le.screenX; 1116 e.clientY = le.screenY; 1117 } 1118 1119 var ofx = ofy = 0; 1120 1121 if (moveneedoffset&&!byiframe) { 1122 var wp = self.win.position(); 1123 ofx=-wp.left; 1124 ofy=-wp.top; 1125 } 1126 1127 var fy = e.clientY + ofy; 1128 var my = (fy-self.rail.drag.y); 1129 var fx = e.clientX + ofx; 1130 var mx = (fx-self.rail.drag.x); 1131 1132 var ny = self.rail.drag.st-my; 1133 1134 if (self.ishwscroll&&self.opt.bouncescroll) { 1135 if (ny<0) { 1136 ny = Math.round(ny/2); 1137// fy = 0; 1138 } 1139 else if (ny>self.page.maxh) { 1140 ny = self.page.maxh+Math.round((ny-self.page.maxh)/2); 1141// fy = 0; 1142 } 1143 } else { 1144 if (ny<0) {ny=0;fy=0} 1145 if (ny>self.page.maxh) {ny=self.page.maxh;fy=0} 1146 } 1147 1148 if (self.railh&&self.railh.scrollable) { 1149 var nx = self.rail.drag.sl-mx; 1150 1151 if (self.ishwscroll&&self.opt.bouncescroll) { 1152 if (nx<0) { 1153 nx = Math.round(nx/2); 1154// fx = 0; 1155 } 1156 else if (nx>self.page.maxw) { 1157 nx = self.page.maxw+Math.round((nx-self.page.maxw)/2); 1158// fx = 0; 1159 } 1160 } else { 1161 if (nx<0) {nx=0;fx=0} 1162 if (nx>self.page.maxw) {nx=self.page.maxw;fx=0} 1163 } 1164 1165 } 1166 1167 var grabbed = false; 1168 if (self.rail.drag.dl) { 1169 grabbed = true; 1170 if (self.rail.drag.dl=="v") nx = self.rail.drag.sl; 1171 else if (self.rail.drag.dl=="h") ny = self.rail.drag.st; 1172 } else { 1173 var ay = Math.abs(my); 1174 var ax = Math.abs(mx); 1175 var dz = self.opt.directionlockdeadzone; 1176 if (self.rail.drag.ck=="v") { 1177 if (ay>dz&&(ax<=(ay*0.3))) { 1178 self.rail.drag = false; 1179 return true; 1180 } 1181 else if (ax>dz) { 1182 self.rail.drag.dl="f"; 1183 $("body").scrollTop($("body").scrollTop()); // stop iOS native scrolling (when active javascript has blocked) 1184 } 1185 } 1186 else if (self.rail.drag.ck=="h") { 1187 if (ax>dz&&(ay<=(az*0.3))) { 1188 self.rail.drag = false; 1189 return true; 1190 } 1191 else if (ay>dz) { 1192 self.rail.drag.dl="f"; 1193 $("body").scrollLeft($("body").scrollLeft()); // stop iOS native scrolling (when active javascript has blocked) 1194 } 1195 } 1196 } 1197 1198 self.synched("touchmove",function(){ 1199 if (self.rail.drag&&(self.rail.drag.pt==2)) { 1200 if (self.prepareTransition) self.prepareTransition(0); 1201 if (self.rail.scrollable) self.setScrollTop(ny); 1202 self.scrollmom.update(fx,fy); 1203 if (self.railh&&self.railh.scrollable) { 1204 self.setScrollLeft(nx); 1205 self.showCursor(ny,nx); 1206 } else { 1207 self.showCursor(ny); 1208 } 1209 if (cap.isie10) document.selection.clear(); 1210 } 1211 }); 1212 1213 if (cap.ischrome&&self.istouchcapable) grabbed=false; //chrome touch emulation doesn't like! 1214 if (grabbed) return self.cancelEvent(e); 1215 } 1216 1217 }; 1218 1219 } 1220
1221 self.onmousedown = function(e,hronly) { 1222 if (self.rail.drag&&self.rail.drag.pt!=1) return; 1223 if (self.locked) return self.cancelEvent(e); 1224 self.cancelScroll(); 1225 self.rail.drag = {x:e.clientX,y:e.clientY,sx:self.scroll.x,sy:self.scroll.y,pt:1,hr:(!!hronly)}; 1226 var tg = self.getTarget(e); 1227 if (!self.ispage&&cap.hasmousecapture) tg.setCapture(); 1228 if (self.isiframe&&!cap.hasmousecapture) { 1229 self.saved["csspointerevents"] = self.doc.css("pointer-events"); 1230 self.css(self.doc,{"pointer-events":"none"}); 1231 } 1232 return self.cancelEvent(e); 1233 }; 1234 1235 self.onmouseup = function(e) { 1236 if (self.rail.drag) { 1237 if (cap.hasmousecapture) document.releaseCapture(); 1238 if (self.isiframe&&!cap.hasmousecapture) self.doc.css("pointer-events",self.saved["csspointerevents"]); 1239 if(self.rail.drag.pt!=1)return; 1240 self.rail.drag = false; 1241 //if (!self.rail.active) self.hideCursor(); 1242 return self.cancelEvent(e); 1243 } 1244 }; 1245 1246 self.onmousemove = function(e) { 1247 if (self.rail.drag) { 1248 if(self.rail.drag.pt!=1)return; 1249 1250 if (cap.ischrome&&e.which==0) return self.onmouseup(e); 1251 1252 self.cursorfreezed = true; 1253 1254 if (self.rail.drag.hr) { 1255 self.scroll.x = self.rail.drag.sx + (e.clientX-self.rail.drag.x); 1256 if (self.scroll.x<0) self.scroll.x=0; 1257 var mw = self.scrollvaluemaxw; 1258 if (self.scroll.x>mw) self.scroll.x=mw; 1259 } else { 1260 self.scroll.y = self.rail.drag.sy + (e.clientY-self.rail.drag.y); 1261 if (self.scroll.y<0) self.scroll.y=0; 1262 var my = self.scrollvaluemax; 1263 if (self.scroll.y>my) self.scroll.y=my; 1264 } 1265 1266 self.synched('mousemove',function(){ 1267 if (self.rail.drag&&(self.rail.drag.pt==1)) { 1268 self.showCursor(); 1269 if (self.rail.drag.hr) self.doScrollLeft(Math.round(self.scroll.x*self.scrollratio.x),self.opt.cursordragspeed); 1270 else self.doScrollTop(Math.round(self.scroll.y*self.scrollratio.y),self.opt.cursordragspeed); 1271 } 1272 }); 1273 1274 return self.cancelEvent(e); 1275 } 1276/* 1277 else { 1278 self.checkarea = true; 1279 } 1280*/ 1281 }; 1282 1283 if (cap.cantouch||self.opt.touchbehavior) { 1284 1285 self.onpreventclick = function(e) { 1286 if (self.preventclick) { 1287 self.preventclick.tg.onclick = self.preventclick.click; 1288 self.preventclick = false; 1289 return self.cancelEvent(e); 1290 } 1291 } 1292 1293// self.onmousedown = self.ontouchstart; 1294// self.onmouseup = self.ontouchend; 1295// self.onmousemove = self.ontouchmove; 1296 1297 self.bind(self.win,"mousedown",self.ontouchstart); // control content dragging 1298 1299 self.onclick = (cap.isios) ? false : function(e) { 1300 if (self.lastmouseup) { 1301 self.lastmouseup = false; 1302 return self.cancelEvent(e); 1303 } else { 1304 return true; 1305 } 1306 }; 1307 1308 if (self.opt.grabcursorenabled&&cap.cursorgrabvalue) { 1309 self.css((self.ispage)?self.doc:self.win,{'cursor':cap.cursorgrabvalue}); 1310 self.css(self.rail,{'cursor':cap.cursorgrabvalue}); 1311 } 1312 1313 } else { 1314 1315 function checkSelectionScroll(e) { 1316 if (!self.selectiondrag) return; 1317 1318 if (e) { 1319 var ww = self.win.outerHeight();
1320 var df = (e.pageY - self.selectiondrag.top); 1321 if (df>0&&df<ww) df=0; 1322 if (df>=ww) df-=ww; 1323 self.selectiondrag.df = df; 1324 } 1325 if (self.selectiondrag.df==0) return; 1326 1327 var rt = -Math.floor(self.selectiondrag.df/6)*2; 1328// self.doScrollTop(self.getScrollTop(true)+rt); 1329 self.doScrollBy(rt); 1330 1331 self.debounced("doselectionscroll",function(){checkSelectionScroll()},50); 1332 } 1333 1334 if ("getSelection" in document) { // A grade - Major browsers 1335 self.hasTextSelected = function() { 1336 return (document.getSelection().rangeCount>0); 1337 } 1338 } 1339 else if ("selection" in document) { //IE9- 1340 self.hasTextSelected = function() { 1341 return (document.selection.type != "None"); 1342 } 1343 } 1344 else { 1345 self.hasTextSelected = function() { // no support 1346 return false; 1347 } 1348 } 1349 1350 self.onselectionstart = function(e) { 1351 if (self.ispage) return; 1352 self.selectiondrag = self.win.offset(); 1353 } 1354 self.onselectionend = function(e) { 1355 self.selectiondrag = false; 1356 } 1357 self.onselectiondrag = function(e) { 1358 if (!self.selectiondrag) return; 1359 if (self.hasTextSelected()) self.debounced("selectionscroll",function(){checkSelectionScroll(e)},250); 1360 } 1361 1362 1363 } 1364 1365 if (cap.hasmstouch) { 1366 self.css(self.rail,{'-ms-touch-action':'none'}); 1367 self.css(self.cursor,{'-ms-touch-action':'none'}); 1368 1369 self.bind(self.win,"MSPointerDown",self.ontouchstart); 1370 self.bind(document,"MSPointerUp",self.ontouchend); 1371 self.bind(document,"MSPointerMove",self.ontouchmove); 1372 self.bind(self.cursor,"MSGestureHold",function(e){e.preventDefault()}); 1373 self.bind(self.cursor,"contextmenu",function(e){e.preventDefault()}); 1374 } 1375 1376 if (this.istouchcapable) { //desktop with screen touch enabled 1377 self.bind(self.win,"touchstart",self.ontouchstart); 1378 self.bind(document,"touchend",self.ontouchend); 1379 self.bind(document,"touchcancel",self.ontouchend); 1380 self.bind(document,"touchmove",self.ontouchmove); 1381 } 1382 1383 self.bind(self.cursor,"mousedown",self.onmousedown); 1384 self.bind(self.cursor,"mouseup",self.onmouseup); 1385 1386 if (self.railh) { 1387 self.bind(self.cursorh,"mousedown",function(e){self.onmousedown(e,true)}); 1388 self.bind(self.cursorh,"mouseup",function(e){ 1389 if (self.rail.drag&&self.rail.drag.pt==2) return; 1390 self.rail.drag = false; 1391 self.hasmoving = false; 1392 self.hideCursor(); 1393 if (cap.hasmousecapture) document.releaseCapture(); 1394 return self.cancelEvent(e); 1395 }); 1396 } 1397 1398 if (self.opt.cursordragontouch||!cap.cantouch&&!self.opt.touchbehavior) { 1399 1400 self.rail.css({"cursor":"default"}); 1401 self.railh&&self.railh.css({"cursor":"default"}); 1402 1403 self.jqbind(self.rail,"mouseenter",function() { 1404 if (self.canshowonmouseevent) self.showCursor(); 1405 self.rail.active = true; 1406 }); 1407 self.jqbind(self.rail,"mouseleave",function() { 1408 self.rail.active = false; 1409 if (!self.rail.drag) self.hideCursor(); 1410 }); 1411 1412 if (self.opt.sensitiverail) { 1413 self.bind(self.rail,"click",function(e){self.doRailClick(e,false,false)}); 1414 self.bind(self.rail,"dblclick",function(e){self.doRailClick(e,true,false)}); 1415 self.bind(self.cursor,"click",function(e){self.cancelEvent(e)}); 1416 self.bind(self.cursor,"dblclick",function(e){self.cancelEvent(e)}); 1417 } 1418 1419 if (self.railh) { 1420 self.jqbind(self.railh,"mouseenter",function() { 1421 if (self.canshowonmouseevent) self.showCursor(); 1422 self.rail.active = true; 1423 }); 1424 self.jqbind(self.railh,"mouseleave",function() { 1425 self.rail.active = false;
1426 if (!self.rail.drag) self.hideCursor(); 1427 }); 1428 1429 if (self.opt.sensitiverail) { 1430 self.bind(self.railh, "click", function(e){self.doRailClick(e,false,true)}); 1431 self.bind(self.railh, "dblclick", function(e){self.doRailClick(e, true, true) }); 1432 self.bind(self.cursorh, "click", function (e) { self.cancelEvent(e) }); 1433 self.bind(self.cursorh, "dblclick", function (e) { self.cancelEvent(e) }); 1434 } 1435 1436 } 1437 1438 } 1439 1440 if (!cap.cantouch&&!self.opt.touchbehavior) { 1441 1442 self.bind((cap.hasmousecapture)?self.win:document,"mouseup",self.onmouseup); 1443 self.bind(document,"mousemove",self.onmousemove); 1444 if (self.onclick) self.bind(document,"click",self.onclick); 1445 1446 if (!self.ispage&&self.opt.enablescrollonselection) { 1447 self.bind(self.win[0],"mousedown",self.onselectionstart); 1448 self.bind(document,"mouseup",self.onselectionend); 1449 self.bind(self.cursor,"mouseup",self.onselectionend); 1450 if (self.cursorh) self.bind(self.cursorh,"mouseup",self.onselectionend); 1451 self.bind(document,"mousemove",self.onselectiondrag); 1452 } 1453 1454 if (self.zoom) { 1455 self.jqbind(self.zoom,"mouseenter",function() { 1456 if (self.canshowonmouseevent) self.showCursor(); 1457 self.rail.active = true; 1458 }); 1459 self.jqbind(self.zoom,"mouseleave",function() { 1460 self.rail.active = false; 1461 if (!self.rail.drag) self.hideCursor(); 1462 }); 1463 } 1464 1465 } else { 1466 1467 self.bind((cap.hasmousecapture)?self.win:document,"mouseup",self.ontouchend); 1468 self.bind(document,"mousemove",self.ontouchmove); 1469 if (self.onclick) self.bind(document,"click",self.onclick); 1470 1471 if (self.opt.cursordragontouch) { 1472 self.bind(self.cursor,"mousedown",self.onmousedown); 1473 self.bind(self.cursor,"mousemove",self.onmousemove); 1474 self.cursorh&&self.bind(self.cursorh,"mousedown",self.onmousedown); 1475 self.cursorh&&self.bind(self.cursorh,"mousemove",self.onmousemove); 1476 } 1477 1478 } 1479 1480 if (self.opt.enablemousewheel) { 1481 if (!self.isiframe) self.bind((cap.isie&&self.ispage) ? document : self.docscroll,"mousewheel",self.onmousewheel); 1482 self.bind(self.rail,"mousewheel",self.onmousewheel); 1483 if (self.railh) self.bind(self.railh,"mousewheel",self.onmousewheelhr); 1484 } 1485 1486 if (!self.ispage&&!cap.cantouch&&!(/HTML|BODY/.test(self.win[0].nodeName))) { 1487 if (!self.win.attr("tabindex")) self.win.attr({"tabindex":tabindexcounter++}); 1488 1489 self.jqbind(self.win,"focus",function(e) { 1490 domfocus = (self.getTarget(e)).id||true; 1491 self.hasfocus = true; 1492 if (self.canshowonmouseevent) self.noticeCursor(); 1493 }); 1494 self.jqbind(self.win,"blur",function(e) { 1495 domfocus = false; 1496 self.hasfocus = false; 1497 }); 1498 1499 self.jqbind(self.win,"mouseenter",function(e) { 1500 mousefocus = (self.getTarget(e)).id||true; 1501 self.hasmousefocus = true; 1502 if (self.canshowonmouseevent) self.noticeCursor(); 1503 }); 1504 self.jqbind(self.win,"mouseleave",function() { 1505 mousefocus = false; 1506 self.hasmousefocus = false; 1507 }); 1508 1509 }; 1510 1511 } // !ie9mobile 1512 1513 //Thanks to http://www.quirksmode.org !! 1514 self.onkeypress = function(e) { 1515 if (self.locked&&self.page.maxh==0) return true; 1516 1517 e = (e) ? e : window.e; 1518 var tg = self.getTarget(e); 1519 if (tg&&/INPUT|TEXTAREA|SELECT|OPTION/.test(tg.nodeName)) { 1520 var tp = tg.getAttribute('type')||tg.type||false; 1521 if ((!tp)||!(/submit|button|cancel/i.tp)) return true; 1522 } 1523 1524 if (self.hasfocus||(self.hasmousefocus&&!domfocus)||(self.ispage&&!domfocus&&!mousefocus)) { 1525 var key = e.keyCode; 1526 1527 if (self.locked&&key!=27) return self.cancelEvent(e); 1528 1529 var ctrl = e.ctrlKey||false; 1530 var shift = e.shiftKey || false; 1531 1532 var ret = false;
1533 switch (key) { 1534 case 38: 1535 case 63233: //safari 1536 self.doScrollBy(24*3); 1537 ret = true; 1538 break; 1539 case 40: 1540 case 63235: //safari 1541 self.doScrollBy(-24*3); 1542 ret = true; 1543 break; 1544 case 37: 1545 case 63232: //safari 1546 if (self.railh) { 1547 (ctrl) ? self.doScrollLeft(0) : self.doScrollLeftBy(24*3); 1548 ret = true; 1549 } 1550 break; 1551 case 39: 1552 case 63234: //safari 1553 if (self.railh) { 1554 (ctrl) ? self.doScrollLeft(self.page.maxw) : self.doScrollLeftBy(-24*3); 1555 ret = true; 1556 } 1557 break; 1558 case 33: 1559 case 63276: // safari 1560 self.doScrollBy(self.view.h); 1561 ret = true; 1562 break; 1563 case 34: 1564 case 63277: // safari 1565 self.doScrollBy(-self.view.h); 1566 ret = true; 1567 break; 1568 case 36: 1569 case 63273: // safari 1570 (self.railh&&ctrl) ? self.doScrollPos(0,0) : self.doScrollTo(0); 1571 ret = true; 1572 break; 1573 case 35: 1574 case 63275: // safari 1575 (self.railh&&ctrl) ? self.doScrollPos(self.page.maxw,self.page.maxh) : self.doScrollTo(self.page.maxh); 1576 ret = true; 1577 break; 1578 case 32: 1579 if (self.opt.spacebarenabled) { 1580 (shift) ? self.doScrollBy(self.view.h) : self.doScrollBy(-self.view.h); 1581 ret = true; 1582 } 1583 break; 1584 case 27: // ESC 1585 if (self.zoomactive) { 1586 self.doZoom(); 1587 ret = true; 1588 } 1589 break; 1590 } 1591 if (ret) return self.cancelEvent(e); 1592 } 1593 }; 1594 1595 if (self.opt.enablekeyboard) self.bind(document,(cap.isopera&&!cap.isopera12)?"keypress":"keydown",self.onkeypress); 1596 1597 self.bind(window,'resize',self.lazyResize); 1598 self.bind(window,'orientationchange',self.lazyResize); 1599 1600 self.bind(window,"load",self.lazyResize); 1601 1602 if (cap.ischrome&&!self.ispage&&!self.haswrapper) { //chrome void scrollbar bug - it persists in version 26 1603 var tmp=self.win.attr("style"); 1604 var ww = parseFloat(self.win.css("width"))+1; 1605 self.win.css('width',ww); 1606 self.synched("chromefix",function(){self.win.attr("style",tmp)}); 1607 } 1608 1609 1610// Trying a cross-browser implementation - good luck! 1611 1612 self.onAttributeChange = function(e) { 1613 self.lazyResize(250); 1614 } 1615 1616 if (!self.ispage&&!self.haswrapper) { 1617 // redesigned MutationObserver for Chrome18+/Firefox14+/iOS6+ with support for: remove div, add/remove content 1618 if (clsMutationObserver !== false) { 1619 self.observer = new clsMutationObserver(function(mutations) { 1620 mutations.forEach(self.onAttributeChange); 1621 }); 1622 self.observer.observe(self.win[0],{childList: true, characterData: false, attributes: true, subtree: false}); 1623 1624 self.observerremover = new clsMutationObserver(function(mutations) { 1625 mutations.forEach(function(mo){ 1626 if (mo.removedNodes.length>0) { 1627 for (var dd in mo.removedNodes) { 1628 if (mo.removedNodes[dd]==self.win[0]) return self.remove(); 1629 } 1630 } 1631 }); 1632 }); 1633 self.observerremover.observe(self.win[0].parentNode,{childList: true, characterData: false, attributes: false, subtree: false}); 1634 1635 } else { 1636 self.bind(self.win,(cap.isie&&!cap.isie9)?"propertychange":"DOMAttrModified",self.onAttributeChange); 1637 if (cap.isie9) self.win[0].attachEvent("onpropertychange",self.onAttributeChange); //IE9 DOMAttrModified bug 1638 self.bind(self.win,"DOMNodeRemoved",function(e){ 1639 if (e.target==self.win[0]) self.remove(); 1640 }); 1641 } 1642 } 1643 1644// 1645 1646 if (!self.ispage&&self.opt.boxzoom) self.bind(window,"resize",self.resizeZoom); 1647 if (self.istextarea) self.bind(self.win,"mouseup",self.lazyResize); 1648 1649 self.checkrtlmode = true; 1650 self.lazyResize(30); 1651 1652 } 1653 1654 if (this.doc[0].nodeName == 'IFRAME') { 1655 function oniframeload(e) { 1656 self.iframexd = false;
1657 try { 1658 var doc = 'contentDocument' in this ? this.contentDocument : this.contentWindow.document; 1659 var a = doc.domain; 1660 } catch(e){self.iframexd = true;doc=false}; 1661 1662 if (self.iframexd) { 1663 if ("console" in window) console.log('NiceScroll error: policy restriced iframe'); 1664 return true; //cross-domain - I can't manage this 1665 } 1666 1667 self.forcescreen = true; 1668 1669 if (self.isiframe) { 1670 self.iframe = { 1671 "doc":$(doc), 1672 "html":self.doc.contents().find('html')[0], 1673 "body":self.doc.contents().find('body')[0] 1674 }; 1675 self.getContentSize = function(){ 1676 return { 1677 w:Math.max(self.iframe.html.scrollWidth,self.iframe.body.scrollWidth), 1678 h:Math.max(self.iframe.html.scrollHeight,self.iframe.body.scrollHeight) 1679 } 1680 } 1681 self.docscroll = $(self.iframe.body);//$(this.contentWindow); 1682 } 1683 1684 if (!cap.isios&&self.opt.iframeautoresize&&!self.isiframe) { 1685 self.win.scrollTop(0); // reset position 1686 self.doc.height(""); //reset height to fix browser bug 1687 var hh=Math.max(doc.getElementsByTagName('html')[0].scrollHeight,doc.body.scrollHeight); 1688 self.doc.height(hh); 1689 } 1690 self.lazyResize(30); 1691 1692 if (cap.isie7) self.css($(self.iframe.html),{'overflow-y':'hidden'}); 1693 //self.css($(doc.body),{'overflow-y':'hidden'}); 1694 self.css($(self.iframe.body),{'overflow-y':'hidden'}); 1695 1696 if ('contentWindow' in this) { 1697 self.bind(this.contentWindow,"scroll",self.onscroll); //IE8 & minor 1698 } else { 1699 self.bind(doc,"scroll",self.onscroll); 1700 } 1701 1702 if (self.opt.enablemousewheel) { 1703 self.bind(doc,"mousewheel",self.onmousewheel); 1704 } 1705 1706 if (self.opt.enablekeyboard) self.bind(doc,(cap.isopera)?"keypress":"keydown",self.onkeypress); 1707 1708 if (cap.cantouch||self.opt.touchbehavior) { 1709 self.bind(doc,"mousedown",self.onmousedown); 1710 self.bind(doc,"mousemove",function(e){self.onmousemove(e,true)}); 1711 if (self.opt.grabcursorenabled&&cap.cursorgrabvalue) self.css($(doc.body),{'cursor':cap.cursorgrabvalue}); 1712 } 1713 1714 self.bind(doc,"mouseup",self.onmouseup); 1715 1716 if (self.zoom) { 1717 if (self.opt.dblclickzoom) self.bind(doc,'dblclick',self.doZoom); 1718 if (self.ongesturezoom) self.bind(doc,"gestureend",self.ongesturezoom); 1719 } 1720 }; 1721 1722 if (this.doc[0].readyState&&this.doc[0].readyState=="complete"){ 1723 setTimeout(function(){oniframeload.call(self.doc[0],false)},500); 1724 } 1725 self.bind(this.doc,"load",oniframeload); 1726 1727 } 1728 1729 }; 1730 1731 this.showCursor = function(py,px) { 1732 if (self.cursortimeout) { 1733 clearTimeout(self.cursortimeout); 1734 self.cursortimeout = 0; 1735 } 1736 if (!self.rail) return; 1737 if (self.autohidedom) { 1738 self.autohidedom.stop().css({opacity:self.opt.cursoropacitymax}); 1739 self.cursoractive = true; 1740 } 1741 1742 if (!self.rail.drag||self.rail.drag.pt!=1) { 1743 if ((typeof py != "undefined")&&(py!==false)) { 1744 self.scroll.y = Math.round(py * 1/self.scrollratio.y); 1745 } 1746 if (typeof px != "undefined") { 1747 self.scroll.x = Math.round(px * 1/self.scrollratio.x); 1748 } 1749 } 1750 1751 self.cursor.css({height:self.cursorheight,top:self.scroll.y}); 1752 if (self.cursorh) { 1753 (!self.rail.align&&self.rail.visibility) ? self.cursorh.css({width:self.cursorwidth,left:self.scroll.x+self.rail.width}) : self.cursorh.css({width:self.cursorwidth,left:self.scroll.x}); 1754 self.cursoractive = true; 1755 } 1756 1757 if (self.zoom) self.zoom.stop().css({opacity:self.opt.cursoropacitymax}); 1758 }; 1759 1760 this.hideCursor = function(tm) { 1761 if (self.cursortimeout) return; 1762 if (!self.rail) return; 1763 if (!self.autohidedom) return; 1764 self.cursortimeout = setTimeout(function() { 1765 if (!self.rail.active||!self.showonmouseevent) { 1766 self.autohidedom.stop().animate({opacity:self.opt.cursoropacitymin}); 1767 if (self.zoom) self.zoom.stop().animate({opacity:self.opt.cursoropacitymin}); 1768 self.cursoractive = false;
1769 } 1770 self.cursortimeout = 0; 1771 },tm||self.opt.hidecursordelay); 1772 }; 1773 1774 this.noticeCursor = function(tm,py,px) { 1775 self.showCursor(py,px); 1776 if (!self.rail.active) self.hideCursor(tm); 1777 }; 1778 1779 this.getContentSize = 1780 (self.ispage) ? 1781 function(){ 1782 return { 1783 w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth), 1784 h:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight) 1785 } 1786 } 1787 : (self.haswrapper) ? 1788 function(){ 1789 return { 1790 w:self.doc.outerWidth()+parseInt(self.win.css('paddingLeft'))+parseInt(self.win.css('paddingRight')), 1791 h:self.doc.outerHeight()+parseInt(self.win.css('paddingTop'))+parseInt(self.win.css('paddingBottom')) 1792 } 1793 } 1794 : function() { 1795 return { 1796 w:self.docscroll[0].scrollWidth, 1797 h:self.docscroll[0].scrollHeight 1798 } 1799 }; 1800 1801 this.onResize = function(e,page) { 1802 1803 if (!self.win) return false; 1804 1805 if (!self.haswrapper&&!self.ispage) { 1806 if (self.win.css('display')=='none') { 1807 if (self.visibility) self.hideRail().hideRailHr(); 1808 return false; 1809 } else { 1810 if (!self.hidden&&!self.visibility) self.showRail().showRailHr(); 1811 } 1812 } 1813 1814 var premaxh = self.page.maxh; 1815 var premaxw = self.page.maxw; 1816 1817 var preview = {h:self.view.h,w:self.view.w}; 1818 1819 self.view = { 1820 w:(self.ispage) ? self.win.width() : parseInt(self.win[0].clientWidth), 1821 h:(self.ispage) ? self.win.height() : parseInt(self.win[0].clientHeight) 1822 }; 1823 1824 self.page = (page) ? page : self.getContentSize(); 1825 1826 self.page.maxh = Math.max(0,self.page.h - self.view.h); 1827 self.page.maxw = Math.max(0,self.page.w - self.view.w); 1828 1829 if ((self.page.maxh==premaxh)&&(self.page.maxw==premaxw)&&(self.view.w==preview.w)) { 1830 // test position 1831 if (!self.ispage) { 1832 var pos = self.win.offset(); 1833 if (self.lastposition) { 1834 var lst = self.lastposition; 1835 if ((lst.top==pos.top)&&(lst.left==pos.left)) return self; //nothing to do 1836 } 1837 self.lastposition = pos; 1838 } else { 1839 return self; //nothing to do 1840 } 1841 } 1842 1843 if (self.page.maxh==0) { 1844 self.hideRail(); 1845 self.scrollvaluemax = 0; 1846 self.scroll.y = 0; 1847 self.scrollratio.y = 0; 1848 self.cursorheight = 0; 1849 self.setScrollTop(0); 1850 self.rail.scrollable = false; 1851 } else { 1852 self.rail.scrollable = true; 1853 } 1854 1855 if (self.page.maxw==0) { 1856 self.hideRailHr(); 1857 self.scrollvaluemaxw = 0; 1858 self.scroll.x = 0; 1859 self.scrollratio.x = 0; 1860 self.cursorwidth = 0; 1861 self.setScrollLeft(0); 1862 self.railh.scrollable = false; 1863 } else { 1864 self.railh.scrollable = true; 1865 } 1866 1867 self.locked = (self.page.maxh==0)&&(self.page.maxw==0); 1868 if (self.locked) { 1869 if (!self.ispage) self.updateScrollBar(self.view); 1870 return false; 1871 } 1872 1873 if (!self.hidden&&!self.visibility) { 1874 self.showRail().showRailHr(); 1875 } 1876 else if (!self.hidden&&!self.railh.visibility) self.showRailHr(); 1877 1878 if (self.istextarea&&self.win.css('resize')&&self.win.css('resize')!='none') self.view.h-=20; 1879 1880 self.cursorheight = Math.min(self.view.h,Math.round(self.view.h * (self.view.h / self.page.h))); 1881 self.cursorheight = (self.opt.cursorfixedheight) ? self.opt.cursorfixedheight : Math.max(self.opt.cursorminheight,self.cursorheight); 1882 1883 self.cursorwidth = Math.min(self.view.w,Math.round(self.view.w * (self.view.w / self.page.w))); 1884 self.cursorwidth = (self.opt.cursorfixedheight) ? self.opt.cursorfixedheight : Math.max(self.opt.cursorminheight,self.cursorwidth); 1885 1886 self.scrollvaluemax = self.view.h-self.cursorheight-self.cursor.hborder; 1887 1888 if (self.railh) { 1889 self.railh.width = (self.page.maxh>0) ? (self.view.w-self.rail.width) : self.view.w; 1890 self.scrollvaluemaxw = self.railh.width-self.cursorwidth-self.cursorh.wborder; 1891 } 1892 1893 if (self.checkrtlmode&&self.railh) { 1894 self.checkrtlmode = false;
1895 if (self.opt.rtlmode&&self.scroll.x==0) self.setScrollLeft(self.page.maxw); 1896 } 1897 1898 if (!self.ispage) self.updateScrollBar(self.view); 1899 1900 self.scrollratio = { 1901 x:(self.page.maxw/self.scrollvaluemaxw), 1902 y:(self.page.maxh/self.scrollvaluemax) 1903 }; 1904 1905 var sy = self.getScrollTop(); 1906 if (sy>self.page.maxh) { 1907 self.doScrollTop(self.page.maxh); 1908 } else { 1909 self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y)); 1910 self.scroll.x = Math.round(self.getScrollLeft() * (1/self.scrollratio.x)); 1911 if (self.cursoractive) self.noticeCursor(); 1912 } 1913 1914 if (self.scroll.y&&(self.getScrollTop()==0)) self.doScrollTo(Math.floor(self.scroll.y*self.scrollratio.y)); 1915 1916 return self; 1917 }; 1918 1919 this.resize = self.onResize; 1920 1921 this.lazyResize = function(tm) { // event debounce 1922 tm = (isNaN(tm)) ? 30 : tm; 1923 self.delayed('resize',self.resize,tm); 1924 return self; 1925 } 1926 1927// modified by MDN https://developer.mozilla.org/en-US/docs/DOM/Mozilla_event_reference/wheel 1928 function _modernWheelEvent(dom,name,fn,bubble) { 1929 self._bind(dom,name,function(e){ 1930 var e = (e) ? e : window.event; 1931 var event = { 1932 original: e, 1933 target: e.target || e.srcElement, 1934 type: "wheel", 1935 deltaMode: e.type == "MozMousePixelScroll" ? 0 : 1, 1936 deltaX: 0, 1937 deltaZ: 0, 1938 preventDefault: function() { 1939 e.preventDefault ? e.preventDefault() : e.returnValue = false; 1940 return false; 1941 }, 1942 stopImmediatePropagation: function() { 1943 (e.stopImmediatePropagation) ? e.stopImmediatePropagation() : e.cancelBubble = true; 1944 } 1945 }; 1946 1947 if (name=="mousewheel") { 1948 event.deltaY = - 1/40 * e.wheelDelta; 1949 e.wheelDeltaX && (event.deltaX = - 1/40 * e.wheelDeltaX); 1950 } else { 1951 event.deltaY = e.detail; 1952 } 1953 1954 return fn.call(dom,event); 1955 },bubble); 1956 }; 1957 1958 this._bind = function(el,name,fn,bubble) { // primitive bind 1959 self.events.push({e:el,n:name,f:fn,b:bubble,q:false}); 1960 if (el.addEventListener) { 1961 el.addEventListener(name,fn,bubble||false); 1962 } 1963 else if (el.attachEvent) { 1964 el.attachEvent("on"+name,fn); 1965 } 1966 else { 1967 el["on"+name] = fn; 1968 } 1969 }; 1970 1971 this.jqbind = function(dom,name,fn) { // use jquery bind for non-native events (mouseenter/mouseleave) 1972 self.events.push({e:dom,n:name,f:fn,q:true}); 1973 $(dom).bind(name,fn); 1974 } 1975 1976 this.bind = function(dom,name,fn,bubble) { // touch-oriented & fixing jquery bind 1977 var el = ("jquery" in dom) ? dom[0] : dom; 1978 1979 if (name=='mousewheel') { 1980 if ("onwheel" in self.win) { 1981 self._bind(el,"wheel",fn,bubble||false); 1982 } else { 1983 var wname = (typeof document.onmousewheel != "undefined") ? "mousewheel" : "DOMMouseScroll"; // older IE/Firefox 1984 _modernWheelEvent(el,wname,fn,bubble||false); 1985 if (wname=="DOMMouseScroll") _modernWheelEvent(el,"MozMousePixelScroll",fn,bubble||false); // Firefox legacy 1986 } 1987 } 1988 else if (el.addEventListener) { 1989 if (cap.cantouch && /mouseup|mousedown|mousemove/.test(name)) { // touch device support 1990 var tt=(name=='mousedown')?'touchstart':(name=='mouseup')?'touchend':'touchmove'; 1991 self._bind(el,tt,function(e){ 1992 if (e.touches) { 1993 if (e.touches.length<2) {var ev=(e.touches.length)?e.touches[0]:e;ev.original=e;fn.call(this,ev);} 1994 } 1995 else if (e.changedTouches) {var ev=e.changedTouches[0];ev.original=e;fn.call(this,ev);} //blackberry 1996 },bubble||false); 1997 } 1998 self._bind(el,name,fn,bubble||false); 1999 if (cap.cantouch && name=="mouseup") self._bind(el,"touchcancel",fn,bubble||false); 2000 } 2001 else { 2002 self._bind(el,name,function(e) { 2003 e = e||window.event||false; 2004 if (e) { 2005 if (e.srcElement) e.target=e.srcElement; 2006 } 2007 if (!("pageY" in e)) { 2008 e.pageX = e.clientX + document.documentElement.scrollLeft; 2009 e.pageY = e.clientY + document.documentElement.scrollTop; 2010 } 2011 return ((fn.call(el,e)===false)||bubble===false) ? self.cancelEvent(e) : true; 2012 }); 2013 } 2014 }; 2015 2016 this._unbind = function(el,name,fn,bub) { // primitive unbind 2017 if (el.removeEventListener) { 2018 el.removeEventListener(name,fn,bub); 2019 } 2020 else if (el.detachEvent) { 2021 el.detachEvent('on'+name,fn); 2022 } else { 2023 el['on'+name] = false;
2024 } 2025 }; 2026 2027 this.unbindAll = function() { 2028 for(var a=0;a<self.events.length;a++) { 2029 var r = self.events[a]; 2030 (r.q) ? r.e.unbind(r.n,r.f) : self._unbind(r.e,r.n,r.f,r.b); 2031 } 2032 }; 2033 2034 // Thanks to http://www.switchonthecode.com !! 2035 this.cancelEvent = function(e) { 2036 var e = (e.original) ? e.original : (e) ? e : window.event||false; 2037 if (!e) return false; 2038 if(e.preventDefault) e.preventDefault(); 2039 if(e.stopPropagation) e.stopPropagation(); 2040 if(e.preventManipulation) e.preventManipulation(); //IE10 2041 e.cancelBubble = true; 2042 e.cancel = true; 2043 e.returnValue = false; 2044 return false; 2045 }; 2046 2047 this.stopPropagation = function(e) { 2048 var e = (e.original) ? e.original : (e) ? e : window.event||false; 2049 if (!e) return false; 2050 if (e.stopPropagation) return e.stopPropagation(); 2051 if (e.cancelBubble) e.cancelBubble=true; 2052 return false; 2053 } 2054 2055 this.showRail = function() { 2056 if ((self.page.maxh!=0)&&(self.ispage||self.win.css('display')!='none')) { 2057 self.visibility = true; 2058 self.rail.visibility = true; 2059 self.rail.css('display','block'); 2060 } 2061 return self; 2062 }; 2063 2064 this.showRailHr = function() { 2065 if (!self.railh) return self; 2066 if ((self.page.maxw!=0)&&(self.ispage||self.win.css('display')!='none')) { 2067 self.railh.visibility = true; 2068 self.railh.css('display','block'); 2069 } 2070 return self; 2071 }; 2072 2073 this.hideRail = function() { 2074 self.visibility = false; 2075 self.rail.visibility = false; 2076 self.rail.css('display','none'); 2077 return self; 2078 }; 2079 2080 this.hideRailHr = function() { 2081 if (!self.railh) return self; 2082 self.railh.visibility = false; 2083 self.railh.css('display','none'); 2084 return self; 2085 }; 2086 2087 this.show = function() { 2088 self.hidden = false; 2089 self.locked = false; 2090 return self.showRail().showRailHr(); 2091 }; 2092 2093 this.hide = function() { 2094 self.hidden = true; 2095 self.locked = true; 2096 return self.hideRail().hideRailHr(); 2097 }; 2098 2099 this.toggle = function() { 2100 return (self.hidden) ? self.show() : self.hide(); 2101 }; 2102 2103 this.remove = function() { 2104 self.stop(); 2105 if (self.cursortimeout) clearTimeout(self.cursortimeout); 2106 self.doZoomOut(); 2107 self.unbindAll(); 2108 if (self.observer !== false) self.observer.disconnect(); 2109 if (self.observerremover !== false) self.observerremover.disconnect(); 2110 self.events = []; 2111 if (self.cursor) { 2112 self.cursor.remove(); 2113 self.cursor = null; 2114 } 2115 if (self.cursorh) { 2116 self.cursorh.remove(); 2117 self.cursorh = null; 2118 } 2119 if (self.rail) { 2120 self.rail.remove(); 2121 self.rail = null; 2122 } 2123 if (self.railh) { 2124 self.railh.remove(); 2125 self.railh = null; 2126 } 2127 if (self.zoom) { 2128 self.zoom.remove(); 2129 self.zoom = null; 2130 } 2131 for(var a=0;a<self.saved.css.length;a++) { 2132 var d=self.saved.css[a]; 2133 d[0].css(d[1],(typeof d[2]=="undefined") ? '' : d[2]); 2134 } 2135 self.saved = false; 2136 self.me.data('__nicescroll',''); //erase all traces 2137 self.me = null; 2138 self.doc = null; 2139 self.docscroll = null; 2140 self.win = null; 2141 return self; 2142 }; 2143 2144 this.scrollstart = function(fn) { 2145 this.onscrollstart = fn; 2146 return self; 2147 } 2148 this.scrollend = function(fn) { 2149 this.onscrollend = fn; 2150 return self; 2151 } 2152 this.scrollcancel = function(fn) { 2153 this.onscrollcancel = fn; 2154 return self; 2155 } 2156 2157 this.zoomin = function(fn) { 2158 this.onzoomin = fn; 2159 return self; 2160 } 2161 this.zoomout = function(fn) { 2162 this.onzoomout = fn; 2163 return self; 2164 } 2165 2166 this.isScrollable = function(e) { 2167 var dom = (e.target) ? e.target : e; 2168 if (dom.nodeName == 'OPTION') return true; 2169 while (dom&&(dom.nodeType==1)&&!(/BODY|HTML/.test(dom.nodeName))) { 2170 var dd = $(dom); 2171 var ov = dd.css('overflowY')||dd.css('overflowX')||dd.css('overflow')||''; 2172 if (/scroll|auto/.test(ov)) return (dom.clientHeight!=dom.scrollHeight); 2173 dom = (dom.parentNode) ? dom.parentNode : false; 2174 } 2175 return false;
2176 }; 2177 2178 this.getViewport = function(me) { 2179 var dom = (me&&me.parentNode) ? me.parentNode : false; 2180 while (dom&&(dom.nodeType==1)&&!(/BODY|HTML/.test(dom.nodeName))) { 2181 var dd = $(dom); 2182 var ov = dd.css('overflowY')||dd.css('overflowX')||dd.css('overflow')||''; 2183 if ((/scroll|auto/.test(ov))&&(dom.clientHeight!=dom.scrollHeight)) return dd; 2184 if (dd.getNiceScroll().length>0) return dd; 2185 dom = (dom.parentNode) ? dom.parentNode : false; 2186 } 2187 return false; 2188 }; 2189 2190 function execScrollWheel(e,hr,chkscroll) { 2191 var px,py; 2192 var rt = 1; 2193 2194 if (e.deltaMode==0) { // PIXEL 2195 px = -Math.floor(e.deltaX*(self.opt.mousescrollstep/(18*3))); 2196 py = -Math.floor(e.deltaY*(self.opt.mousescrollstep/(18*3))); 2197 } 2198 else if (e.deltaMode==1) { // LINE 2199 px = -Math.floor(e.deltaX*self.opt.mousescrollstep); 2200 py = -Math.floor(e.deltaY*self.opt.mousescrollstep); 2201 } 2202 2203 if (hr&&(px==0)&&py) { // classic vertical-only mousewheel + browser with x/y support 2204 px = py; 2205 py = 0; 2206 } 2207 2208 if (px) { 2209 if (self.scrollmom) {self.scrollmom.stop()} 2210 self.lastdeltax+=px; 2211 self.debounced("mousewheelx",function(){var dt=self.lastdeltax;self.lastdeltax=0;if(!self.rail.drag){self.doScrollLeftBy(dt)}},120); 2212 } 2213 if (py) { 2214 if (self.opt.nativeparentscrolling&&chkscroll&&!self.ispage&&!self.zoomactive) { 2215 if (py<0) { 2216 if (self.getScrollTop()>=self.page.maxh) return true; 2217 } else { 2218 if (self.getScrollTop()<=0) return true; 2219 } 2220 } 2221 if (self.scrollmom) {self.scrollmom.stop()} 2222 self.lastdeltay+=py; 2223 self.debounced("mousewheely",function(){var dt=self.lastdeltay;self.lastdeltay=0;if(!self.rail.drag){self.doScrollBy(dt)}},120); 2224 } 2225 2226 e.stopImmediatePropagation(); 2227 return e.preventDefault(); 2228// return self.cancelEvent(e); 2229 }; 2230 2231 this.onmousewheel = function(e) { 2232 if (self.locked) return true; 2233 if (self.rail.drag) return self.cancelEvent(e); 2234 2235 if (!self.rail.scrollable) { 2236 if (self.railh&&self.railh.scrollable) { 2237 return self.onmousewheelhr(e); 2238 } else { 2239 return true; 2240 } 2241 } 2242 2243 var nw = +(new Date()); 2244 var chk = false; 2245 if (self.opt.preservenativescrolling&&((self.checkarea+600)<nw)) { 2246// self.checkarea = false; 2247 self.nativescrollingarea = self.isScrollable(e); 2248 chk = true; 2249 } 2250 self.checkarea = nw; 2251 if (self.nativescrollingarea) return true; // this isn't my business 2252// if (self.locked) return self.cancelEvent(e); 2253 var ret = execScrollWheel(e,false,chk); 2254 if (ret) self.checkarea = 0; 2255 return ret; 2256 }; 2257 2258 this.onmousewheelhr = function(e) { 2259 if (self.locked||!self.railh.scrollable) return true; 2260 if (self.rail.drag) return self.cancelEvent(e); 2261 2262 var nw = +(new Date()); 2263 var chk = false; 2264 if (self.opt.preservenativescrolling&&((self.checkarea+600)<nw)) { 2265// self.checkarea = false; 2266 self.nativescrollingarea = self.isScrollable(e); 2267 chk = true; 2268 } 2269 self.checkarea = nw; 2270 if (self.nativescrollingarea) return true; // this isn't my business 2271 if (self.locked) return self.cancelEvent(e); 2272 2273 return execScrollWheel(e,true,chk); 2274 }; 2275 2276 this.stop = function() { 2277 self.cancelScroll(); 2278 if (self.scrollmon) self.scrollmon.stop(); 2279 self.cursorfreezed = false; 2280 self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y)); 2281 self.noticeCursor(); 2282 return self; 2283 }; 2284 2285 this.getTransitionSpeed = function(dif) { 2286 var sp = Math.round(self.opt.scrollspeed*10); 2287 var ex = Math.min(sp,Math.round((dif / 20) * self.opt.scrollspeed)); 2288 return (ex>
228820) ? ex : 0; 2289 } 2290 2291 if (!self.opt.smoothscroll) { 2292 this.doScrollLeft = function(x,spd) { //direct 2293 var y = self.getScrollTop(); 2294 self.doScrollPos(x,y,spd); 2295 } 2296 this.doScrollTop = function(y,spd) { //direct 2297 var x = self.getScrollLeft(); 2298 self.doScrollPos(x,y,spd); 2299 } 2300 this.doScrollPos = function(x,y,spd) { //direct 2301 var nx = (x>self.page.maxw) ? self.page.maxw : x; 2302 if (nx<0) nx=0; 2303 var ny = (y>self.page.maxh) ? self.page.maxh : y; 2304 if (ny<0) ny=0; 2305 self.synched('scroll',function(){ 2306 self.setScrollTop(ny); 2307 self.setScrollLeft(nx); 2308 }); 2309 } 2310 this.cancelScroll = function() {}; // direct 2311 } 2312 else if (self.ishwscroll&&cap.hastransition&&self.opt.usetransition) { 2313 this.prepareTransition = function(dif,istime) { 2314 var ex = (istime) ? ((dif>20)?dif:0) : self.getTransitionSpeed(dif); 2315 var trans = (ex) ? cap.prefixstyle+'transform '+ex+'ms ease-out' : ''; 2316 if (!self.lasttransitionstyle||self.lasttransitionstyle!=trans) { 2317 self.lasttransitionstyle = trans; 2318 self.doc.css(cap.transitionstyle,trans); 2319 } 2320 return ex; 2321 }; 2322 2323 this.doScrollLeft = function(x,spd) { //trans 2324 var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop(); 2325 self.doScrollPos(x,y,spd); 2326 } 2327 2328 this.doScrollTop = function(y,spd) { //trans 2329 var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft(); 2330 self.doScrollPos(x,y,spd); 2331 } 2332 2333 this.doScrollPos = function(x,y,spd) { //trans 2334 2335 var py = self.getScrollTop(); 2336 var px = self.getScrollLeft(); 2337 2338 if (((self.newscrolly-py)*(y-py)<0)||((self.newscrollx-px)*(x-px)<0)) self.cancelScroll(); //inverted movement detection 2339 2340 if (self.opt.bouncescroll==false) { 2341 if (y<0) y=0; 2342 else if (y>self.page.maxh) y=self.page.maxh; 2343 if (x<0) x=0; 2344 else if (x>self.page.maxw) x=self.page.maxw; 2345 } 2346 2347 if (self.scrollrunning&&x==self.newscrollx&&y==self.newscrolly) return false; 2348 2349 self.newscrolly = y; 2350 self.newscrollx = x; 2351 2352 self.newscrollspeed = spd||false; 2353 2354 if (self.timer) return false; 2355 2356 self.timer = setTimeout(function(){ 2357 2358 var top = self.getScrollTop(); 2359 var lft = self.getScrollLeft(); 2360 2361 var dst = {}; 2362 dst.x = x-lft; 2363 dst.y = y-top; 2364 dst.px = lft; 2365 dst.py = top; 2366 2367 var dd = Math.round(Math.sqrt(Math.pow(dst.x,2)+Math.pow(dst.y,2))); 2368 2369// var df = (self.newscrollspeed) ? self.newscrollspeed : dd; 2370 2371 var ms = (self.newscrollspeed && self.newscrollspeed>1) ? self.newscrollspeed : self.getTransitionSpeed(dd); 2372 if (self.newscrollspeed&&self.newscrollspeed<=1) ms*=self.newscrollspeed; 2373 2374 self.prepareTransition(ms,true); 2375 2376 if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm); 2377 2378 if (ms>0) { 2379 2380 if (!self.scrollrunning&&self.onscrollstart) { 2381 var info = {"type":"scrollstart","current":{"x":lft,"y":top},"request":{"x":x,"y":y},"end":{"x":self.newscrollx,"y":self.newscrolly},"speed":ms}; 2382 self.onscrollstart.call(self,info); 2383 } 2384 2385 if (cap.transitionend) { 2386 if (!self.scrollendtrapped) { 2387 self.scrollendtrapped = true; 2388 self.bind(self.doc,cap.transitionend,self.onScrollEnd,false); //I have got to do something usefull!! 2389 } 2390 } else { 2391 if (self.scrollendtrapped) clearTimeout(self.scrollendtrapped); 2392 self.scrollendtrapped = setTimeout(self.onScrollEnd,ms); // simulate transitionend event 2393 } 2394 2395 var py = top; 2396 var px = lft; 2397 self.timerscroll = { 2398 bz: new BezierClass(py,self.newscrolly,ms,0,0,0.58,1), 2399 bh: new BezierClass(px,self.newscrollx,ms,0,0,0.58,1) 2400 }; 2401 if (!self.cursorfreezed) self.timerscroll.tm=setInterval(function(){self.showCursor(self.getScrollTop(),self.getScrollLeft())},60); 2402 2403 } 2404 2405 self.synched("doScroll-set",function(){ 2406 self.timer = 0; 2407 if (self.scrollendtrapped) self.scrollrunning = true; 2408 self.setScrollTop(self.newscrolly); 2409 self.setScrollLeft(self.newscrollx); 2410 if (!self.scrollendtrapped) self.onScrollEnd(); 2411 }); 2412 2413 2414 },50); 2415 2416 }; 2417 2418 this.cancelScroll = function() { 2419 if (!self.scrollendtrapped) return true; 2420 var py = self.getScrollTop(); 2421 var px = self.getScrollLeft(); 2422 self.scrollrunning = false;
2423 if (!cap.transitionend) clearTimeout(cap.transitionend); 2424 self.scrollendtrapped = false; 2425 self._unbind(self.doc,cap.transitionend,self.onScrollEnd); 2426 self.prepareTransition(0); 2427 self.setScrollTop(py); // fire event onscroll 2428 if (self.railh) self.setScrollLeft(px); 2429 if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm); 2430 self.timerscroll = false; 2431 2432 self.cursorfreezed = false; 2433 2434 //self.noticeCursor(false,py,px); 2435 self.showCursor(py,px); 2436 return self; 2437 }; 2438 this.onScrollEnd = function() { 2439 if (self.scrollendtrapped) self._unbind(self.doc,cap.transitionend,self.onScrollEnd); 2440 self.scrollendtrapped = false; 2441 self.prepareTransition(0); 2442 if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm); 2443 self.timerscroll = false; 2444 var py = self.getScrollTop(); 2445 var px = self.getScrollLeft(); 2446 self.setScrollTop(py); // fire event onscroll 2447 if (self.railh) self.setScrollLeft(px); // fire event onscroll left 2448 2449 self.noticeCursor(false,py,px); 2450 2451 self.cursorfreezed = false; 2452 2453 if (py<0) py=0 2454 else if (py>self.page.maxh) py=self.page.maxh; 2455 if (px<0) px=0 2456 else if (px>self.page.maxw) px=self.page.maxw; 2457 if((py!=self.newscrolly)||(px!=self.newscrollx)) return self.doScrollPos(px,py,self.opt.snapbackspeed); 2458 2459 if (self.onscrollend&&self.scrollrunning) { 2460 var info = {"type":"scrollend","current":{"x":px,"y":py},"end":{"x":self.newscrollx,"y":self.newscrolly}}; 2461 self.onscrollend.call(self,info); 2462 } 2463 self.scrollrunning = false; 2464 2465 }; 2466 2467 } else { 2468 2469 this.doScrollLeft = function(x,spd) { //no-trans 2470 var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop(); 2471 self.doScrollPos(x,y,spd); 2472 } 2473 2474 this.doScrollTop = function(y,spd) { //no-trans 2475 var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft(); 2476 self.doScrollPos(x,y,spd); 2477 } 2478 2479 this.doScrollPos = function(x,y,spd) { //no-trans 2480 var y = ((typeof y == "undefined")||(y===false)) ? self.getScrollTop(true) : y; 2481 2482 if ((self.timer)&&(self.newscrolly==y)&&(self.newscrollx==x)) return true; 2483 2484 if (self.timer) clearAnimationFrame(self.timer); 2485 self.timer = 0; 2486 2487 var py = self.getScrollTop(); 2488 var px = self.getScrollLeft(); 2489 2490 if (((self.newscrolly-py)*(y-py)<0)||((self.newscrollx-px)*(x-px)<0)) self.cancelScroll(); //inverted movement detection 2491 2492 self.newscrolly = y; 2493 self.newscrollx = x; 2494 2495 if (!self.bouncescroll||!self.rail.visibility) { 2496 if (self.newscrolly<0) { 2497 self.newscrolly = 0; 2498 } 2499 else if (self.newscrolly>self.page.maxh) { 2500 self.newscrolly = self.page.maxh; 2501 } 2502 } 2503 if (!self.bouncescroll||!self.railh.visibility) { 2504 if (self.newscrollx<0) { 2505 self.newscrollx = 0; 2506 } 2507 else if (self.newscrollx>self.page.maxw) { 2508 self.newscrollx = self.page.maxw; 2509 } 2510 } 2511 2512 self.dst = {}; 2513 self.dst.x = x-px; 2514 self.dst.y = y-py; 2515 self.dst.px = px; 2516 self.dst.py = py; 2517 2518 var dst = Math.round(Math.sqrt(Math.pow(self.dst.x,2)+Math.pow(self.dst.y,2))); 2519 2520 self.dst.ax = self.dst.x / dst; 2521 self.dst.ay = self.dst.y / dst; 2522 2523 var pa = 0; 2524 var pe = dst; 2525 2526 if (self.dst.x==0) { 2527 pa = py; 2528 pe = y; 2529 self.dst.ay = 1; 2530 self.dst.py = 0; 2531 } else if (self.dst.y==0) { 2532 pa = px; 2533 pe = x; 2534 self.dst.ax = 1; 2535 self.dst.px = 0; 2536 } 2537 2538 var ms = self.getTransitionSpeed(dst); 2539 if (spd&&spd<=1) ms*=spd; 2540 if (ms>0) { 2541 self.bzscroll = (self.bzscroll) ? self.bzscroll.update(pe,ms) : new BezierClass(pa,pe,ms,0,1,0,1); 2542 } else { 2543 self.bzscroll = false;
2544 } 2545 2546 if (self.timer) return; 2547 2548 if ((py==self.page.maxh&&y>=self.page.maxh)||(px==self.page.maxw&&x>=self.page.maxw)) self.checkContentSize(); 2549 2550 var sync = 1; 2551 2552 function scrolling() { 2553 if (self.cancelAnimationFrame) return true; 2554 2555 self.scrollrunning = true; 2556 2557 sync = 1-sync; 2558 if (sync) return (self.timer = setAnimationFrame(scrolling)||1); 2559 2560 var done = 0; 2561 2562 var sc = sy = self.getScrollTop(); 2563 if (self.dst.ay) { 2564 sc = (self.bzscroll) ? self.dst.py + (self.bzscroll.getNow()*self.dst.ay) : self.newscrolly; 2565 var dr=sc-sy; 2566 if ((dr<0&&sc<self.newscrolly)||(dr>0&&sc>self.newscrolly)) sc = self.newscrolly; 2567 self.setScrollTop(sc); 2568 if (sc == self.newscrolly) done=1; 2569 } else { 2570 done=1; 2571 } 2572 2573 var scx = sx = self.getScrollLeft(); 2574 if (self.dst.ax) { 2575 scx = (self.bzscroll) ? self.dst.px + (self.bzscroll.getNow()*self.dst.ax) : self.newscrollx; 2576 var dr=scx-sx; 2577 if ((dr<0&&scx<self.newscrollx)||(dr>0&&scx>self.newscrollx)) scx = self.newscrollx; 2578 self.setScrollLeft(scx); 2579 if (scx == self.newscrollx) done+=1; 2580 } else { 2581 done+=1; 2582 } 2583 2584 if (done==2) { 2585 self.timer = 0; 2586 self.cursorfreezed = false; 2587 self.bzscroll = false; 2588 self.scrollrunning = false; 2589 if (sc<0) sc=0; 2590 else if (sc>self.page.maxh) sc=self.page.maxh; 2591 if (scx<0) scx=0; 2592 else if (scx>self.page.maxw) scx=self.page.maxw; 2593 if ((scx!=self.newscrollx)||(sc!=self.newscrolly)) self.doScrollPos(scx,sc); 2594 else { 2595 if (self.onscrollend) { 2596 var info = {"type":"scrollend","current":{"x":sx,"y":sy},"end":{"x":self.newscrollx,"y":self.newscrolly}}; 2597 self.onscrollend.call(self,info); 2598 } 2599 } 2600 } else { 2601 self.timer = setAnimationFrame(scrolling)||1; 2602 } 2603 }; 2604 self.cancelAnimationFrame=false; 2605 self.timer = 1; 2606 2607 if (self.onscrollstart&&!self.scrollrunning) { 2608 var info = {"type":"scrollstart","current":{"x":px,"y":py},"request":{"x":x,"y":y},"end":{"x":self.newscrollx,"y":self.newscrolly},"speed":ms}; 2609 self.onscrollstart.call(self,info); 2610 } 2611 2612 scrolling(); 2613 2614 if ((py==self.page.maxh&&y>=py)||(px==self.page.maxw&&x>=px)) self.checkContentSize(); 2615 2616 self.noticeCursor(); 2617 }; 2618 2619 this.cancelScroll = function() { 2620 if (self.timer) clearAnimationFrame(self.timer); 2621 self.timer = 0; 2622 self.bzscroll = false; 2623 self.scrollrunning = false; 2624 return self; 2625 }; 2626 2627 } 2628 2629 this.doScrollBy = function(stp,relative) { 2630 var ny = 0; 2631 if (relative) { 2632 ny = Math.floor((self.scroll.y-stp)*self.scrollratio.y) 2633 } else { 2634 var sy = (self.timer) ? self.newscrolly : self.getScrollTop(true); 2635 ny = sy-stp; 2636 } 2637 if (self.bouncescroll) { 2638 var haf = Math.round(self.view.h/2); 2639 if (ny<-haf) ny=-haf 2640 else if (ny>(self.page.maxh+haf)) ny = (self.page.maxh+haf); 2641 } 2642 self.cursorfreezed = false; 2643 2644 py = self.getScrollTop(true); 2645 if (ny<0&&py<=0) return self.noticeCursor(); 2646 else if (ny>self.page.maxh&&py>=self.page.maxh) { 2647 self.checkContentSize(); 2648 return self.noticeCursor(); 2649 } 2650 2651 self.doScrollTop(ny); 2652 }; 2653 2654 this.doScrollLeftBy = function(stp,relative) { 2655 var nx = 0; 2656 if (relative) { 2657 nx = Math.floor((self.scroll.x-stp)*self.scrollratio.x) 2658 } else { 2659 var sx = (self.timer) ? self.newscrollx : self.getScrollLeft(true); 2660 nx = sx-stp; 2661 } 2662 if (self.bouncescroll) { 2663 var haf = Math.round(self.view.w/2); 2664 if (nx<-haf) nx=-haf 2665 else if (nx>(self.page.maxw+haf)) nx = (self.page.maxw+haf); 2666 } 2667 self.cursorfreezed = false; 2668 2669 px = self.getScrollLeft(true); 2670 if (nx<0&&px<=0) return self.noticeCursor(); 2671 else if (nx>self.page.maxw&&px>=self.page.maxw) return self.noticeCursor(); 2672 2673 self.doScrollLeft(nx); 2674 }; 2675 2676 this.doScrollTo = function(pos,relative) { 2677 var ny = (relative) ? Math.round(pos*self.scrollratio.y) : pos; 2678 if (ny<0) ny=0 2679 else if (ny>self.page.maxh) ny = self.page.maxh; 2680 self.cursorfreezed = false;
2681 self.doScrollTop(pos); 2682 }; 2683 2684 this.checkContentSize = function() { 2685 var pg = self.getContentSize(); 2686 if ((pg.h!=self.page.h)||(pg.w!=self.page.w)) self.resize(false,pg); 2687 }; 2688 2689 self.onscroll = function(e) { 2690 if (self.rail.drag) return; 2691 if (!self.cursorfreezed) { 2692 self.synched('scroll',function(){ 2693 self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y)); 2694 if (self.railh) self.scroll.x = Math.round(self.getScrollLeft() * (1/self.scrollratio.x)); 2695 self.noticeCursor(); 2696 }); 2697 } 2698 }; 2699 self.bind(self.docscroll,"scroll",self.onscroll); 2700 2701 this.doZoomIn = function(e) { 2702 if (self.zoomactive) return; 2703 self.zoomactive = true; 2704 2705 self.zoomrestore = { 2706 style:{} 2707 }; 2708 var lst = ['position','top','left','zIndex','backgroundColor','marginTop','marginBottom','marginLeft','marginRight']; 2709 var win = self.win[0].style; 2710 for(var a in lst) { 2711 var pp = lst[a]; 2712 self.zoomrestore.style[pp] = (typeof win[pp] != "undefined") ? win[pp] : ''; 2713 } 2714 2715 self.zoomrestore.style.width = self.win.css('width'); 2716 self.zoomrestore.style.height = self.win.css('height'); 2717 2718 self.zoomrestore.padding = { 2719 w:self.win.outerWidth()-self.win.width(), 2720 h:self.win.outerHeight()-self.win.height() 2721 }; 2722 2723 if (cap.isios4) { 2724 self.zoomrestore.scrollTop = $(window).scrollTop(); 2725 $(window).scrollTop(0); 2726 } 2727 2728 self.win.css({ 2729 "position":(cap.isios4)?"absolute":"fixed", 2730 "top":0, 2731 "left":0, 2732 "z-index":globalmaxzindex+100, 2733 "margin":"0px" 2734 }); 2735 var bkg = self.win.css("backgroundColor"); 2736 if (bkg==""||/transparent|rgba\(0, 0, 0, 0\)|rgba\(0,0,0,0\)/.test(bkg)) self.win.css("backgroundColor","#fff"); 2737 self.rail.css({"z-index":globalmaxzindex+101}); 2738 self.zoom.css({"z-index":globalmaxzindex+102}); 2739 self.zoom.css('backgroundPosition','0px -18px'); 2740 self.resizeZoom(); 2741 2742 if (self.onzoomin) self.onzoomin.call(self); 2743 2744 return self.cancelEvent(e); 2745 }; 2746 2747 this.doZoomOut = function(e) { 2748 if (!self.zoomactive) return; 2749 self.zoomactive = false; 2750 2751 self.win.css("margin",""); 2752 self.win.css(self.zoomrestore.style); 2753 2754 if (cap.isios4) { 2755 $(window).scrollTop(self.zoomrestore.scrollTop); 2756 } 2757 2758 self.rail.css({"z-index":self.zindex}); 2759 self.zoom.css({"z-index":self.zindex}); 2760 self.zoomrestore = false; 2761 self.zoom.css('backgroundPosition','0px 0px'); 2762 self.onResize(); 2763 2764 if (self.onzoomout) self.onzoomout.call(self); 2765 2766 return self.cancelEvent(e); 2767 }; 2768 2769 this.doZoom = function(e) { 2770 return (self.zoomactive) ? self.doZoomOut(e) : self.doZoomIn(e); 2771 }; 2772 2773 this.resizeZoom = function() { 2774 if (!self.zoomactive) return; 2775 2776 var py = self.getScrollTop(); //preserve scrolling position 2777 self.win.css({ 2778 width:$(window).width()-self.zoomrestore.padding.w+"px", 2779 height:$(window).height()-self.zoomrestore.padding.h+"px" 2780 }); 2781 self.onResize(); 2782 2783 self.setScrollTop(Math.min(self.page.maxh,py)); 2784 }; 2785 2786 this.init(); 2787 2788 $.nicescroll.push(this); 2789 2790 }; 2791 2792// Inspired by the work of Kin Blas 2793// http://webpro.host.adobe.com/people/jblas/momentum/includes/jquery.momentum.0.7.js 2794 2795 2796 var ScrollMomentumClass2D = function(nc) { 2797 var self = this; 2798 this.nc = nc; 2799 2800 this.lastx = 0; 2801 this.lasty = 0; 2802 this.speedx = 0; 2803 this.speedy = 0; 2804 this.lasttime = 0; 2805 this.steptime = 0; 2806 this.snapx = false; 2807 this.snapy = false; 2808 this.demulx = 0; 2809 this.demuly = 0; 2810 2811 this.lastscrollx = -1; 2812 this.lastscrolly = -1; 2813 2814 this.chkx = 0; 2815 this.chky = 0; 2816 2817 this.timer = 0; 2818 2819 this.time = function() { 2820 return +new Date();//beautifull hack 2821 }; 2822 2823 this.reset = function(px,py) { 2824 self.stop(); 2825 var now = self.time(); 2826 self.steptime = 0; 2827 self.lasttime = now; 2828 self.speedx = 0; 2829 self.speedy = 0; 2830 self.lastx = px; 2831 self.lasty = py; 2832 self.lastscrollx = -1; 2833 self.lastscrolly = -1; 2834 }; 2835 2836 this.update = function(px,py) { 2837 var now = self.time();
vendor: 5,989 bytes, lines 2838-3044
2838 self.steptime = now - self.lasttime; 2839 self.lasttime = now; 2840 var dy = py - self.lasty; 2841 var dx = px - self.lastx; 2842 var sy = self.nc.getScrollTop(); 2843 var sx = self.nc.getScrollLeft(); 2844 var newy = sy + dy; 2845 var newx = sx + dx; 2846 self.snapx = (newx<0)||(newx>self.nc.page.maxw); 2847 self.snapy = (newy<0)||(newy>self.nc.page.maxh); 2848 self.speedx = dx; 2849 self.speedy = dy; 2850 self.lastx = px; 2851 self.lasty = py; 2852 }; 2853 2854 this.stop = function() { 2855 self.nc.unsynched("domomentum2d"); 2856 if (self.timer) clearTimeout(self.timer); 2857 self.timer = 0; 2858 self.lastscrollx = -1; 2859 self.lastscrolly = -1; 2860 }; 2861 2862 this.doSnapy = function(nx,ny) { 2863 var snap = false; 2864 2865 if (ny<0) { 2866 ny=0; 2867 snap=true; 2868 } 2869 else if (ny>self.nc.page.maxh) { 2870 ny=self.nc.page.maxh; 2871 snap=true; 2872 } 2873 2874 if (nx<0) { 2875 nx=0; 2876 snap=true; 2877 } 2878 else if (nx>self.nc.page.maxw) { 2879 nx=self.nc.page.maxw; 2880 snap=true; 2881 } 2882 2883 if (snap) self.nc.doScrollPos(nx,ny,self.nc.opt.snapbackspeed); 2884 }; 2885 2886 this.doMomentum = function(gp) { 2887 var t = self.time(); 2888 var l = (gp) ? t+gp : self.lasttime; 2889 2890 var sl = self.nc.getScrollLeft(); 2891 var st = self.nc.getScrollTop(); 2892 2893 var pageh = self.nc.page.maxh; 2894 var pagew = self.nc.page.maxw; 2895 2896 self.speedx = (pagew>0) ? Math.min(60,self.speedx) : 0; 2897 self.speedy = (pageh>0) ? Math.min(60,self.speedy) : 0; 2898 2899 var chk = l && (t - l) <= 50; 2900 2901 if ((st<0)||(st>pageh)||(sl<0)||(sl>pagew)) chk = false; 2902 2903 var sy = (self.speedy && chk) ? self.speedy : false; 2904 var sx = (self.speedx && chk) ? self.speedx : false; 2905 2906 if (sy||sx) { 2907 var tm = Math.max(16,self.steptime); //timeout granularity 2908 2909 if (tm>50) { // do smooth 2910 var xm = tm/50; 2911 self.speedx*=xm; 2912 self.speedy*=xm; 2913 tm = 50; 2914 } 2915 2916 self.demulxy = 0; 2917 2918 self.lastscrollx = self.nc.getScrollLeft(); 2919 self.chkx = self.lastscrollx; 2920 self.lastscrolly = self.nc.getScrollTop(); 2921 self.chky = self.lastscrolly; 2922 2923 var nx = self.lastscrollx; 2924 var ny = self.lastscrolly; 2925 2926 var onscroll = function(){ 2927 var df = ((self.time()-t)>600) ? 0.04 : 0.02; 2928 2929 if (self.speedx) { 2930 nx = Math.floor(self.lastscrollx - (self.speedx*(1-self.demulxy))); 2931 self.lastscrollx = nx; 2932 if ((nx<0)||(nx>pagew)) df=0.10; 2933 } 2934 2935 if (self.speedy) { 2936 ny = Math.floor(self.lastscrolly - (self.speedy*(1-self.demulxy))); 2937 self.lastscrolly = ny; 2938 if ((ny<0)||(ny>pageh)) df=0.10; 2939 } 2940 2941 self.demulxy = Math.min(1,self.demulxy+df); 2942 2943 self.nc.synched("domomentum2d",function(){ 2944 2945 if (self.speedx) { 2946 var scx = self.nc.getScrollLeft(); 2947 if (scx!=self.chkx) self.stop(); 2948 self.chkx=nx; 2949 self.nc.setScrollLeft(nx); 2950 } 2951 2952 if (self.speedy) { 2953 var scy = self.nc.getScrollTop(); 2954 if (scy!=self.chky) self.stop(); 2955 self.chky=ny; 2956 self.nc.setScrollTop(ny); 2957 } 2958 2959 if(!self.timer) { 2960 self.nc.hideCursor(); 2961 self.doSnapy(nx,ny); 2962 } 2963 2964 }); 2965 2966 if (self.demulxy<1) { 2967 self.timer = setTimeout(onscroll,tm); 2968 } else { 2969 self.stop(); 2970 self.nc.hideCursor(); 2971 self.doSnapy(nx,ny); 2972 } 2973 }; 2974 2975 onscroll(); 2976 2977 } else { 2978 self.doSnapy(self.nc.getScrollLeft(),self.nc.getScrollTop()); 2979 } 2980 2981 } 2982 2983 }; 2984 2985 2986// override jQuery scrollTop 2987 2988 var _scrollTop = jQuery.fn.scrollTop; // preserve original function 2989 2990 jQuery.cssHooks["pageYOffset"] = { 2991 get: function(elem,computed,extra) { 2992 var nice = $.data(elem,'__nicescroll')||false; 2993 return (nice&&nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(elem); 2994 }, 2995 set: function(elem,value) { 2996 var nice = $.data(elem,'__nicescroll')||false; 2997 (nice&&nice.ishwscroll) ? nice.setScrollTop(parseInt(value)) : _scrollTop.call(elem,value); 2998 return this; 2999 } 3000 }; 3001 3002/* 3003 $.fx.step["scrollTop"] = function(fx){ 3004 $.cssHooks["scrollTop"].set( fx.elem, fx.now + fx.unit ); 3005 }; 3006*/ 3007 3008 jQuery.fn.scrollTop = function(value) { 3009 if (typeof value == "undefined") { 3010 var nice = (this[0]) ? $.data(this[0],'__nicescroll')||false : false; 3011 return (nice&&nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(this); 3012 } else { 3013 return this.each(function() { 3014 var nice = $.data(this,'__nicescroll')||false; 3015 (nice&&nice.ishwscroll) ? nice.setScrollTop(parseInt(value)) : _scrollTop.call($(this),value); 3016 }); 3017 } 3018 } 3019 3020// override jQuery scrollLeft 3021 3022 var _scrollLeft = jQuery.fn.scrollLeft; // preserve original function 3023 3024 $.cssHooks.pageXOffset = { 3025 get: function(elem,computed,extra) { 3026 var nice = $.data(elem,'__nicescroll')||false; 3027 return (nice&&nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(elem); 3028 }, 3029 set: function(elem,value) { 3030 var nice = $.data(elem,'__nicescroll')||false; 3031 (nice&&nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)) : _scrollLeft.call(elem,value); 3032 return this; 3033 } 3034 }; 3035 3036/* 3037 $.fx.step["scrollLeft"] = function(fx){ 3038 $.cssHooks["scrollLeft"].set( fx.elem, fx.now + fx.unit ); 3039 }; 3040*/ 3041 3042 jQuery.fn.scrollLeft = function(value) { 3043 if (typeof value == "undefined") { 3044 var nice = (this[0]) ? $.data(this[0],'__nicescroll')||false : false;
3045 return (nice&&nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(this); 3046 } else { 3047 return this.each(function() { 3048 var nice = $.data(this,'__nicescroll')||false; 3049 (nice&&nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)) : _scrollLeft.call($(this),value); 3050 }); 3051 } 3052 } 3053 3054 var NiceScrollArray = function(doms) { 3055 var self = this; 3056 this.length = 0; 3057 this.name = "nicescrollarray"; 3058 3059 this.each = function(fn) { 3060 for(var a=0;a<self.length;a++) fn.call(self[a]); 3061 return self; 3062 }; 3063 3064 this.push = function(nice) { 3065 self[self.length]=nice; 3066 self.length++; 3067 }; 3068 3069 this.eq = function(idx) { 3070 return self[idx]; 3071 }; 3072 3073 if (doms) { 3074 for(a=0;a<doms.length;a++) { 3075 var nice = $.data(doms[a],'__nicescroll')||false; 3076 if (nice) { 3077 this[this.length]=nice; 3078 this.length++; 3079 } 3080 }; 3081 } 3082 3083 return this; 3084 }; 3085 3086 function mplex(el,lst,fn) { 3087 for(var a=0;a<lst.length;a++) fn(el,lst[a]); 3088 }; 3089 mplex( 3090 NiceScrollArray.prototype, 3091 ['show','hide','toggle','onResize','resize','remove','stop','doScrollPos'], 3092 function(e,n) { 3093 e[n] = function(){ 3094 var args = arguments; 3095 return this.each(function(){ 3096 this[n].apply(this,args); 3097 }); 3098 }; 3099 } 3100 ); 3101 3102 jQuery.fn.getNiceScroll = function(index) { 3103 if (typeof index == "undefined") { 3104 return new NiceScrollArray(this); 3105 } else { 3106 var nice = $.data(this[index],'__nicescroll')||false; 3107 return nice; 3108 } 3109 }; 3110 3111 jQuery.extend(jQuery.expr[':'], { 3112 nicescroll: function(a) { 3113 return ($.data(a,'__nicescroll'))?true:false; 3114 } 3115 }); 3116 3117 $.fn.niceScroll = function(wrapper,opt) { 3118 if (typeof opt=="undefined") { 3119 if ((typeof wrapper=="object")&&!("jquery" in wrapper)) { 3120 opt = wrapper; 3121 wrapper = false; 3122 } 3123 } 3124 var ret = new NiceScrollArray(); 3125 if (typeof opt=="undefined") opt = {}; 3126 3127 if (wrapper||false) { 3128 opt.doc = $(wrapper); 3129 opt.win = $(this); 3130 } 3131 var docundef = !("doc" in opt); 3132 if (!docundef&&!("win" in opt)) opt.win = $(this); 3133 3134 this.each(function() { 3135 var nice = $(this).data('__nicescroll')||false; 3136 if (!nice) { 3137 opt.doc = (docundef) ? $(this) : opt.doc; 3138 nice = new NiceScrollClass(opt,$(this)); 3139 $(this).data('__nicescroll',nice); 3140 } 3141 ret.push(nice); 3142 }); 3143 return (ret.length==1) ? ret[0] : ret; 3144 }; 3145 3146 window.NiceScroll = { 3147 getjQuery:function(){return jQuery} 3148 }; 3149 3150 if (!$.nicescroll) { 3151 $.nicescroll = new NiceScrollArray(); 3152 $.nicescroll.options = _globaloptions; 3153 } 3154 3155})( jQuery ); 3156
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.