1/*! 2 * multiscroll.js 0.2.3 3 * https://github.com/alvarotrigo/multiscroll.js 4 * 5 * @license 6 * Get a multiScroll.js Commercial License for commercial use 7 * https://alvarotrigo.com/multiScroll/pricing/ 8 * 9 * Copyright (C) 2018 http://alvarotrigo.com/multiScroll/ - A project by Alvaro Trigo 10 */ 11(function($, window, document, Math, undefined) { 12 13 $.fn.multiscroll = function(options) { 14 var MS = $.fn.multiscroll; 15 var isOK = options && new RegExp('([\\d\\w]{8}-){3}[\\d\\w]{8}|^(?=.*?[A-Y])(?=.*?[a-y])(?=.*?[0-8])(?=.*?[#?!@$%^&*-]).{8,}$').test(options['li'+'cen'+'seK' + 'e' + 'y']) || document.domain.indexOf('al'+'varotri' +'go' + '.' + 'com') > -1; 16 var NO_TRANSITION = 'ms-notransition'; 17 var canScroll = true; 18 var scrollings = []; 19 var afterSectionLoadsId; 20 var g_transitionLapseId; 21 22 // Create some defaults, extending them with any options that were provided 23 options = $.extend({ 24 'verticalCentered' : true, 25 'scrollingSpeed': 700, 26 'easing': 'easeInQuart', 27 'easingcss3': 'ease-out', 28 'menu': false, 29 'sectionsColor': [], 30 'anchors':[], 31 'navigation': false, 32 'navigationPosition': 'right', 33 'navigationColor': '#000', 34 'navigationTooltips': [], 35 'loopBottom': false, 36 'loopTop': false, 37 'css3': true, 38 'paddingTop': 0, 39 'paddingBottom': 0, 40 'fixedElements': null, 41 'normalScrollElements': null, 42 'keyboardScrolling': true, 43 'touchSensitivity': 5, 44 45 // Custom selectors 46 'sectionSelector': '.ms-section', 47 'leftSelector': '.ms-left', 48 'rightSelector': '.ms-right', 49 50 //events 51 'afterLoad': null, 52 'onLeave': null, 53 'afterRender': null, 54 'afterResize': null 55 }, options); 56 57 // adding default easing 58 $.extend($.easing, { 59 easeInQuart: function (x, t, b, c, d) { 60 return c*(t/=d)*t*t*t + b; 61 } 62 }); 63 64 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 65 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 66 67 // adding class namef for right and left blocks 68 if (options.rightSelector !== '.ms-right') { 69 $(options.rightSelector).addClass('ms-right'); 70 } 71 72 if (options.leftSelector !== '.ms-left') { 73 $(options.leftSelector).addClass('ms-left'); 74 } 75 76 var numberSections = $('.ms-left').find('.ms-section').length; 77 var nav; 78 var windowHeight = $(window).height(); 79 var MSPointer = getMSPointer(); 80 var events = { 81 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer.move, 82 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer.down 83 }; 84 85 //only once my friend! 86 // displayWarnings(); 87 88 //timeouts 89 var resizeId; 90 91 addMouseWheelHandler(); 92 addTouchHandler(); 93 94 //if css3 is not supported, it will use jQuery animations 95 if(options.css3){ 96 options.css3 = support3d(); 97 } 98 99 /** 100 * Used only this css when no elementor 101 */ 102 103 // $('html, body').css({ 104 // 'overflow' : 'hidden', 105 // 'height' : '100%' 106 // }); 107 108 //adding class names to each sections 109 if (options.sectionSelector !== '.ms-section') { 110 $(options.sectionSelector).each(function(){ 111 $(this).addClass('ms-section'); 112 }); 113 } 114 115 //creating the navigation dots 116 if (options.navigation) { 117 $('body').append('<div id="multiscroll-nav"><ul></ul></div>'); 118 nav = $('#multiscroll-nav'); 119 120 nav.css('color', options.navigationColor); 121 nav.addClass(options.navigationPosition); 122 } 123 // else{ // Used only this js when use widget elementor 124 // nav = $('#multiscroll-nav'); 125 // if(nav.length) nav.remove(); 126 // } 127 128 $('.ms-right, .ms-left').css({ 129 'width': '50%', 130 'position': 'absolute', 131 'height': '100%',
132 '-ms-touch-action': 'none' 133 }); 134 135 $('.ms-right').css({ 136 'right': '1px', //http://stackoverflow.com/questions/23675457/chrome-and-opera-creating-small-padding-when-using-displaytable 137 'top': '0', 138 '-ms-touch-action': 'none', 139 'touch-action': 'none' 140 }); 141 142 $('.ms-left').css({ 143 'left': '0', 144 'top': '0', 145 '-ms-touch-action': 'none', 146 'touch-action': 'none' 147 }); 148 149 150 $('.ms-left .ms-section, .ms-right .ms-section').each(function(){ 151 var sectionIndex = $(this).index(); 152 153 if(options.paddingTop || options.paddingBottom){ 154 $(this).css('padding', options.paddingTop + ' 0 ' + options.paddingBottom + ' 0'); 155 } 156 157 if (typeof options.sectionsColor[sectionIndex] !== 'undefined') { 158 $(this).css('background-color', options.sectionsColor[sectionIndex]); 159 } 160 161 if (typeof options.anchors[sectionIndex] !== 'undefined') { 162 $(this).attr('data-anchor', options.anchors[sectionIndex]); 163 } 164 165 if(options.verticalCentered){ 166 addTableClass($(this)); 167 } 168 169 //only for the left panel 170 if($(this).closest('.ms-left').length && options.navigation) { 171 var link = ''; 172 if(options.anchors.length){ 173 link = options.anchors[sectionIndex]; 174 } 175 var tooltip = options.navigationTooltips[sectionIndex]; 176 if(typeof tooltip === 'undefined'){ 177 tooltip = ''; 178 } 179 if (options.navigation) { 180 nav.find('ul').append('<li data-tooltip="' + tooltip + '"><a href="#' + link + '"><span></span></a></li>'); 181 } 182 } 183 }); 184 185 //inverting the right panel 186 $('.ms-right').html( $('.ms-right').find('.ms-section').get().reverse()); 187 188 $('.ms-left .ms-section, .ms-right .ms-section').each(function(){ 189 var sectionIndex = $(this).index(); 190 191 $(this).css({ 192 'height': '100%' 193 }); 194 195 196 if(!sectionIndex && options.navigation ){ 197 //activating the navigation bullet 198 nav.find('li').eq(sectionIndex).find('a').addClass('active'); 199 } 200 }).promise().done(function(){ 201 202 //if no active section is defined, the 1st one will be the default one 203 if(!$('.ms-left .ms-section.active').length){ 204 $('.ms-right').find('.ms-section').last().addClass('active'); 205 $('.ms-left').find('.ms-section').first().addClass('active'); 206 } 207 208 //vertical centered of the navigation + first bullet active 209 if(options.navigation){ 210 nav.css('margin-top', '-' + (nav.height()/2) + 'px'); 211 } 212 $.isFunction( options.afterRender ) && options.afterRender.call( this); 213 214 //scrolling to the defined active section and adjusting right and left panels 215 silentScroll(); 216 217 //setting the class for the body element 218 setBodyClass(); 219 220 if (document.readyState == 'complete'){ 221 scrollToAnchor(); 222 }else{ 223 $(window).on('load', function() { 224 scrollToAnchor(); 225 }); 226 } 227 }); 228 229 230 //detecting any change on the URL to scroll to the given anchor link 231 //(a way to detect back history button as we play with the hashes on the URL) 232 $(window).on('hashchange', hashChangeHandler); 233 234 function hashChangeHandler(){ 235 var value = window.location.hash.replace('#', ''); 236 var sectionAnchor = value; 237 238 if(sectionAnchor.length){ 239 var section = $('.ms-left').find('[data-anchor="'+sectionAnchor+'"]'); 240 241 if(section.length){ 242 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' ); 243 244 if (isFirstScrollMove || sectionAnchor !== lastScrolledDestiny){ 245 scrollPage(section); 246 } 247 } 248 } 249 }; 250 251 252 /** 253 * Sliding with arrow keys, both, vertical and horizontal 254 */ 255 $(document).keydown(keydownHandler); 256 257
258 var keydownId; 259 function keydownHandler(e) { 260 clearTimeout(keydownId); 261 262 var activeElement = $(document.activeElement); 263 264 if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 265 options.keyboardScrolling){ 266 var keyCode = e.which; 267 268 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 269 var keyControls = [40, 38, 32, 33, 34]; 270 if($.inArray(keyCode, keyControls) > -1){ 271 e.preventDefault(); 272 } 273 274 keydownId = setTimeout(function(){ 275 onkeydown(e); 276 },150); 277 } 278 } 279 280 /** 281 * Sliding with arrow keys, both, vertical and horizontal 282 */ 283 function onkeydown(e){ 284 var shiftPressed = e.shiftKey; 285 286 //do nothing if we can not scroll 287 if(!canScroll){ 288 return; 289 } 290 291 switch (e.which) { 292 //up 293 case 38: 294 case 33: 295 MS.moveSectionUp(); 296 break; 297 298 //down 299 case 32: //spacebar 300 if(shiftPressed){ 301 MS.moveSectionUp(); 302 break; 303 } 304 case 40: 305 case 34: 306 MS.moveSectionDown(); 307 break; 308 309 //Home 310 case 36: 311 MS.moveTo(1); 312 break; 313 314 //End 315 case 35: 316 MS.moveTo( $('.ms-left .ms-section').length); 317 break; 318 319 default: 320 return; // exit this handler for other keys 321 } 322 } 323 324 /** 325 * Disabling any action when pressing of the mouse wheel (Chrome, IE, Opera, Safari) 326 */ 327 $(document).mousedown(function(e) { 328 if(e.button == 1){ 329 e.preventDefault(); 330 return false; 331 } 332 }); 333 334 function navClickHandler(e) { 335 e.preventDefault(); 336 var index = $(this).parent().index(); 337 scrollPage($('.ms-left .ms-section').eq(index)); 338 } 339 340 //navigation action 341 $(document).on('click', '#multiscroll-nav a', navClickHandler); 342 343 function navMouseEnterHandler() { 344 var tooltip = $(this).data('tooltip'); 345 $('<div class="multiscroll-tooltip ' + options.navigationPosition +'">' + tooltip + '</div>').hide().appendTo($(this)).fadeIn(200); 346 } 347 348 function navMouseLeaveHandler() { 349 $(this).find('.multiscroll-tooltip').fadeOut(200, function() { 350 $(this).remove(); 351 }); 352 } 353 354 //navigation tooltips 355 $(document).on({ 356 mouseenter: navMouseEnterHandler, 357 mouseleave: navMouseLeaveHandler 358 }, '#multiscroll-nav li'); 359 360 361 if(options.normalScrollElements){ 362 $(document).on('mouseenter', options.normalScrollElements, function () { 363 MS.setMouseWheelScrolling(false); 364 }); 365 366 $(document).on('mouseleave', options.normalScrollElements, function(){ 367 MS.setMouseWheelScrolling(true); 368 }); 369 } 370 371 372 //when resizing the site, we adjust the heights of the sections 373 $(window).on('resize', resizeHandler); 374 375 376 var previousHeight = windowHeight; 377 378 /** 379 * When resizing is finished, we adjust the slides sizes and positions 380 */ 381 function resizeHandler() { 382 // rebuild immediately on touch devices 383 if (isTouchDevice) { 384 var activeElement = $(document.activeElement); 385 386 //if the keyboard is NOT visible 387 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 388 var currentHeight = $(window).height(); 389 390 //making sure the change in the viewport size is enough to force a rebuild. (20 % of the window to avoid problems when hidding scroll bars) 391 if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 392 reBuild(true); 393 previousHeight = currentHeight; 394 } 395 } 396 }else{ 397 //in order to call the functions only when the resize is finished 398 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 399 clearTimeout(resizeId); 400 401 resizeId = setTimeout(function(){ 402 reBuild(true); 403 }, 350); 404 } 405 } 406 407 /** 408 * When resizing is finished, we adjust the slides sizes and positions 409 */ 410 function reBuild(resizing){ 411 windowHeight = $(window).height(); 412 $('.ms-tableCell').each(function() { 413 $(this).css({ height: getTableHeight($(this).parent()) }); 414 }); 415 416 if(options.scrollOverflow){ 417 scrollBarHandler.createScrollBarForAll(); 418 } 419 420 silentScroll(); 421 $.isFunction( options.afterResize ) && options.afterResize.call( this); 422 } 423 424 function silentScroll(){ 425 //moving the right section to the bottom 426 if(options.css3){ 427 transformContainer($('.ms-left'), 'translate3d(0px, -' + $('.ms-left').find('.ms-section.active').position().top + 'px, 0px)', false); 428 transformContainer($('.ms-right'), 'translate3d(0px, -' + $('.ms-right').find('.ms-section.active').position().top + 'px, 0px)', false); 429 }else{ 430 $('.ms-left').css('top', -$('.ms-left').find('.ms-section.active').position().top ); 431 $('.ms-right').css('top', -$('.ms-right').find('.ms-section.active').position().top ); 432 } 433 } 434 435 MS.moveSectionUp = function(){ 436 var prev = $('.ms-left .ms-section.active').prev('.ms-section'); 437 438 if(!prev.length && options.loopTop){ 439 prev = $('.ms-left .ms-section').last(); 440 } 441 442 if (prev.length) { 443 scrollPage(prev); 444 } 445 }; 446 447 MS.moveSectionDown = function (){ 448 var next = $('.ms-left .ms-section.active').next('.ms-section'); 449 450 if(!next.length && options.loopBottom ){ 451 next = $('.ms-left .ms-section').first(); 452 } 453 454 if(next.length){ 455 scrollPage(next); 456 } 457 }; 458 459 MS.moveTo = function (section){ 460 var destiny = ''; 461 462 if(isNaN(section)){ 463 destiny = $('.ms-left [data-anchor="'+section+'"]'); 464 }else{ 465 destiny = $('.ms-left .ms-section').eq( (section -1) ); 466 } 467 468 scrollPage(destiny); 469 }; 470 471 function scrollPage(leftDestination){ 472 var leftDestinationIndex = leftDestination.index(); 473 var rightDestination = $('.ms-right').find('.ms-section').eq( numberSections -1 - leftDestinationIndex); 474 var rightDestinationIndex = numberSections - 1 - leftDestinationIndex; 475 var anchorLink = leftDestination.data('anchor'); 476 var activeSection = $('.ms-left .ms-section.active'); 477 var leavingSection = activeSection.index() + 1; 478 var yMovement = getYmovement(leftDestination); 479 var isFastSpeed = options.scrollingSpeed < 700; 480 var transitionLapse = isFastSpeed ? 700 : options.scrollingSpeed; 481 482 //preventing from activating the MouseWheelHandler event 483 //more than once if the page is scrolling 484 canScroll = false; 485 486 var topPos = { 487 'left' : leftDestination.position().top, 488 'right': rightDestination.position().top 489 }; 490 491 rightDestination.addClass('active').siblings().removeClass('active'); 492 leftDestination.addClass('active').siblings().removeClass('active'); 493 494 setURLHash(anchorLink); 495 496 // Use CSS3 translate functionality or... 497 if (options.css3){ 498 499 //callback (onLeave) 500 $.isFunction(options.onLeave) && options.onLeave.call(this, leavingSection, (leftDestinationIndex + 1), yMovement); 501 502 var translate3dLeft = 'translate3d(0px, -' + topPos['left'] + 'px, 0px)'; 503 var translate3dRight = 'translate3d(0px, -' + topPos['right'] + 'px, 0px)'; 504 505 transformContainer($('.ms-left'), translate3dLeft, true); 506 transformContainer($('.ms-right'), translate3dRight, true); 507 508 if(options.scrollingSpeed){ 509 clearTimeout(afterSectionLoadsId); 510 afterSectionLoadsId = setTimeout(function () { 511 //callback (afterLoad) 512 $.isFunction(options.afterLoad) && options.afterLoad.call(this, anchorLink, (leftDestinationIndex + 1)); 513 514 //disabling canScroll when using fastSpeed 515 canScroll = !isFastSpeed; 516 }, options.scrollingSpeed); 517 }else{ 518 $.isFunction(options.afterLoad) && options.afterLoad.call(this, anchorLink, (leftDestinationIndex + 1)); 519 } 520 }else{ 521 //callback (onLeave) 522 $.isFunction(options.onLeave) && options.onLeave.call(this, leavingSection, (leftDestinationIndex + 1), yMovement); 523 524 $('.ms-left').animate({ 525 'top': -topPos['left'] 526 }, options.scrollingSpeed, options.easing, function(){ 527 $.isFunction(options.afterLoad) && options.afterLoad.call(this, anchorLink, (leftDestinationIndex + 1)); 528 529 canScroll = !isFastSpeed; 530 }); 531 532 $('.ms-right').animate({ 533 'top': -topPos['right'] 534 }, options.scrollingSpeed, options.easing); 535 } 536 537 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 538 lastScrolledDestiny = anchorLink; 539 540 activateMenuElement(anchorLink); 541 activateNavDots(anchorLink, leftDestinationIndex); 542 543 // enabling canScroll after the minimum transition laps 544 if(isFastSpeed){ 545 clearTimeout(g_transitionLapseId); 546 g_transitionLapseId = setTimeout(function(){ 547 canScroll = true; 548 }, transitionLapse); 549 } 550 } 551 552 /** 553 * Removes the auto scrolling action fired by the mouse wheel and tackpad. 554 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 555 */ 556 function removeMouseWheelHandler(){ 557 if (document.addEventListener) { 558 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 559 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 560 } else { 561 document.detachEvent("onmousewheel", MouseWheelHandler); //IE 6/7/8 562 } 563 } 564 565 /** 566 * Adds the auto scrolling action for the mouse wheel and tackpad. 567 * After this function is called, the mousewheel and trackpad movements will scroll through sections 568 */ 569 function addMouseWheelHandler(){ 570 if (document.addEventListener) { 571 document.addEventListener("mousewheel", MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 572 document.addEventListener("wheel", MouseWheelHandler, false); //Firefox 573 } else { 574 document.attachEvent("onmousewheel", MouseWheelHandler); //IE 6/7/8 575 } 576 } 577 578 /** 579 * Detecting mousewheel scrolling 580 * 581 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 582 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 583 */ 584 var prevTime = new Date().getTime(); 585 586 function MouseWheelHandler(e) { 587 var curTime = new Date().getTime(); 588 589 // cross-browser wheel delta 590 e = e ||Â window.event; 591 var value = e.wheelDelta || -e.deltaY || -e.detail; 592 var delta = Math.max(-1, Math.min(1, value)); 593 594 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 595 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 596 597 //time difference between the last scroll and the current one 598 var timeDiff = curTime-prevTime; 599 prevTime = curTime; 600 601 //keeping record of the previous scrollings 602 scrollings.push(Math.abs(value)); 603 604 //haven't they scrolled in a while? 605 //(enough to be consider a different scrolling action to scroll another section) 606 if(timeDiff > 200){ 607 //emptying the array, we dont care about old scrollings for our averages 608 scrollings = []; 609 } 610 611 if (canScroll) { 612 var averageEnd = getAverage(scrollings, 10); 613 var averageMiddle = getAverage(scrollings, 70); 614 var isAccelerating = averageEnd >= averageMiddle; 615 616 if(isAccelerating && isScrollingVertically){ 617 //scrolling down? 618 if (delta < 0) { 619 MS.moveSectionDown(); 620 } 621 622 //scrolling up? 623 else { 624 MS.moveSectionUp(); 625 } 626 } 627 } 628 629 return false; 630 } 631 632 /** 633 * Gets the average of the last `number` elements of the given array. 634 */ 635 function getAverage(elements, number){
636 var sum = 0; 637 638 //taking `number` elements from the end to make the average, if there are not enought, 1 639 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 640 641 for(var i = 0; i < lastElements.length; i++){ 642 sum = sum + lastElements[i]; 643 } 644 645 return Math.ceil(sum/number); 646 } 647 648 /** 649 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 650 */ 651 function transformContainer(container, translate3d, animated){ 652 if(animated){ 653 addAnimation(container); 654 }else{ 655 removeAnimation(container); 656 } 657 658 container.css(getTransforms(translate3d)); 659 } 660 661 /** 662 * Adds transition animations for the given element 663 */ 664 function addAnimation(element){ 665 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 666 667 element.removeClass(NO_TRANSITION); 668 return element.css({ 669 '-webkit-transition': transition, 670 'transition': transition 671 }); 672 } 673 674 /** 675 * Remove transition animations for the given element 676 */ 677 function removeAnimation(element){ 678 return element.addClass(NO_TRANSITION); 679 } 680 681 /** 682 * Returns the transform styles for all browsers 683 */ 684 function getTransforms(translate3d){ 685 return { 686 '-webkit-transform': translate3d, 687 '-moz-transform': translate3d, 688 '-ms-transform':translate3d, 689 'transform': translate3d 690 }; 691 } 692 693 /** 694 * Activating the website navigation dots according to the given slide name. 695 */ 696 function activateNavDots(name, sectionIndex){ 697 if(options.navigation){ 698 $('#multiscroll-nav').find('.active').removeClass('active'); 699 if(name){ 700 $('#multiscroll-nav').find('a[href="#' + name + '"]').addClass('active'); 701 }else{ 702 $('#multiscroll-nav').find('li').eq(sectionIndex).find('a').addClass('active'); 703 } 704 } 705 } 706 707 /** 708 * Activating the website main menu elements according to the given slide name. 709 */ 710 function activateMenuElement(name){ 711 if(options.menu){ 712 $(options.menu).find('.active').removeClass('active'); 713 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass('active'); 714 } 715 } 716 717 /** 718 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 719 * from the current section. 720 */ 721 function getYmovement(destiny){ 722 var fromIndex = $('.ms-left .ms-section.active').index(); 723 var toIndex = destiny.index(); 724 725 if(fromIndex > toIndex){ 726 return 'up'; 727 } 728 return 'down'; 729 } 730 731 732 /** 733 * Sets the URL hash for a section with slides 734 */ 735 function setURLHash(anchorLink){ 736 if(options.anchors.length){ 737 location.hash = anchorLink; 738 } 739 740 setBodyClass(); 741 } 742 743 /** 744 * Sets a class for the body of the page depending on the active section / slide 745 */ 746 function setBodyClass(){ 747 var section = $('.ms-left .ms-section.active'); 748 var sectionAnchor = section.data('anchor'); 749 var sectionIndex = section.index(); 750 751 var text = String(sectionIndex); 752 753 if(options.anchors.length){ 754 text = sectionAnchor; 755 } 756 757 //changing slash for dash to make it a valid CSS style 758 text = text.replace('/', '-').replace('#',''); 759 760 //removing previous anchor classes 761 var classRe = new RegExp('\\b\\s?' + 'ms-viewing' + '-[^\\s]+\\b', "g"); 762 $('body')[0].className = $('body')[0].className.replace(classRe, ''); 763 764 //adding the current anchor 765 $('body').addClass('ms-viewing-' + text); 766 } 767 768 769 /** 770 * Checks for translate3d support 771 * @return boolean 772 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 773 */ 774 function support3d() { 775 var el = document.createElement('p'), 776 has3d, 777 transforms = { 778 'webkitTransform':'-webkit-transform',
779 'OTransform':'-o-transform', 780 'msTransform':'-ms-transform', 781 'MozTransform':'-moz-transform', 782 'transform':'transform' 783 }; 784 785 // Add it to the body to get the computed style. 786 document.body.insertBefore(el, null); 787 788 for (var t in transforms) { 789 if (el.style[t] !== undefined) { 790 el.style[t] = "translate3d(1px,1px,1px)"; 791 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 792 } 793 } 794 795 document.body.removeChild(el); 796 797 return (has3d !== undefined && has3d.length > 0 && has3d !== "none"); 798 } 799 800 /** 801 * Wraps an element in order to center it vertically by using a class style. 802 */ 803 function addTableClass(element){ 804 element.addClass('ms-table').wrapInner('<div class="ms-tableCell" style="height: ' + getTableHeight(element) + 'px" />'); 805 } 806 807 /** 808 * Gets the height of the section after removing the paddings. 809 */ 810 function getTableHeight(section){ 811 var sectionHeight = windowHeight; 812 813 if(options.paddingTop || options.paddingBottom){ 814 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 815 sectionHeight = (windowHeight - paddings); 816 } 817 818 return sectionHeight; 819 } 820 821 822 /** 823 * Scrolls the page to the existent anchor in the URL 824 */ 825 function scrollToAnchor(){ 826 //getting the anchor link in the URL and deleting the `#` 827 var sectionAnchor = window.location.hash.replace('#', ''); 828 var section = $('.ms-left .ms-section[data-anchor="'+sectionAnchor+'"]'); 829 830 if(sectionAnchor.length && section.length){ 831 scrollPage(section); 832 } 833 } 834 835 /** 836 * Adds or remove the possiblity of scrolling through sections by using the keyboard arrow keys 837 */ 838 MS.setKeyboardScrolling = function (value){ 839 options.keyboardScrolling = value; 840 }; 841 842 /** 843 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. 844 */ 845 MS.setMouseWheelScrolling = function (value){ 846 if(value){ 847 addMouseWheelHandler(); 848 }else{ 849 removeMouseWheelHandler(); 850 } 851 }; 852 853 /** 854 * Defines the scrolling speed 855 */ 856 MS.setScrollingSpeed = function(value){ 857 options.scrollingSpeed = value; 858 }; 859 860 861 862 var touchStartY = 0; 863 var touchStartX = 0; 864 var touchEndY = 0; 865 var touchEndX = 0; 866 867 /* Detecting touch events 868 869 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 870 * This way, the touchstart and the touch moves shows an small difference between them which is the 871 * used one to determine the direction. 872 */ 873 function touchMoveHandler(e){ 874 875 if(isReallyTouch(e)){ 876 //preventing the easing on iOS devices 877 event.preventDefault(); 878 879 var activeSection = $('.ms-left .ms-section.active'); 880 881 if (canScroll) { //if theres any # 882 var touchEvents = getEventsPage(e); 883 touchEndY = touchEvents['y']; 884 touchEndX = touchEvents['x']; 885 886 //is the movement greater than the minimum resistance to scroll? 887 if (Math.abs(touchStartY - touchEndY) > ($(window).height() / 100 * options.touchSensitivity)) { 888 889 if (touchStartY > touchEndY) { 890 MS.moveSectionDown(); 891 892 } else if (touchEndY > touchStartY) { 893 MS.moveSectionUp(); 894 } 895 } 896 } 897 } 898 } 899 900 /** 901 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 902 * this way we make sure that is really a touch event what IE is detecting. 903 */ 904 function isReallyTouch(e){ 905 //if is not IE || IE is detecting `touch` or `pen` 906 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 907 } 908 909 910 /** 911 * Handler to get he coordinates of the starting touch 912 */ 913 function touchStartHandler(e){ 914 915 if(isReallyTouch(e)){ 916 var touchEvents = getEventsPage(e); 917 touchStartY = touchEvents['y']; 918 touchStartX = touchEvents['x']; 919 } 920 } 921 922 923 /** 924 * Adds the possibility to auto scroll through sections on touch devices. 925 */ 926 function addTouchHandler(){ 927 if(isTouch || isTouchDevice){ 928 document.removeEventListener(events.touchstart, touchStartHandler); 929 document.removeEventListener(events.touchmove, touchMoveHandler, {passive: false}); 930 931 document.addEventListener(events.touchstart, touchStartHandler); 932 document.addEventListener(events.touchmove, touchMoveHandler, {passive: false}); 933 } 934 } 935 936 /** 937 * Removes the auto scrolling for touch devices. 938 */ 939 function removeTouchHandler(){ 940 if(isTouch || isTouchDevice){ 941 document.removeEventListener(events.touchstart, touchStartHandler); 942 document.removeEventListener(events.touchmove, touchMoveHandler, {passive: false}); 943 } 944 } 945 946 /* 947 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11)
948 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 949 */ 950 function getMSPointer(){ 951 var pointer; 952 953 //IE >= 11 954 if(window.PointerEvent){ 955 pointer = { down: "pointerdown", move: "pointermove"}; 956 } 957 958 //IE < 11 959 else{ 960 pointer = { down: "MSPointerDown", move: "MSPointerMove"}; 961 } 962 963 return pointer; 964 } 965 966 /** 967 * Gets the pageX and pageY properties depending on the browser. 968 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 969 */ 970 function getEventsPage(e){ 971 var events = []; 972 973 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 974 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 975 976 //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 977 if(isTouch && isReallyTouch(e) && typeof e.touches !== 'undefined'){ 978 events.y = e.touches[0].pageY; 979 events.x = e.touches[0].pageX; 980 } 981 982 return events; 983 } 984 985 /** 986 * Destroy multiscroll.js plugin's events 987 */ 988 MS.destroy = function() { 989 MS.setKeyboardScrolling(false); 990 MS.setMouseWheelScrolling(false); 991 removeTouchHandler(); 992 993 $(window) 994 .off('hashchange', hashChangeHandler) 995 .off('resize', resizeHandler); 996 997 $(document) 998 .off('mouseenter', '#multiscroll-nav li') 999 .off('mouseleave', '#multiscroll-nav li') 1000 .off('click', '#multiscroll-nav a'); 1001 }; 1002 1003 /** 1004 * Build multiscroll.js plugin's events after destroy 1005 */ 1006 MS.build = function() { 1007 MS.setKeyboardScrolling(true); 1008 MS.setMouseWheelScrolling(true); 1009 addTouchHandler(); 1010 1011 $(window) 1012 .on('hashchange', hashChangeHandler) 1013 .on('resize', resizeHandler); 1014 1015 $(document) 1016 .on('mouseenter', '#multiscroll-nav li', navMouseEnterHandler) 1017 .on('mouseleave', '#multiscroll-nav li', navMouseLeaveHandler) 1018 .on('click', '#multiscroll-nav a', navClickHandler); 1019 }; 1020 1021 /** 1022 * Displays warnings 1023 */ 1024 // function displayWarnings(){ 1025 // var l = options['li' + 'c' + 'enseK' + 'e' + 'y']; 1026 // var msgStyle = 'font-size: 15px;background:yellow;'; 1027 1028 // if(!isOK){ 1029 // showError('error', 'multiScroll.js version 0.2.3 has changed its license to GPLv3 and it requires a `licenseKey` option. Read about it here:'); 1030 // showError('error', 'https://github.com/alvarotrigo/multiScroll.js#options'); 1031 // } 1032 // } 1033 1034 /** 1035 * Shows a message in the console of the given type. 1036 */ 1037 // function showError(type, text){ 1038 // window.console && window.console[type] && window.console[type]('multiScroll: ' + text); 1039 // } 1040 }; 1041})(jQuery, window, document, Math);
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.