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