1/** 2 * sp-slidemenu.js 3 * 4 * @version 0.1.0 5 * @url https://github.com/be-hase/sp-slidemenu 6 * 7 * Copyright 2013 be-hase.com, Inc. 8 * Licensed under the MIT License: 9 * http://www.opensource.org/licenses/mit-license.php 10 */ 11 12;(function(window, document, undefined) { 13"use strict"; 14 15var div, PREFIX, support, gestureStart, EVENTS, ANIME_SPEED, SLIDE_STATUS, SCROLL_STATUS, THRESHOLD, EVENT_MOE_TIME, rclass, ITEM_CLICK_CLASS_NAME; 16 17div = document.createElement('div'); 18 19PREFIX = ['webkit', 'moz', 'o', 'ms']; 20 21support = SpSlidemenu.support = {}; 22support.transform3d = hasProp([ 23 'perspectiveProperty', 24 'WebkitPerspective', 25 'MozPerspective', 26 'OPerspective', 27 'msPerspective' 28]); 29support.transform = hasProp([ 30 'transformProperty', 31 'WebkitTransform', 32 'MozTransform', 33 'OTransform', 34 'msTransform' 35]); 36support.transition = hasProp([ 37 'transitionProperty', 38 'WebkitTransitionProperty', 39 'MozTransitionProperty', 40 'OTransitionProperty', 41 'msTransitionProperty' 42]); 43support.addEventListener = 'addEventListener' in window; 44support.msPointer = window.navigator.msPointerEnabled; 45support.cssAnimation = (support.transform3d || support.transform) && support.transition; 46support.touch = 'ontouchend' in window; 47 48EVENTS = { 49 start: { 50 touch: 'touchstart', 51 mouse: 'mousedown' 52 }, 53 move: { 54 touch: 'touchmove', 55 mouse: 'mousemove' 56 }, 57 end: { 58 touch: 'touchend', 59 mouse: 'mouseup' 60 } 61}; 62 63gestureStart = false;
64if (support.addEventListener) { 65 document.addEventListener('gesturestart', function() { 66 gestureStart = true; 67 }); 68 69 document.addEventListener('gestureend', function() { 70 gestureStart = false; 71 }); 72} 73 74ANIME_SPEED = { 75 slider: 200, 76 scrollOverBack: 400 77}; 78 79SLIDE_STATUS = { 80 close: 0, 81 open: 1, 82 progress: 2 83}; 84 85THRESHOLD = 10; 86 87EVENT_MOE_TIME = 50; 88 89rclass = /[\t\r\n\f]/g; 90 91ITEM_CLICK_CLASS_NAME = 'menu-item'; 92 93/* 94[MEMO] 95SpSlidemenu properties which is not function is ... 96 97-- element -- 98element: main 99element: slidemenu 100element: button 101element: slidemenuBody 102element: slidemenuContent 103element: slidemenuHeader 104 105-- options -- 106bool: disableCssAnimation 107bool: disabled3d 108 109-- animation -- 110bool: useCssAnimation 111bool: use3d 112 113-- slide -- 114int: slideWidth 115string: htmlOverflowX 116string: bodyOverflowX 117int: buttonStartPageX 118int: buttonStartPageY 119 120-- scroll -- 121bool: scrollTouchStarted 122bool: scrollMoveReady 123int: scrollStartPageX 124int: scrollStartPageY 125int: scrollBasePageY 126int: scrollTimeForVelocity 127int: scrollCurrentY 128int: scrollMoveEventCnt 129int: scrollAnimationTimer 130int: scrollOverTimer 131int: scrollMaxY 132*/ 133 134function SpSlidemenu(main, slidemenu, button, options) { 135 if (this instanceof SpSlidemenu) { 136 return this.init(main, slidemenu, button, options); 137 } else { 138 return new SpSlidemenu(main, slidemenu, button, options); 139 } 140} 141 142SpSlidemenu.prototype.init = function(main, slidemenu, button, options) { 143 var _this = this; 144 145 // find and set element. 146 _this.setElement(main, slidemenu, button); 147 if (!_this.main || !_this.slidemenu || !_this.button || !_this.slidemenuBody || !_this.slidemenuContent) { 148 throw new Error('Element not found. Please set correctly.'); 149 } 150 151 // options 152 options = options || {}; 153 _this.disableCssAnimation = (options.disableCssAnimation === undefined) ? false : options.disableCssAnimation; 154 _this.disable3d = (options.disable3d === undefined) ? false : options.disable3d; 155 _this.direction = 'left'; 156 if (options.direction === 'right') { 157 _this.direction = 'right'; 158 } 159 160 // animation 161 _this.useCssAnimation = support.cssAnimation; 162 if (_this.disableCssAnimation === true) { 163 _this.useCssAnimation = false; 164 } 165 _this.use3d = support.transform3d; 166 if (_this.disable3d === true) { 167 _this.use3d = false; 168 } 169 170 // slide 171 _this.slideWidth = (getDimentions(_this.slidemenu)).width; 172 _this.main.SpSlidemenuStatus = SLIDE_STATUS.close; 173 _this.htmlOverflowX = ''; 174 _this.bodyOverflowX = ''; 175 176 // scroll 177 _this.scrollCurrentY = 0; 178 _this.scrollAnimationTimer = false; 179 _this.scrollOverTimer = false; 180 181 // set default style. 182 _this.setDefaultStyle(); 183 184 // bind some method for callback. 185 _this.bindMethods(); 186 187 // add event 188 addTouchEvent('start', _this.button, _this.buttonTouchStart, false); 189 addTouchEvent('move', _this.button, blockEvent, false); 190 addTouchEvent('end', _this.button, _this.buttonTouchEnd, false); 191 addTouchEvent('start', _this.slidemenuContent, _this.scrollTouchStart, false); 192 addTouchEvent('move', _this.slidemenuContent, _this.scrollTouchMove, false); 193 addTouchEvent('end', _this.slidemenuContent, _this.scrollTouchEnd, false); 194 _this.slidemenuContent.addEventListener('click', _this.itemClick, false); 195 // window size change 196 window.addEventListener('resize', debounce(_this.setHeight, 100), false); 197 198 return _this; 199}; 200 201SpSlidemenu.prototype.bindMethods = function() { 202 var _this, funcs; 203 _this = this; 204 funcs = [ 205 'setHeight', 206 'slideOpen', 'slideOpenEnd', 'slideClose', 'slideCloseEnd', 207 'buttonTouchStart', 'buttonTouchEnd', 'mainTouchStart', 208 'scrollTouchStart', 'scrollTouchMove', 'scrollTouchEnd', 'scrollInertiaMove', 'scrollOverBack', 'scrollOver', 209 'itemClick' 210 ]; 211 212 funcs.forEach(function(func) { 213 _this[func] = bind(_this[func], _this); 214 }); 215}; 216 217SpSlidemenu.prototype.setElement = function(main, slidemenu, button) { 218 var _this = this; 219 220 _this.main = main; 221 if (typeof main === 'string') { 222 _this.main = document.querySelector(main); 223 } 224 _this.slidemenu = slidemenu; 225 if (typeof slidemenu === 'string') { 226 _this.slidemenu = document.querySelector(slidemenu); 227 } 228 _this.button = button; 229 if (typeof button === 'string') { 230 _this.button = document.querySelector(button); 231 } 232 if (!_this.slidemenu) { 233 return; 234 } 235 _this.slidemenuBody = _this.slidemenu.querySelector('.slidemenu-body'); 236 _this.slidemenuContent = _this.slidemenu.querySelector('.slidemenu-content'); 237 _this.slidemenuHeader = _this.slidemenu.querySelector('.slidemenu-header'); 238}; 239 240SpSlidemenu.prototype.setDefaultStyle = function() { 241 var _this = this; 242 243 if (support.msPointer) {
244 _this.slidemenuContent.style.msTouchAction = 'none'; 245 } 246 _this.setHeight(); 247 if (_this.useCssAnimation) { 248 setStyles(_this.main, { 249 transitionProperty: getCSSName('transform'), 250 transitionTimingFunction: 'ease-in-out', 251 transitionDuration: ANIME_SPEED.slider + 'ms', 252 transitionDelay: '0ms', 253 transform: _this.getTranslateX(0) 254 }); 255 setStyles(_this.slidemenu, { 256 transitionProperty: 'visibility', 257 transitionTimingFunction: 'linear', 258 transitionDuration: '0ms', 259 transitionDelay: ANIME_SPEED.slider + 'ms' 260 }); 261 setStyles(_this.slidemenuContent, { 262 transitionProperty: getCSSName('transform'), 263 transitionTimingFunction: 'ease-in-out', 264 transitionDuration: '0ms', 265 transitionDelay: '0ms', 266 transform: _this.getTranslateY(0) 267 }); 268 } else { 269 setStyles(_this.main, { 270 position: 'relative', 271 left: '0px' 272 }); 273 setStyles(_this.slidemenuContent, { 274 top: '0px' 275 }); 276 } 277}; 278 279SpSlidemenu.prototype.setHeight = function(event) { 280 var _this, browserHeight; 281 _this = this; 282 browserHeight = getBrowserHeight(); 283 284 setStyles(_this.main, { 285 minHeight: browserHeight + 'px' 286 }); 287 setStyles(_this.slidemenu, { 288 height: browserHeight + 'px' 289 }); 290}; 291 292SpSlidemenu.prototype.buttonTouchStart = function(event) { 293 var _this = this; 294 295 event.preventDefault(); 296 event.stopPropagation(); 297 298 switch(_this.main.SpSlidemenuStatus) { 299 case SLIDE_STATUS.progress: 300 break; 301 case SLIDE_STATUS.open: 302 case SLIDE_STATUS.close: 303 _this.buttonStartPageX = getPage(event, 'pageX'); 304 _this.buttonStartPageY = getPage(event, 'pageY'); 305 break; 306 } 307}; 308 309SpSlidemenu.prototype.buttonTouchEnd = function(event) { 310 var _this = this; 311 312 event.preventDefault(); 313 event.stopPropagation(); 314 315 if (_this.shouldTrigerNext(event)) { 316 switch(_this.main.SpSlidemenuStatus) { 317 case SLIDE_STATUS.progress: 318 break; 319 case SLIDE_STATUS.open: 320 _this.slideClose(event); 321 break; 322 case SLIDE_STATUS.close: 323 _this.slideOpen(event); 324 break; 325 } 326 } 327}; 328 329SpSlidemenu.prototype.mainTouchStart = function(event) { 330 var _this = this; 331 332 event.preventDefault(); 333 event.stopPropagation(); 334 335 _this.slideClose(event); 336}; 337 338SpSlidemenu.prototype.shouldTrigerNext = function(event) { 339 var _this = this, 340 buttonEndPageX = getPage(event, 'pageX'), 341 buttonEndPageY = getPage(event, 'pageY'), 342 deltaX = Math.abs(buttonEndPageX - _this.buttonStartPageX), 343 deltaY = Math.abs(buttonEndPageY - _this.buttonStartPageY); 344 345 return deltaX < 20 && deltaY < 20; 346}; 347 348SpSlidemenu.prototype.slideOpen = function(event) { 349 var _this = this, toX; 350 351 if (_this.direction === 'left') { 352 toX = _this.slideWidth; 353 } else { 354 toX = -_this.slideWidth; 355 } 356 _this.main.SpSlidemenuStatus = SLIDE_STATUS.progress; 357 358 //set event 359 addTouchEvent('move', document, blockEvent, false); 360 361 // change style 362 _this.htmlOverflowX = document.documentElement.style['overflowX']; 363 _this.bodyOverflowX = document.body.style['overflowX']; 364 document.documentElement.style['overflowX'] = document.body.style['overflowX'] = 'hidden'; 365 if (_this.useCssAnimation) { 366 setStyles(_this.main, { 367 transform: _this.getTranslateX(toX) 368 }); 369 setStyles(_this.slidemenu, { 370 transitionProperty: 'z-index', 371 visibility: 'visible', 372 zIndex: '1' 373 }); 374 } else { 375 animate(_this.main, _this.direction, toX, ANIME_SPEED.slider); 376 setStyles(_this.slidemenu, { 377 visibility: 'visible' 378 }); 379 } 380 381 // set callback 382 setTimeout(_this.slideOpenEnd, ANIME_SPEED.slider + EVENT_MOE_TIME); 383}; 384SpSlidemenu.prototype.slideOpenEnd = function() { 385 var _this = this; 386 387 _this.main.SpSlidemenuStatus = SLIDE_STATUS.open; 388 389 // change style 390 if (_this.useCssAnimation) { 391 } else { 392 setStyles(_this.slidemenu, { 393 zIndex: '1' 394 }); 395 } 396 397 // add event 398 addTouchEvent('start', _this.main, _this.mainTouchStart, false); 399}; 400 401SpSlidemenu.prototype.slideClose = function(event) { 402 var _this = this; 403 404 _this.main.SpSlidemenuStatus = SLIDE_STATUS.progress; 405 406 //event 407 removeTouchEvent('start', _this.main, _this.mainTouchStart, false); 408 409 // change style 410 if (_this.useCssAnimation) { 411 setStyles(_this.main, { 412 transform: _this.getTranslateX(0) 413 }); 414 setStyles(_this.slidemenu, { 415 transitionProperty: 'visibility', 416 visibility: 'hidden', 417 zIndex: '-1' 418 }); 419 } else { 420 animate(_this.main, _this.direction, 0, ANIME_SPEED.slider); 421 setStyles(_this.slidemenu, { 422 zIndex: '-1' 423 }); 424 } 425 426 // set callback 427 setTimeout(_this.slideCloseEnd, ANIME_SPEED.slider + EVENT_MOE_TIME); 428}; 429SpSlidemenu.prototype.slideCloseEnd = function() { 430 var _this = this; 431 432 _this.main.SpSlidemenuStatus = SLIDE_STATUS.close; 433 434 // change style
435 document.documentElement.style['overflowX'] = _this.htmlOverflowX; 436 document.body.style['overflowX'] = _this.bodyOverflowX; 437 if (_this.useCssAnimation) { 438 } else { 439 setStyles(_this.slidemenu, { 440 visibility: 'hidden' 441 }); 442 } 443 444 // set event 445 removeTouchEvent('move', document, blockEvent, false); 446}; 447 448SpSlidemenu.prototype.scrollTouchStart = function(event) { 449 var _this = this; 450 451 if (gestureStart) { 452 return; 453 } 454 455 if (_this.scrollOverTimer !== false) { 456 clearTimeout(_this.scrollOverTimer); 457 } 458 459 _this.scrollCurrentY = _this.getScrollCurrentY(); 460 if (_this.useCssAnimation) { 461 setStyles(_this.slidemenuContent, { 462 transitionTimingFunction: 'ease-in-out', 463 transitionDuration: '0ms', 464 transform: _this.getTranslateY(_this.scrollCurrentY) 465 }); 466 } else { 467 _this.stopScrollAnimate(); 468 setStyles(_this.slidemenuContent, { 469 top: _this.scrollCurrentY + 'px' 470 }); 471 } 472 473 _this.scrollOverTimer = false; 474 _this.scrollAnimationTimer = false; 475 _this.scrollTouchStarted = true; 476 _this.scrollMoveReady = false; 477 _this.scrollMoveEventCnt = 0; 478 _this.scrollMaxY = _this.calcMaxY(); 479 _this.scrollStartPageX = getPage(event, 'pageX'); 480 _this.scrollStartPageY = getPage(event, 'pageY'); 481 _this.scrollBasePageY = _this.scrollStartPageY; 482 _this.scrollTimeForVelocity = event.timeStamp; 483 _this.scrollPageYForVelocity = _this.scrollStartPageY; 484 485 _this.slidemenuContent.removeEventListener('click', blockEvent, true); 486}; 487 488SpSlidemenu.prototype.scrollTouchMove = function(event) { 489 var _this, pageX, pageY, distY, newY, deltaX, deltaY; 490 _this = this; 491 492 if (!_this.scrollTouchStarted || gestureStart) { 493 return; 494 } 495 496 pageX = getPage(event, 'pageX'); 497 pageY = getPage(event, 'pageY'); 498 499 if (_this.scrollMoveReady) { 500 event.preventDefault(); 501 event.stopPropagation(); 502 distY = pageY - _this.scrollBasePageY; 503 newY = _this.scrollCurrentY + distY; 504 if (newY > 0 || newY < _this.scrollMaxY) { 505 newY = Math.round(_this.scrollCurrentY + distY / 3); 506 } 507 _this.scrollSetY(newY); 508 509 if (_this.scrollMoveEventCnt % THRESHOLD === 0) { 510 _this.scrollPageYForVelocity = pageY; 511 _this.scrollTimeForVelocity = event.timeStamp; 512 } 513 _this.scrollMoveEventCnt++; 514 } else { 515 deltaX = Math.abs(pageX - _this.scrollStartPageX); 516 deltaY = Math.abs(pageY - _this.scrollStartPageY); 517 if (deltaX > 5 || deltaY > 5) { 518 _this.scrollMoveReady = true; 519 _this.slidemenuContent.addEventListener('click', blockEvent, true); 520 } 521 } 522 523 _this.scrollBasePageY = pageY; 524}; 525 526SpSlidemenu.prototype.scrollTouchEnd = function(event) { 527 var _this, speed, deltaY, deltaTime; 528 _this = this; 529 530 if (!_this.scrollTouchStarted) { 531 return; 532 } 533 534 _this.scrollTouchStarted = false; 535 _this.scrollMaxY = _this.calcMaxY(); 536 537 if (_this.scrollCurrentY > 0 || _this.scrollCurrentY < _this.scrollMaxY) { 538 _this.scrollOverBack(); 539 return; 540 } 541 542 deltaY = getPage(event, 'pageY') - _this.scrollPageYForVelocity; 543 deltaTime = event.timeStamp - _this.scrollTimeForVelocity; 544 speed = deltaY / deltaTime; 545 546 if (Math.abs(speed) >= 0.01) { 547 _this.scrollInertia(speed); 548 } 549}; 550 551SpSlidemenu.prototype.scrollInertia = function(speed) { 552 var _this, directionToTop, maxTo, distanceMaxTo, stopTime, canMove, to, duration, speedAtboundary, nextTo; 553 _this = this; 554 555 if (speed > 0) { 556 directionToTop = true; 557 maxTo = 0; 558 } else { 559 directionToTop = false; 560 maxTo = _this.scrollMaxY; 561 } 562 563 distanceMaxTo = Math.abs(_this.scrollCurrentY - maxTo); 564 565 speed = Math.abs(750 * speed); 566 if (speed > 1000) { 567 speed = 1000; 568 } 569 570 stopTime = speed / 500; 571 canMove = (speed * stopTime) - ((500 * Math.pow(stopTime, 2)) / 2); 572 573 if (canMove <= distanceMaxTo) { 574 if (directionToTop) { 575 to = _this.scrollCurrentY + canMove; 576 } else { 577 to = _this.scrollCurrentY - canMove; 578 } 579 duration = stopTime * 1000; 580 _this.scrollInertiaMove(to, duration, false); 581 } else { 582 to = maxTo; 583 speedAtboundary = Math.sqrt((2 * 500 * distanceMaxTo) + Math.pow(speed, 2)); 584 duration = (speedAtboundary - speed) / 500 * 1000; 585 _this.scrollInertiaMove(to, duration, true, speedAtboundary, directionToTop); 586 } 587}; 588 589SpSlidemenu.prototype.scrollInertiaMove = function(to, duration, isOver, speed, directionToTop) { 590 var _this = this, stopTime, canMove; 591 592 _this.scrollCurrentY = to; 593 if (_this.useCssAnimation) { 594 setStyles(_this.slidemenuContent,{ 595 transitionTimingFunction: 'cubic-bezier(0.33, 0.66, 0.66, 1)', 596 transitionDuration: duration + 'ms', 597 transform: _this.getTranslateY(to) 598 }); 599 } else { 600 _this.scrollAnimate(to, duration); 601 } 602 603 if (!isOver) { 604 return; 605 } 606 607 stopTime = speed / 7500; 608 canMove = (speed * stopTime) - ((7500 * Math.pow(stopTime, 2)) / 2); 609 if (directionToTop) { 610 to = _this.scrollCurrentY + canMove; 611 } else { 612 to = _this.scrollCurrentY - canMove; 613 } 614 duration = stopTime * 1000; 615 _this.scrollOver(to, duration); 616}; 617 618SpSlidemenu.prototype.scrollOver = function(to, duration) { 619 var _this; 620 _this = this; 621 622 _this.scrollCurrentY = to; 623 if (_this.useCssAnimation) { 624 setStyles(_this.slidemenuContent,{ 625 transitionTimingFunction: 'cubic-bezier(0.33, 0.66, 0.66, 1)', 626 transitionDuration: duration + 'ms', 627 transform: _this.getTranslateY(to) 628 }); 629 } else { 630 _this.scrollAnimate(to, duration); 631 } 632 633 _this.scrollOverTimer = setTimeout(_this.scrollOverBack, duration); 634}; 635 636SpSlidemenu.prototype.scrollOverBack = function() { 637 var _this, to; 638 _this = this; 639 if (_this.scrollCurrentY >= 0) { 640 to = 0; 641 } else { 642 to = _this.scrollMaxY; 643 } 644 645 _this.scrollCurrentY = to; 646 if (_this.useCssAnimation) { 647 setStyles(_this.slidemenuContent,{ 648 transitionTimingFunction: 'ease-out',
649 transitionDuration: ANIME_SPEED.scrollOverBack + 'ms', 650 transform: _this.getTranslateY(to) 651 }); 652 } else { 653 _this.scrollAnimate(to, ANIME_SPEED.scrollOverBack); 654 } 655}; 656 657SpSlidemenu.prototype.scrollSetY = function(y) { 658 var _this = this; 659 660 _this.scrollCurrentY = y; 661 if (_this.useCssAnimation) { 662 setStyles(_this.slidemenuContent,{ 663 transitionTimingFunction: 'ease-in-out', 664 transitionDuration: '0ms', 665 transform: _this.getTranslateY(y) 666 }); 667 } else { 668 _this.slidemenuContent.style.top = y + 'px'; 669 } 670}; 671 672SpSlidemenu.prototype.scrollAnimate = function(to, transitionDuration) { 673 var _this = this; 674 675 _this.stopScrollAnimate(); 676 _this.scrollAnimationTimer = animate(_this.slidemenuContent, 'top', to, transitionDuration); 677}; 678 679SpSlidemenu.prototype.stopScrollAnimate = function() { 680 var _this = this; 681 if (_this.scrollAnimationTimer !== false) { 682 clearInterval(_this.scrollAnimationTimer); 683 } 684}; 685 686SpSlidemenu.prototype.itemClick = function(event) { 687 var elem = event.target || event.srcElement; 688 689 if (hasClass(elem, ITEM_CLICK_CLASS_NAME)) { 690 this.slideClose(); 691 } 692}; 693 694SpSlidemenu.prototype.calcMaxY = function(x) { 695 var _this, contentHeight, bodyHeight, headerHeight; 696 _this = this; 697 contentHeight = _this.slidemenuContent.offsetHeight; 698 bodyHeight = _this.slidemenuBody.offsetHeight; 699 headerHeight = 0; 700 if (_this.slidemenuHeader) { 701 headerHeight = _this.slidemenuHeader.offsetHeight; 702 } 703 if (contentHeight > bodyHeight) { 704 return - (contentHeight - bodyHeight + headerHeight); 705 } else { 706 return 0; 707 } 708}; 709 710SpSlidemenu.prototype.getScrollCurrentY = function() { 711 var ret = 0; 712 713 if (this.useCssAnimation) { 714 getStyle(window.getComputedStyle(this.slidemenuContent, ''), 'transform').split(',').forEach(function(value){ 715 var number = parseInt(value, 10); 716 if (!isNaN(number) && number !== 0 && number !== 1) { 717 ret = number; 718 } 719 }); 720 } else { 721 var number = parseInt(getStyle(window.getComputedStyle(this.slidemenuContent, ''), 'top'), 10); 722 if (!isNaN(number) && number !== 0 && number !== 1) { 723 ret = number; 724 } 725 } 726 return ret; 727}; 728 729SpSlidemenu.prototype.getTranslateX = function(x) { 730 var _this = this; 731 732 return _this.use3d ? 'translate3d(' + x + 'px, 0px, 0px)' : 'translate(' + x + 'px, 0px)'; 733}; 734 735SpSlidemenu.prototype.getTranslateY = function(y) { 736 var _this = this; 737 738 return _this.use3d ? 'translate3d(0px, ' + y + 'px, 0px)' : 'translate(0px, ' + y + 'px)'; 739}; 740 741 742 743//Utility Function 744function hasProp(props) { 745 return some(props, function(prop) { 746 return div.style[prop] !== undefined; 747 }); 748} 749function upperCaseFirst(str) { 750 return str.charAt(0).toUpperCase() + str.substr(1); 751} 752function some(ary, callback) { 753 var i, len; 754 755 for (i = 0, len = ary.length; i < len; i++) { 756 if (callback(ary[i], i)) { 757 return true; 758 } 759 } 760 return false; 761} 762function setStyle(elem, prop, val) { 763 var style = elem.style; 764 if (!setStyle.cache) { 765 setStyle.cache = {}; 766 } 767 768 if (setStyle.cache[prop] !== undefined) { 769 style[setStyle.cache[prop]] = val; 770 return; 771 } 772 if (style[prop] !== undefined) { 773 setStyle.cache[prop] = prop; 774 style[prop] = val; 775 return; 776 } 777 some(PREFIX, function(_prefix) { 778 var _prop = upperCaseFirst(_prefix) + upperCaseFirst(prop); 779 if (style[_prop] !== undefined) { 780 //setStyle.cache[prop] = _prop; 781 style[_prop] = val; 782 return true; 783 } 784 }); 785} 786function setStyles(elem, styles) { 787 var style, prop; 788 789 for (prop in styles) { 790 if (styles.hasOwnProperty(prop)) { 791 setStyle(elem, prop, styles[prop]); 792 } 793 } 794} 795function getStyle(style, prop) { 796 var ret; 797 798 if (style[prop] !== undefined) { 799 return style[prop]; 800 } 801 some(PREFIX, function(_prefix) { 802 var _prop = upperCaseFirst(_prefix) + upperCaseFirst(prop); 803 if (style[_prop] !== undefined) { 804 ret = style[_prop]; 805 return true; 806 } 807 }); 808 return ret; 809} 810function getCSSName(prop) { 811 var ret; 812 813 if (!getCSSName.cache) { 814 getCSSName.cache = {}; 815 } 816 if (getCSSName.cache[prop] !== undefined) { 817 return getCSSName.cache[prop]; 818 } 819 if (div.style[prop] !== undefined) { 820 getCSSName.cache[prop] = prop; 821 return prop; 822 } 823 some(PREFIX, function(_prefix) { 824 var _prop = upperCaseFirst(_prefix) + upperCaseFirst(prop); 825 826 if (div.style[_prop] !== undefined) { 827 ret = '-' + _prefix + '-' + prop; 828 return true; 829 } 830 }); 831 getCSSName.cache[prop] = ret; 832 return ret; 833} 834function bind(func, context) { 835 var nativeBind, slice, args; 836 nativeBind = Function.prototype.bind; 837 slice = Array.prototype.slice; 838 839 if (func.bind === nativeBind && nativeBind) { 840 return nativeBind.apply(func, slice.call(arguments, 1)); 841 } 842 843 args = slice.call(arguments, 2); 844 return function() { 845 return func.apply(context, args.concat(slice.call(arguments))); 846 }; 847} 848function blockEvent(event) { 849 event.preventDefault(); 850 event.stopPropagation(); 851} 852function getDimentions(element) { 853 var previous, key, properties, result; 854 previous = {}; 855 properties = { 856 position: 'absolute', 857 visibility: 'hidden', 858 display: 'block' 859 }; 860 861 for (key in properties) { 862 previous[key] = element.style[key]; 863 element.style[key] = properties[key]; 864 } 865 866 result = { 867 width: element.offsetWidth, 868 height: element.offsetHeight 869 }; 870 871 for (key in properties) { 872 element.style[key] = previous[key]; 873 } 874 875 return result; 876} 877function getPage(event, page) { 878 return event.changedTouches ? event.changedTouches[0][page] : event[page]; 879} 880function addTouchEvent(eventType, element, listener, useCapture) { 881 useCapture = useCapture || false; 882 883 if (support.touch) { 884 element.addEventListener(EVENTS[eventType].touch, listener, useCapture); 885 } else { 886 element.addEventListener(EVENTS[eventType].mouse, listener, useCapture); 887 } 888} 889function removeTouchEvent(eventType, element, listener, useCapture) { 890 useCapture = useCapture || false; 891 892 if (support.touch) { 893 element.removeEventListener(EVENTS[eventType].touch, listener, useCapture); 894 } else { 895 element.removeEventListener(EVENTS[eventType].mouse, listener, useCapture); 896 } 897} 898function hasClass(elem, className) { 899 className = " " + className + " "; 900 if (elem.nodeType === 1 && (" " + elem.className + " ").replace(rclass, " ").indexOf(className) >= 0 ) { 901 return true; 902 } 903 904 return false;
905} 906function animate(elem, prop, to, transitionDuration) { 907 var begin, from, duration, easing, timer; 908 begin = +new Date(); 909 from = parseInt(elem.style[prop], 10); 910 to = parseInt(to, 10); 911 duration = parseInt(transitionDuration, 10); 912 easing = function(time, duration) { 913 return -(time /= duration) * (time - 2); 914 }; 915 916 917 timer = setInterval(function() { 918 var time, pos, now; 919 time = new Date() - begin; 920 if (time > duration) { 921 clearInterval(timer); 922 now = to; 923 } else { 924 pos = easing(time, duration); 925 now = pos * (to - from) + from; 926 } 927 elem.style[prop] = now + 'px'; 928 }, 10); 929 return timer; 930} 931function getBrowserHeight() { 932 if ( window.innerHeight ) { 933 return window.innerHeight; 934 } 935 else if ( document.documentElement && document.documentElement.clientHeight !== 0 ) { 936 return document.documentElement.clientHeight; 937 } 938 else if ( document.body ) { 939 return document.body.clientHeight; 940 } 941 return 0; 942} 943function debounce(func, wait, immediate) { 944 var timeout, result; 945 return function() { 946 var context = this, args = arguments; 947 var later = function() { 948 timeout = null; 949 if (!immediate) result = func.apply(context, args); 950 }; 951 var callNow = immediate && !timeout; 952 clearTimeout(timeout); 953 timeout = setTimeout(later, wait); 954 if (callNow) result = func.apply(context, args); 955 return result; 956 }; 957} 958 959window.SpSlidemenu = SpSlidemenu; 960 961})(window, window.document);
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.