1/*! 2 * fullPage 2.9.6 3 * https://github.com/alvarotrigo/fullPage.js 4 * @license MIT licensed 5 * 6 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo 7 */ 8var tabKeyBreaked = false; 9function tabKeyBreakFunc(e){ 10 tabKeyBreaked = true; 11 setTimeout(function(){ 12 tabKeyBreaked = false; 13 },500); 14} 15(function(global, factory) { 16 'use strict'; 17 if (typeof define === 'function' && define.amd) { 18 define(['jquery'], function($) { 19 return factory($, global, global.document, global.Math); 20 }); 21 } else if (typeof exports === "object" && exports) { 22 module.exports = factory(require('jquery'), global, global.document, global.Math); 23 } else { 24 factory(jQuery, global, global.document, global.Math); 25 } 26})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { 27 'use strict'; 28 29 // keeping central set of classnames and selectors 30 var WRAPPER = 'fullpage-wrapper'; 31 var WRAPPER_SEL = '.' + WRAPPER; 32 33 // slimscroll 34 var SCROLLABLE = 'fp-scrollable'; 35 var SCROLLABLE_SEL = '.' + SCROLLABLE; 36 37 // util 38 var RESPONSIVE = 'fp-responsive'; 39 var NO_TRANSITION = 'fp-notransition'; 40 var DESTROYED = 'fp-destroyed'; 41 var ENABLED = 'fp-enabled'; 42 var VIEWING_PREFIX = 'fp-viewing'; 43 var ACTIVE = 'active'; 44 var ACTIVE_SEL = '.' + ACTIVE; 45 var COMPLETELY = 'fp-completely'; 46 var COMPLETELY_SEL = '.' + COMPLETELY; 47 48 // section 49 var SECTION_DEFAULT_SEL = '.section'; 50 var SECTION = 'fp-section'; 51 var SECTION_SEL = '.' + SECTION; 52 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 53 var SECTION_FIRST_SEL = SECTION_SEL + ':first'; 54 var SECTION_LAST_SEL = SECTION_SEL + ':last'; 55 var TABLE_CELL = 'fp-tableCell'; 56 var TABLE_CELL_SEL = '.' + TABLE_CELL; 57 var AUTO_HEIGHT = 'fp-auto-height'; 58 var AUTO_HEIGHT_SEL = '.fp-auto-height'; 59 var NORMAL_SCROLL = 'fp-normal-scroll'; 60 var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; 61 62 // section nav 63 var SECTION_NAV = 'fp-nav'; 64 var SECTION_NAV_SEL = '#' + SECTION_NAV; 65 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 66 var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; 67 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; 68 69 // slide 70 var SLIDE_DEFAULT_SEL = '.slide'; 71 var SLIDE = 'fp-slide'; 72 var SLIDE_SEL = '.' + SLIDE; 73 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 74 var SLIDES_WRAPPER = 'fp-slides'; 75 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 76 var SLIDES_CONTAINER = 'fp-slidesContainer'; 77 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 78 var TABLE = 'fp-table'; 79 80 // slide nav 81 var SLIDES_NAV = 'fp-slidesNav'; 82 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 83 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 84 var SLIDES_ARROW = 'fp-controlArrow'; 85 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 86 var SLIDES_PREV = 'fp-prev'; 87 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 88 var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; 89 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 90 var SLIDES_NEXT = 'fp-next'; 91 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 92 var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; 93 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 94 95 var $window = $(window); 96 var $document = $(document); 97 98 $.fn.fullpage = function(options) { 99 //only once my friend! 100 if($('html').hasClass(ENABLED)){ displayWarnings(); return; } 101 102 // common jQuery objects 103 var $htmlBody = $('html, body'); 104 var $body = $('body'); 105 106 var FP = $.fn.fullpage; 107 108 // Creating some defaults, extending them with any options that were provided 109 options = $.extend({ 110 //navigation 111 menu: false, 112 anchors:[], 113 lockAnchors: false, 114 navigation: false, 115 navigationPosition: 'right', 116 navigationTooltips: [], 117 showActiveTooltip: false, 118 slidesNavigation: false, 119 slidesNavPosition: 'bottom', 120 scrollBar: false, 121 hybrid: false, 122 123 //scrolling 124 css3: true, 125 scrollingSpeed: 700, 126 autoScrolling: true, 127 fitToSection: true, 128 fitToSectionDelay: 1000, 129 easing: 'easeInOutCubic', 130 easingcss3: 'ease', 131 loopBottom: false, 132 loopTop: false, 133 loopHorizontal: true, 134 continuousVertical: false, 135 continuousHorizontal: false, 136 scrollHorizontally: false, 137 interlockedSlides: false, 138 dragAndMove: false, 139 offsetSections: false, 140 resetSliders: false, 141 fadingEffect: false, 142 normalScrollElements: null, 143 scrollOverflow: false, 144 scrollOverflowReset: false, 145 scrollOverflowHandler: $.fn.fp_scrolloverflow ? $.fn.fp_scrolloverflow.iscrollHandler : null, 146 scrollOverflowOptions: null, 147 touchSensitivity: 5, 148 normalScrollElementTouchThreshold: 5, 149 bigSectionsDestination: null, 150 151 //Accessibility 152 keyboardScrolling: true, 153 animateAnchor: true, 154 recordHistory: true, 155 156 //design 157 controlArrows: true, 158 controlArrowColor: '#fff', 159 verticalCentered: true, 160 sectionsColor : [], 161 paddingTop: 0, 162 paddingBottom: 0, 163 fixedElements: null, 164 responsive: 0, //backwards compabitility with responsiveWiddth 165 responsiveWidth: 0, 166 responsiveHeight: 0, 167 responsiveSlides: false, 168 parallax: false, 169 parallaxOptions: { 170 type: 'reveal', 171 percentage: 62, 172 property: 'translate' 173 }, 174 175 //Custom selectors 176 sectionSelector: SECTION_DEFAULT_SEL, 177 slideSelector: SLIDE_DEFAULT_SEL, 178 179 //events 180 afterLoad: null, 181 onLeave: null, 182 afterRender: null, 183 afterResize: null, 184 afterReBuild: null, 185 afterSlideLoad: null, 186 onSlideLeave: null, 187 afterResponsive: null, 188 189 lazyLoading: true 190 }, options); 191 192 //flag to avoid very fast sliding for landscape sliders 193 var slideMoving = false; 194 195 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 196 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 197 var container = $(this); 198 var windowsHeight = $window.height(); 199 var isResizing = false; 200 var isWindowFocused = true; 201 var lastScrolledDestiny; 202 var lastScrolledSlide; 203 var canScroll = true; 204 var scrollings = []; 205 var controlPressed; 206 var startingSection; 207 var isScrollAllowed = {}; 208 isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; 209 isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); 210 var MSPointer = getMSPointer(); 211 var events = { 212 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer.move, 213 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer.down 214 }; 215 var scrollBarHandler; 216 217 // taken from https://github.com/udacity/ud891/blob/gh-pages/lesson2-focus/07-modals-and-keyboard-traps/solution/modal.js 218 var focusableElementsString = 'a[href], area[href], input
218:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"], [contenteditable]'; 219 220 //timeouts 221 var resizeId; 222 var afterSectionLoadsId; 223 var afterSlideLoadsId; 224 var scrollId; 225 var scrollId2; 226 var keydownId; 227 var originals = $.extend(true, {}, options); //deep copy 228 229 displayWarnings(); 230 231 //easeInOutCubic animation included in the plugin 232 $.extend($.easing,{ easeInOutCubic: function (x, t, b, c, d) {if ((t/=d/2) < 1) return c/2*t*t*t + b;return c/2*((t-=2)*t*t + 2) + b;}}); 233 234 /** 235 * Sets the autoScroll option. 236 * It changes the scroll bar visibility and the history of the site as a result. 237 */ 238 function setAutoScrolling(value, type){ 239 //removing the transformation 240 if(!value){ 241 silentScroll(0); 242 } 243 244 setVariableState('autoScrolling', value, type); 245 246 var element = $(SECTION_ACTIVE_SEL); 247 248 if(options.autoScrolling && !options.scrollBar){ 249 $htmlBody.css({ 250 'overflow' : 'hidden', 251 'height' : '100%' 252 }); 253 254 setRecordHistory(originals.recordHistory, 'internal'); 255 256 //for IE touch devices 257 container.css({ 258 '-ms-touch-action': 'none', 259 'touch-action': 'none' 260 }); 261 262 if(element.length){ 263 //moving the container up 264 silentScroll(element.position().top); 265 } 266 267 }else{ 268 $htmlBody.css({ 269 'overflow' : 'visible', 270 'height' : 'initial' 271 }); 272 273 setRecordHistory(false, 'internal'); 274 275 //for IE touch devices 276 container.css({ 277 '-ms-touch-action': '', 278 'touch-action': '' 279 }); 280 281 //scrolling the page to the section with no animation 282 if (element.length) { 283 $htmlBody.scrollTop(element.position().top); 284 } 285 } 286 } 287 288 /** 289 * Defines wheter to record the history for each hash change in the URL. 290 */ 291 function setRecordHistory(value, type){ 292 setVariableState('recordHistory', value, type); 293 } 294 295 /** 296 * Defines the scrolling speed 297 */ 298 function setScrollingSpeed(value, type){ 299 setVariableState('scrollingSpeed', value, type); 300 } 301 302 /** 303 * Sets fitToSection 304 */ 305 function setFitToSection(value, type){ 306 setVariableState('fitToSection', value, type); 307 } 308 309 /** 310 * Sets lockAnchors 311 */ 312 function setLockAnchors(value){ 313 options.lockAnchors = value; 314 } 315 316 /** 317 * Adds or remove the possibility of scrolling through sections by using the mouse wheel or the trackpad. 318 */ 319 function setMouseWheelScrolling(value){ 320 if(value){ 321 addMouseWheelHandler(); 322 addMiddleWheelHandler(); 323 }else{ 324 removeMouseWheelHandler(); 325 removeMiddleWheelHandler(); 326 } 327 } 328 329 /** 330 * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 331 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 332 * 333 * @param directions string containing the direction or directions separated by comma. 334 */ 335 function setAllowScrolling(value, directions){ 336 if(typeof directions !== 'undefined'){ 337 directions = directions.replace(/ /g,'').split(','); 338 339 $.each(directions, function (index, direction){ 340 setIsScrollAllowed(value, direction, 'm'); 341 }); 342 } 343 else{ 344 setIsScrollAllowed(value, 'all', 'm'); 345 346 if(value){ 347 setMouseWheelScrolling(true); 348 addTouchHandler(); 349 }else{ 350 setMouseWheelScrolling(false); 351 removeTouchHandler(); 352 } 353 } 354 } 355 356 /** 357 * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys 358 */ 359 function setKeyboardScrolling(value, directions){ 360 if(typeof directions !== 'undefined'){ 361 directions = directions.replace(/ /g,'').split(','); 362 363 $.each(directions, function (index, direction){ 364 setIsScrollAllowed(value, direction, 'k'); 365 }); 366 }else{ 367 setIsScrollAllowed(value, 'all', 'k'); 368 options.keyboardScrolling = value; 369 } 370 } 371 372 /** 373 * Moves the page up one section. 374 */ 375 function moveSectionUp(){ 376 var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); 377 378 //looping to the bottom if there's no more sections above 379 if (!prev.length && (options.loopTop || options.continuousVertical)) {
380 prev = $(SECTION_SEL).last(); 381 } 382 383 if (prev.length) { 384 scrollPage(prev, null, true); 385 } 386 } 387 388 /** 389 * Moves the page down one section. 390 */ 391 function moveSectionDown(){ 392 var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); 393 394 //looping to the top if there's no more sections below 395 if(!next.length && 396 (options.loopBottom || options.continuousVertical)){ 397 next = $(SECTION_SEL).first(); 398 } 399 400 if(next.length){ 401 scrollPage(next, null, false); 402 } 403 } 404 405 /** 406 * Moves the page to the given section and slide with no animation. 407 * Anchors or index positions can be used as params. 408 */ 409 function silentMoveTo(sectionAnchor, slideAnchor){ 410 setScrollingSpeed (0, 'internal'); 411 moveTo(sectionAnchor, slideAnchor); 412 setScrollingSpeed (originals.scrollingSpeed, 'internal'); 413 } 414 415 /** 416 * Moves the page to the given section and slide. 417 * Anchors or index positions can be used as params. 418 */ 419 function moveTo(sectionAnchor, slideAnchor){ 420 var destiny = getSectionByAnchor(sectionAnchor); 421 422 if (typeof slideAnchor !== 'undefined'){ 423 scrollPageAndSlide(sectionAnchor, slideAnchor); 424 }else if(destiny.length > 0){ 425 scrollPage(destiny); 426 } 427 } 428 429 /** 430 * Slides right the slider of the active section. 431 * Optional `section` param. 432 */ 433 function moveSlideRight(section){ 434 moveSlide('right', section); 435 } 436 437 /** 438 * Slides left the slider of the active section. 439 * Optional `section` param. 440 */ 441 function moveSlideLeft(section){ 442 moveSlide('left', section); 443 } 444 445 /** 446 * When resizing is finished, we adjust the slides sizes and positions 447 */ 448 function reBuild(resizing){ 449 if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed 450 451 isResizing = true; 452 453 windowsHeight = $window.height(); //updating global var 454 455 $(SECTION_SEL).each(function(){ 456 var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); 457 var slides = $(this).find(SLIDE_SEL); 458 459 //adjusting the height of the table-cell for IE and Firefox 460 if(options.verticalCentered){ 461 $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); 462 } 463 464 $(this).css('height', windowsHeight + 'px'); 465 466 //adjusting the position fo the FULL WIDTH slides... 467 if (slides.length > 1) { 468 landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); 469 } 470 }); 471 472 if(options.scrollOverflow){ 473 scrollBarHandler.createScrollBarForAll(); 474 } 475 476 var activeSection = $(SECTION_ACTIVE_SEL); 477 var sectionIndex = activeSection.index(SECTION_SEL); 478 479 //isn't it the first section? 480 if(sectionIndex){ 481 //adjusting the position for the current section 482 silentMoveTo(sectionIndex + 1); 483 } 484 485 isResizing = false; 486 $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); 487 $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); 488 } 489 490 /** 491 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 492 * are smaller than the set limit values. 493 */ 494 function setResponsive(active){ 495 var isResponsive = $body.hasClass(RESPONSIVE); 496 497 if(active){ 498 if(!isResponsive){ 499 setAutoScrolling(false, 'internal'); 500 setFitToSection(false, 'internal'); 501 $(SECTION_NAV_SEL).hide(); 502 $body.addClass(RESPONSIVE); 503 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 504 } 505 } 506 else if(isResponsive){ 507 setAutoScrolling(originals.autoScrolling, 'internal'); 508 setFitToSection(originals.autoScrolling, 'internal'); 509 $(SECTION_NAV_SEL).show(); 510 $body.removeClass(RESPONSIVE); 511 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 512 } 513 } 514 515 if($(this).length){ 516 //public functions 517 FP.version = '2.9.5'; 518 FP.setAutoScrolling = setAutoScrolling; 519 FP.setRecordHistory = setRecordHistory;
520 FP.setScrollingSpeed = setScrollingSpeed; 521 FP.setFitToSection = setFitToSection; 522 FP.setLockAnchors = setLockAnchors; 523 FP.setMouseWheelScrolling = setMouseWheelScrolling; 524 FP.setAllowScrolling = setAllowScrolling; 525 FP.setKeyboardScrolling = setKeyboardScrolling; 526 FP.moveSectionUp = moveSectionUp; 527 FP.moveSectionDown = moveSectionDown; 528 FP.silentMoveTo = silentMoveTo; 529 FP.moveTo = moveTo; 530 FP.moveSlideRight = moveSlideRight; 531 FP.moveSlideLeft = moveSlideLeft; 532 FP.fitToSection = fitToSection; 533 FP.reBuild = reBuild; 534 FP.setResponsive = setResponsive; 535 FP.destroy = destroy; 536 537 //functions we want to share across files but which are not 538 //mean to be used on their own by developers 539 FP.shared ={ 540 afterRenderActions: afterRenderActions 541 }; 542 543 init(); 544 545 bindEvents(); 546 } 547 548 function init(){ 549 //if css3 is not supported, it will use jQuery animations 550 if(options.css3){ 551 options.css3 = support3d(); 552 } 553 554 options.scrollBar = options.scrollBar || options.hybrid; 555 556 setOptionsFromDOM(); 557 prepareDom(); 558 setAllowScrolling(true); 559 setAutoScrolling(options.autoScrolling, 'internal'); 560 responsive(); 561 562 //setting the class for the body element 563 setBodyClass(); 564 565 if(document.readyState === 'complete'){ 566 scrollToAnchor(); 567 } 568 $window.on('load', scrollToAnchor); 569 } 570 571 function bindEvents(){ 572 $window 573 //when scrolling... 574 .on('scroll', scrollHandler) 575 576 //detecting any change on the URL to scroll to the given anchor link 577 //(a way to detect back history button as we play with the hashes on the URL) 578 .on('hashchange', hashChangeHandler) 579 580 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 581 .blur(blurHandler) 582 583 //when resizing the site, we adjust the heights of the sections, slimScroll... 584 .resize(resizeHandler); 585 586 $document 587 //Sliding with arrow keys, both, vertical and horizontal 588 .keydown(keydownHandler) 589 590 //to prevent scrolling while zooming 591 .keyup(keyUpHandler) 592 593 //Scrolls to the section when clicking the navigation bullet 594 .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) 595 596 //Scrolls the slider to the given slide destination for the given section 597 .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) 598 599 .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); 600 601 //Scrolling horizontally when clicking on the slider controls. 602 $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); 603 604 /** 605 * Applying normalScroll elements. 606 * Ignoring the scrolls over the specified selectors. 607 */ 608 if(options.normalScrollElements){ 609 $document.on('mouseenter touchstart', options.normalScrollElements, function () { 610 setAllowScrolling(false); 611 }); 612 613 $document.on('mouseleave touchend', options.normalScrollElements, function(){ 614 setAllowScrolling(true); 615 }); 616 } 617 } 618 619 /** 620 * Setting options from DOM elements if they are not provided. 621 */ 622 function setOptionsFromDOM(){ 623 var sections = container.find(options.sectionSelector); 624 625 //no anchors option? Checking for them in the DOM attributes 626 if(!options.anchors.length){ 627 options.anchors = sections.filter('[data-anchor]').map(function(){ 628 return $(this).data('anchor').toString(); 629 }).get(); 630 } 631 632 //no tooltips option? Checking for them in the DOM attributes 633 if(!options.navigationTooltips.length){ 634 options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ 635 return $(this).data('tooltip').toString(); 636 }).get(); 637 } 638 } 639 640 /** 641 * Works over the DOM structure to set it up for the current fullpage options. 642 */ 643 function prepareDom(){ 644 container.css({ 645 'height': '100%', 646 'position': 'relative' 647 }); 648 649 //adding a class to recognize the container internally in the code 650 container.addClass(WRAPPER); 651 $('html').addClass(ENABLED); 652 653 //due to https://github.com/alvarotrigo/fullPage.js/issues/1502 654 windowsHeight = $window.height(); 655 656 container.removeClass(DESTROYED); //in case it was destroyed before initializing it again 657 658 addInternalSelectors(); 659 660 //styling the sections / slides / menu 661 $(SECTION_SEL).each(function(index){ 662 var section = $(this); 663 var slides = section.find(SLIDE_SEL); 664 var numSlides = slides.length; 665 666 //caching the original styles to add them back on destroy('all') 667 section.data('fp-styles', section.attr('style')); 668 669 styleSection(section, index); 670 styleMenu(section, index); 671 672 // if there's any slide 673 if (numSlides > 0) { 674 styleSlides(section, slides, numSlides); 675 }else{ 676 if(options.verticalCentered){ 677 addTableClass(section); 678 } 679 } 680 }); 681 682 //fixed elements need to be moved out of the plugin container due to problems with CSS3. 683 if(options.fixedElements && options.css3){ 684 $(options.fixedElements).appendTo($body); 685 } 686 687 //vertical centered of the navigation + active bullet 688 if(options.navigation){ 689 addVerticalNavigation(); 690 } 691 692 enableYoutubeAPI(); 693 694 if(options.scrollOverflow){ 695 scrollBarHandler = options.scrollOverflowHandler.init(options); 696 }else{ 697 afterRenderActions(); 698 } 699 } 700 701 /** 702 * Styles the horizontal slides for a section. 703 */ 704 function styleSlides(section, slides, numSlides){ 705 var sliderWidth = numSlides * 100; 706 var slideWidth = 100 / numSlides; 707 708 slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />'); 709 slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />'); 710 711 section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); 712 713 if(numSlides > 1){ 714 if(options.controlArrows){ 715 createSlideArrows(section); 716 } 717 718 if(options.slidesNavigation){ 719 addSlidesNavigation(section, numSlides); 720 } 721 } 722 723 slides.each(function(index) { 724 $(this).css('width', slideWidth + '%'); 725 726 if(options.verticalCentered){ 727 addTableClass($(this)); 728 } 729 }); 730 731 var startingSlide = section.find(SLIDE_ACTIVE_SEL); 732 733 //if the slide won't be an starting point, the default will be the first one 734 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
734ide by default. 735 if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ 736 silentLandscapeScroll(startingSlide, 'internal'); 737 }else{ 738 slides.eq(0).addClass(ACTIVE); 739 } 740 } 741 742 /** 743 * Styling vertical sections 744 */ 745 function styleSection(section, index){ 746 //if no active section is defined, the 1st one will be the default one 747 if(!index && $(SECTION_ACTIVE_SEL).length === 0) { 748 section.addClass(ACTIVE); 749 } 750 startingSection = $(SECTION_ACTIVE_SEL); 751 752 section.css('height', windowsHeight + 'px'); 753 754 if(options.paddingTop){ 755 section.css('padding-top', options.paddingTop); 756 } 757 758 if(options.paddingBottom){ 759 section.css('padding-bottom', options.paddingBottom); 760 } 761 762 if (typeof options.sectionsColor[index] !== 'undefined') { 763 section.css('background-color', options.sectionsColor[index]); 764 } 765 766 if (typeof options.anchors[index] !== 'undefined') { 767 section.attr('data-anchor', options.anchors[index]); 768 } 769 } 770 771 /** 772 * Sets the data-anchor attributes to the menu elements and activates the current one. 773 */ 774 function styleMenu(section, index){ 775 if (typeof options.anchors[index] !== 'undefined') { 776 //activating the menu / nav element on load 777 if(section.hasClass(ACTIVE)){ 778 activateMenuAndNav(options.anchors[index], index); 779 } 780 } 781 782 //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 783 if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ 784 $(options.menu).appendTo($body); 785 } 786 } 787 788 /** 789 * Adds internal classes to be able to provide customizable selectors 790 * keeping the link with the style sheet. 791 */ 792 function addInternalSelectors(){ 793 container.find(options.sectionSelector).addClass(SECTION); 794 container.find(options.slideSelector).addClass(SLIDE); 795 } 796 797 /** 798 * Creates the control arrows for the given section 799 */ 800 function createSlideArrows(section){ 801 section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>'); 802 803 if(options.controlArrowColor!='#fff'){ 804 section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); 805 section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); 806 } 807 808 if(!options.loopHorizontal){ 809 section.find(SLIDES_ARROW_PREV_SEL).hide(); 810 } 811 } 812 813 /** 814 * Creates a vertical navigation bar. 815 */ 816 function addVerticalNavigation(){ 817 $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>'); 818 var nav = $(SECTION_NAV_SEL); 819 820 nav.addClass(function() { 821 return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; 822 }); 823 824 for (var i = 0; i < $(SECTION_SEL).length; i++) { 825 var link = ''; 826 if (options.anchors.length) { 827 link = options.anchors[i]; 828 } 829 830 var li = '<li><a href="#' + link + '"><span></span></a>'; 831 832 // Only add tooltip if needed (defined by user) 833 var tooltip = options.navigationTooltips[i]; 834 835 if (typeof tooltip !== 'undefined' && tooltip !== '') { 836 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>'; 837 } 838 839 li += '</li>'; 840 841 nav.find('ul').append(li); 842 } 843 844 //centering it vertically 845 $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px'); 846 847 //activating the current active section 848 $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); 849 } 850 851 /*
852 * Enables the Youtube videos API so we can control their flow if necessary. 853 */ 854 function enableYoutubeAPI(){ 855 container.find('iframe[src*="youtube.com/embed/"]').each(function(){ 856 addURLParam($(this), 'enablejsapi=1'); 857 }); 858 } 859 860 /** 861 * Adds a new parameter and its value to the `src` of a given element 862 */ 863 function addURLParam(element, newParam){ 864 var originalSrc = element.attr('src'); 865 element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam); 866 } 867 868 /* 869 * Returns the prefix sign to use for a new parameter in an existen URL. 870 * 871 * @return {String} ? | & 872 */ 873 function getUrlParamSign(url){ 874 return ( !/\?/.test( url ) ) ? '?' : '&'; 875 } 876 877 /** 878 * Actions and callbacks to fire afterRender 879 */ 880 function afterRenderActions(){ 881 var section = $(SECTION_ACTIVE_SEL); 882 883 section.addClass(COMPLETELY); 884 885 lazyLoad(section); 886 playMedia(section); 887 888 if(options.scrollOverflow){ 889 options.scrollOverflowHandler.afterLoad(); 890 } 891 892 if(isDestinyTheStartingSection()){ 893 $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); 894 } 895 896 $.isFunction( options.afterRender ) && options.afterRender.call(container); 897 } 898 899 /** 900 * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization) 901 */ 902 function isDestinyTheStartingSection(){ 903 var destinationSection = getSectionByAnchor(getAnchorsURL().section); 904 return !destinationSection || destinationSection.length && destinationSection.index() === startingSection.index(); 905 } 906 907 908 var isScrolling = false; 909 var lastScroll = 0; 910 911 //when scrolling... 912 function scrollHandler(){ 913 var currentSection; 914 915 if(!options.autoScrolling || options.scrollBar){ 916 var currentScroll = $window.scrollTop(); 917 var scrollDirection = getScrollDirection(currentScroll); 918 var visibleSectionIndex = 0; 919 var screen_mid = currentScroll + ($window.height() / 2.0); 920 var isAtBottom = $body.height() - $window.height() === currentScroll; 921 var sections = document.querySelectorAll(SECTION_SEL); 922 923 //when using `auto-height` for a small last section it won't be centered in the viewport 924 if(isAtBottom){ 925 visibleSectionIndex = sections.length - 1; 926 } 927 //is at top? when using `auto-height` for a small first section it won't be centered in the viewport 928 else if(!currentScroll){ 929 visibleSectionIndex = 0; 930 } 931 932 //taking the section which is showing more content in the viewport 933 else{ 934 for (var i = 0; i < sections.length; ++i) { 935 var section = sections[i]; 936 937 // Pick the the last section which passes the middle line of the screen. 938 if (section.offsetTop <= screen_mid) 939 { 940 visibleSectionIndex = i; 941 } 942 } 943 } 944 945 if(isCompletelyInViewPort(scrollDirection)){ 946 if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ 947 $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 948 } 949 } 950 951 //geting the last one, the current one on the screen 952 currentSection = $(sections).eq(visibleSectionIndex); 953 954 //setting the visible section as active when manually scrolling 955 //executing only once the first time we reach the section 956 if(!currentSection.hasClass(ACTIVE)){ 957 isScrolling = true; 958 var leavingSection = $(SECTION_ACTIVE_SEL); 959 var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; 960 var yMovement = getYmovement(currentSection); 961 var anchorLink = currentSection.data('anchor'); 962 var sectionIndex = currentSection.index(SECTION_SEL) + 1; 963 var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); 964 var slideIndex; 965 var slideAnchorLink; 966 967 if(activeSlide.length){ 968 slideAnchorLink = activeSlide.data('anchor'); 969 slideIndex = activeSlide.index(); 970 } 971 972 if(canScroll){ 973 currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); 974 975 $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); 976 $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); 977 978 stopMedia(leavingSection); 979 lazyLoad(currentSection); 980 playMedia(currentSection); 981 982 activateMenuAndNav(anchorLink, sectionIndex - 1); 983 984 if(options.anchors.length){ 985 //needed to enter in hashChange event when using the menu with anchor links 986 lastScrolledDestiny = anchorLink; 987 } 988 setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); 989 } 990 991 //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 992 clearTimeout(scrollId); 993 scrollId = setTimeout(function(){ 994 isScrolling = false; 995 }, 100); 996 } 997 998 if(options.fitToSection){ 999 //for the auto adjust of the viewport to fit a whole section 1000 clearTimeout(scrollId2); 1001 1002 scrollId2 = setTimeout(function(){ 1003 //checking it again in case it changed during the delay 1004 if(options.fitToSection && 1005 1006 //is the destination element bigger than the viewport? 1007 $(SECTION_ACTIVE_SEL).outerHeight() <= windowsHeight 1008 ){ 1009 fitToSection(); 1010 } 1011 }, options.fitToSectionDelay); 1012 } 1013 } 1014 } 1015 1016 /** 1017 * Fits the site to the nearest active section 1018 */ 1019 function fitToSection(){ 1020 //checking fitToSection again in case it was set to false before the timeout delay 1021 if(canScroll){ 1022 //allows to scroll to an active section and 1023 //if the section is already active, we prevent firing callbacks 1024 isResizing = true; 1025 1026 scrollPage($(SECTION_ACTIVE_SEL)); 1027 isResizing = false; 1028 } 1029 } 1030 1031 /** 1032 * Determines whether the active section has seen in its whole or not. 1033 */ 1034 function isCompletelyInViewPort(movement){ 1035 var top = $(SECTION_ACTIVE_SEL).position().top; 1036 var bottom = top + $window.height(); 1037 1038 if(movement == 'up'){ 1039 return bottom >= ($window.scrollTop() + $window.height()); 1040 } 1041 return top <= $window.scrollTop(); 1042 } 1043 1044 /** 1045 * Gets the directon of the the scrolling fired by the scroll event. 1046 */ 1047 function getScrollDirection(currentScroll){ 1048 var direction = currentScroll > lastScroll ? 'down' : 'up'; 1049 1050 lastScroll = currentScroll; 1051 1052 //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination 1053 previousDestTop = currentScroll; 1054 1055 return direction; 1056 } 1057 1058 /** 1059 * Determines the way of scrolling up or down: 1060 * by 'automatically' scrolling a section or by using the default and n
1060ormal scrolling. 1061 */ 1062 function scrolling(type){ 1063 if (!isScrollAllowed.m[type]){ 1064 return; 1065 } 1066 1067 var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp; 1068 1069 if(options.scrollOverflow){ 1070 var scrollable = options.scrollOverflowHandler.scrollable($(SECTION_ACTIVE_SEL)); 1071 var check = (type === 'down') ? 'bottom' : 'top'; 1072 1073 if(scrollable.length > 0 ){ 1074 //is the scrollbar at the start/end of the scroll? 1075 if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ 1076 scrollSection(); 1077 }else{ 1078 return true; 1079 } 1080 }else{ 1081 // moved up/down 1082 scrollSection(); 1083 } 1084 }else{ 1085 // moved up/down 1086 scrollSection(); 1087 } 1088 } 1089 1090 /* 1091 * Preventing bouncing in iOS #2285 1092 */ 1093 function preventBouncing(event){ 1094 var e = event.originalEvent; 1095 if(options.autoScrolling && isReallyTouch(e)){ 1096 //preventing the easing on iOS devices 1097 event.preventDefault(); 1098 } 1099 } 1100 1101 var touchStartY = 0; 1102 var touchStartX = 0; 1103 var touchEndY = 0; 1104 var touchEndX = 0; 1105 1106 /* Detecting touch events 1107 1108 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 1109 * This way, the touchstart and the touch moves shows an small difference between them which is the 1110 * used one to determine the direction. 1111 */ 1112 function touchMoveHandler(event){ 1113 var e = event.originalEvent; 1114 var activeSection = $(e.target).closest(SECTION_SEL); 1115 1116 // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain 1117 if (isReallyTouch(e) ) { 1118 1119 if(options.autoScrolling){ 1120 //preventing the easing on iOS devices 1121 event.preventDefault(); 1122 } 1123 1124 var touchEvents = getEventsPage(e); 1125 1126 touchEndY = touchEvents.y; 1127 touchEndX = touchEvents.x; 1128 1129 //if movement in the X axys is greater than in the Y and the currect section has slides... 1130 if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { 1131 1132 //is the movement greater than the minimum resistance to scroll? 1133 if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { 1134 if (touchStartX > touchEndX) { 1135 if(isScrollAllowed.m.right){ 1136 moveSlideRight(activeSection); //next 1137 } 1138 } else { 1139 if(isScrollAllowed.m.left){ 1140 moveSlideLeft(activeSection); //prev 1141 } 1142 } 1143 } 1144 } 1145 1146 //vertical scrolling (only when autoScrolling is enabled) 1147 else if(options.autoScrolling && canScroll){ 1148 1149 //is the movement greater than the minimum resistance to scroll? 1150 if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { 1151 if (touchStartY > touchEndY) { 1152 scrolling('down'); 1153 } else if (touchEndY > touchStartY) { 1154 scrolling('up'); 1155 } 1156 } 1157 } 1158 } 1159 } 1160 1161 /** 1162 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 1163 * this way we make sure that is really a touch event what IE is detecting. 1164 */ 1165 function isReallyTouch(e){ 1166 //if is not IE || IE is detecting `touch` or `pen` 1167 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 1168 } 1169 1170 /** 1171 * Handler for the touch start event. 1172 */ 1173 function touchStartHandler(event){ 1174 var e = event.originalEvent; 1175 1176 //stopping the auto scroll to adjust to a section 1177 if(options.fitToSection){ 1178 $htmlBody.stop(); 1179 } 1180 1181 if(isReallyTouch(e)){ 1182 var touchEvents = getEventsPage(e); 1183 touchStartY = touchEvents.y; 1184 touchStartX = touchEvents.x; 1185 } 1186 } 1187 1188 /** 1189 * Gets the average of the last `number` elements of the given array. 1190 */ 1191 function getAverage(elements, number){
1192 var sum = 0; 1193 1194 //taking `number` elements from the end to make the average, if there are not enought, 1 1195 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 1196 1197 for(var i = 0; i < lastElements.length; i++){ 1198 sum = sum + lastElements[i]; 1199 } 1200 1201 return Math.ceil(sum/number); 1202 } 1203 1204 /** 1205 * Detecting mousewheel scrolling 1206 * 1207 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 1208 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 1209 */ 1210 var prevTime = new Date().getTime(); 1211 1212 function MouseWheelHandler(e) { 1213 var curTime = new Date().getTime(); 1214 var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); 1215 1216 //autoscrolling and not zooming? 1217 if(options.autoScrolling && !controlPressed && !isNormalScroll){ 1218 // cross-browser wheel delta 1219 e = e || window.event; 1220 var value = e.wheelDelta || -e.deltaY || -e.detail; 1221 var delta = Math.max(-1, Math.min(1, value)); 1222 1223 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 1224 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 1225 1226 //Limiting the array to 150 (lets not waste memory!) 1227 if(scrollings.length > 149){ 1228 scrollings.shift(); 1229 } 1230 1231 //keeping record of the previous scrollings 1232 scrollings.push(Math.abs(value)); 1233 1234 //preventing to scroll the site on mouse wheel when scrollbar is present 1235 if(options.scrollBar){ 1236 e.preventDefault ? e.preventDefault() : e.returnValue = false; 1237 } 1238 1239 //time difference between the last scroll and the current one 1240 var timeDiff = curTime-prevTime; 1241 prevTime = curTime; 1242 1243 //haven't they scrolled in a while? 1244 //(enough to be consider a different scrolling action to scroll another section) 1245 if(timeDiff > 200){ 1246 //emptying the array, we dont care about old scrollings for our averages 1247 scrollings = []; 1248 } 1249 1250 if(canScroll){ 1251 var averageEnd = getAverage(scrollings, 10); 1252 var averageMiddle = getAverage(scrollings, 70); 1253 var isAccelerating = averageEnd >= averageMiddle; 1254 1255 //to avoid double swipes... 1256 if(isAccelerating && isScrollingVertically){ 1257 //scrolling down? 1258 if (delta < 0) { 1259 scrolling('down'); 1260 1261 //scrolling up? 1262 }else { 1263 scrolling('up'); 1264 } 1265 } 1266 } 1267 1268 return false; 1269 } 1270 1271 if(options.fitToSection){ 1272 //stopping the auto scroll to adjust to a section 1273 $htmlBody.stop(); 1274 } 1275 } 1276 1277 /** 1278 * Slides a slider to the given direction. 1279 * Optional `section` param. 1280 */ 1281 function moveSlide(direction, section){ 1282 var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; 1283 var slides = activeSection.find(SLIDES_WRAPPER_SEL); 1284 var numSlides = slides.find(SLIDE_SEL).length; 1285 1286 // more than one slide needed and nothing should be sliding 1287 if (!slides.length || slideMoving || numSlides < 2) { 1288 return; 1289 } 1290 1291 var currentSlide = slides.find(SLIDE_ACTIVE_SEL); 1292 var destiny = null; 1293 1294 if(direction === 'left'){ 1295 destiny = currentSlide.prev(SLIDE_SEL); 1296 }else{ 1297 destiny = currentSlide.next(SLIDE_SEL); 1298 } 1299 1300 //isn't there a next slide in the secuence? 1301 if(!destiny.length){ 1302 //respect loopHorizontal settin 1303 if (!options.loopHorizontal) return; 1304 1305 if(direction === 'left'){ 1306 destiny = currentSlide.siblings(':last'); 1307 }else{ 1308 destiny = currentSlide.siblings(':first'); 1309 } 1310 } 1311 1312 slideMoving = true; 1313
1314 landscapeScroll(slides, destiny, direction); 1315 } 1316 1317 /** 1318 * Maintains the active slides in the viewport 1319 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 1320 */ 1321 function keepSlidesPosition(){ 1322 $(SLIDE_ACTIVE_SEL).each(function(){ 1323 silentLandscapeScroll($(this), 'internal'); 1324 }); 1325 } 1326 1327 var previousDestTop = 0; 1328 /** 1329 * Returns the destination Y position based on the scrolling direction and 1330 * the height of the section. 1331 */ 1332 function getDestinationPosition(element){ 1333 var elemPosition = element.position(); 1334 1335 //top of the desination will be at the top of the viewport 1336 var position = elemPosition.top; 1337 var isScrollingDown = elemPosition.top > previousDestTop; 1338 var sectionBottom = position - windowsHeight + element.outerHeight(); 1339 var bigSectionsDestination = options.bigSectionsDestination; 1340 1341 //is the destination element bigger than the viewport? 1342 if(element.outerHeight() > windowsHeight){ 1343 //scrolling up? 1344 if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){ 1345 position = sectionBottom; 1346 } 1347 } 1348 1349 //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 1350 else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ 1351 //The bottom of the destination will be at the bottom of the viewport 1352 position = sectionBottom; 1353 } 1354 1355 /* 1356 Keeping record of the last scrolled position to determine the scrolling direction. 1357 No conventional methods can be used as the scroll bar might not be present 1358 AND the section might not be active if it is auto-height and didnt reach the middle 1359 of the viewport. 1360 */ 1361 previousDestTop = position; 1362 return position; 1363 } 1364 1365 /** 1366 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 1367 */ 1368 function scrollPage(element, callback, isMovementUp){ 1369 if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function 1370 1371 var dtop = getDestinationPosition(element); 1372 var slideAnchorLink; 1373 var slideIndex; 1374 1375 //local variables 1376 var v = { 1377 element: element, 1378 callback: callback, 1379 isMovementUp: isMovementUp, 1380 dtop: dtop, 1381 yMovement: getYmovement(element), 1382 anchorLink: element.data('anchor'), 1383 sectionIndex: element.index(SECTION_SEL), 1384 activeSlide: element.find(SLIDE_ACTIVE_SEL), 1385 activeSection: $(SECTION_ACTIVE_SEL), 1386 leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, 1387 1388 //caching the value of isResizing at the momment the function is called 1389 //because it will be checked later inside a setTimeout and the value might change 1390 localIsResizing: isResizing 1391 }; 1392 1393 //quiting when destination scroll is the same as the current one 1394 if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } 1395 1396 if(v.activeSlide.length){ 1397 slideAnchorLink = v.activeSlide.data('anchor'); 1398 slideIndex = v.activeSlide.index(); 1399 } 1400 1401 //callback (onLeave) if the site is not just resizing and readjusting the slides 1402 if($.isFunction(options.onLeave) && !v.localIsResizing){ 1403 if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ 1404 return; 1405 } 1406 } 1407 1408 // If continuousVertical && we need to wrap around 1409 if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && 1410 ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or 1411 (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down 1412 1413 v = createInfiniteSections(v); 1414 } 1415 1416 //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one) 1417 if(!v.localIsResizing){ 1418 stopMedia(v.activeSection); 1419 } 1420 1421 if(options.scrollOverflow){ 1422 options.scrollOverflowHandler.beforeLeave(); 1423 } 1424 1425 element.addClass(ACTIVE).siblings().removeClass(ACTIVE); 1426 lazyLoad(element); 1427 1428 if(options.scrollOverflow){ 1429 options.scrollOverflowHandler.onLeave(); 1430 } 1431 1432 //preventing from activating the MouseWheelHandler event 1433 //more than once if the page is scrolling 1434 canScroll = false; 1435 1436 setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); 1437 1438 performMovement(v); 1439 1440 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 1441 lastScrolledDestiny = v.anchorLink; 1442 1443 //avoid firing it twice (as it does also on scroll) 1444 activateMenuAndNav(v.anchorLink, v.sectionIndex); 1445 } 1446 1447 /** 1448 * Performs the vertical movement (by CSS3 or by jQuery) 1449 */ 1450 function performMovement(v){ 1451 // using CSS3 translate functionality 1452 if (options.css3 && options.autoScrolling && !options.scrollBar) { 1453 1454 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 1455 // that's why we round it to 0. 1456 var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; 1457 transformContainer(translate3d, true); 1458 1459 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 1460 //scrollingSpeed to change in case of using silentMoveTo(); 1461 if(options.scrollingSpeed){ 1462 clearTimeout(afterSectionLoadsId); 1463 afterSectionLoadsId = setTimeout(function () { 1464 afterSectionLoads(v); 1465 }, options.scrollingSpeed); 1466 }else{ 1467 afterSectionLoads(v); 1468 } 1469 } 1470 1471 // using jQuery animate 1472 else{ 1473 var scrollSettings = getScrollSettings(v); 1474 1475 $(scrollSettings.element).animate( 1476 scrollSettings.options, 1477 options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating `html, body` 1478 if(options.scrollBar){ 1479 1480 /* Hack! 1481 The timeout prevents setting the most dominant section in the viewport as "active" when the user 1482 scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. 1483 1484 When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. 1485 */ 1486 setTimeout(function(){ 1487 afterSectionLoads(v); 1488 },30); 1489 }else{ 1490 afterSectionLoads(v); 1491 } 1492 }); 1493 } 1494 } 1495 1496 /** 1497 * Gets the scrolling settings depending on the plugin autoScrolling option 1498 */ 1499 function getScrollSettings(v){ 1500 var scroll = {}; 1501 1502 if(options.autoScrolling && !options.scrollBar){ 1503 scroll.options = { 'top': -v.dtop}; 1504 scroll.element = WRAPPER_SEL; 1505 }else{ 1506 scroll.options = { 'scrollTop': v.dtop}; 1507 scroll.element = 'html, body'; 1508 } 1509 1510 return scroll; 1511 } 1512 1513 /** 1514 * Adds sections before or after the current one to create the infinite effect. 1515 */ 1516 function createInfiniteSections(v){ 1517 // Scrolling down 1518 if (!v.isMovementUp) { 1519 // Move all previous sections to after the active section 1520 $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); 1521 } 1522 else { // Scrolling up 1523 // Move all next sections to before the active section 1524 $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); 1525 } 1526 1527 // Maintain the displayed position (now that we changed the element order) 1528 silentScroll($(SECTION_ACTIVE_SEL).position().top); 1529 1530 // Maintain the active slides visible in the viewport 1531 keepSlidesPosition(); 1532 1533 // save for later the elements that still need to be reordered 1534 v.wrapAroundElements = v.activeSection; 1535 1536 // Recalculate animation variables 1537 v.dtop = v.element.position().top; 1538 v.yMovement = getYmovement(v.element); 1539 1540 //sections will temporally have another position in the DOM 1541 //updating this values in case we need them 1542 v.leavingSection = v.activeSection.index(SECTION_SEL) + 1; 1543 v.sectionIndex = v.element.index(SECTION_SEL); 1544 1545 return v; 1546 } 1547 1548 /** 1549 * Fix section order after continuousVertical changes have been animated 1550 */ 1551 function continuousVerticalFixSectionOrder (v) {
1552 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 1553 // finish moving the elements around so the direct navigation will function more simply 1554 if (!v.wrapAroundElements || !v.wrapAroundElements.length) { 1555 return; 1556 } 1557 1558 if (v.isMovementUp) { 1559 $(SECTION_FIRST_SEL).before(v.wrapAroundElements); 1560 } 1561 else { 1562 $(SECTION_LAST_SEL).after(v.wrapAroundElements); 1563 } 1564 1565 silentScroll($(SECTION_ACTIVE_SEL).position().top); 1566 1567 // Maintain the active slides visible in the viewport 1568 keepSlidesPosition(); 1569 } 1570 1571 1572 /** 1573 * Actions to do once the section is loaded. 1574 */ 1575 function afterSectionLoads (v){ 1576 continuousVerticalFixSectionOrder(v); 1577 1578 //callback (afterLoad) if the site is not just resizing and readjusting the slides 1579 $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); 1580 1581 if(options.scrollOverflow){ 1582 options.scrollOverflowHandler.afterLoad(); 1583 } 1584 1585 if(!v.localIsResizing){ 1586 playMedia(v.element); 1587 } 1588 1589 v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 1590 1591 canScroll = true; 1592 1593 $.isFunction(v.callback) && v.callback.call(this); 1594 } 1595 1596 /** 1597 * Sets the value for the given attribute from the `data-` attribute with the same suffix 1598 * ie: data-srcset ==> srcset | data-src ==> src 1599 */ 1600 function setSrc(element, attribute){ 1601 element 1602 .attr(attribute, element.data(attribute)) 1603 .removeAttr('data-' + attribute); 1604 } 1605 1606 /** 1607 * Lazy loads image, video and audio elements. 1608 */ 1609 function lazyLoad(destiny){ 1610 if (!options.lazyLoading){ 1611 return; 1612 } 1613 1614 var panel = getSlideOrSection(destiny); 1615 var element; 1616 1617 panel.find('img[data-src], img[data-srcset], source[data-src], source[data-srcset], video[data-src], audio[data-src], iframe[data-src]').each(function(){ 1618 element = $(this); 1619 1620 $.each(['src', 'srcset'], function(index, type){ 1621 var attribute = element.attr('data-' + type); 1622 if(typeof attribute !== 'undefined' && attribute){ 1623 setSrc(element, type); 1624 } 1625 }); 1626 1627 if(element.is('source')){ 1628 var typeToPlay = element.closest('video').length ? 'video' : 'audio'; 1629 element.closest(typeToPlay).get(0).load(); 1630 } 1631 }); 1632 } 1633 1634 /** 1635 * Plays video and audio elements. 1636 */ 1637 function playMedia(destiny){ 1638 var panel = getSlideOrSection(destiny); 1639 1640 //playing HTML5 media elements 1641 panel.find('video, audio').each(function(){ 1642 var element = $(this).get(0); 1643 1644 if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) { 1645 element.play(); 1646 } 1647 }); 1648 1649 //youtube videos 1650 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 1651 var element = $(this).get(0); 1652 1653 if ( element.hasAttribute('data-autoplay') ){ 1654 playYoutube(element); 1655 } 1656 1657 //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. 1658 element.onload = function() { 1659 if ( element.hasAttribute('data-autoplay') ){ 1660 playYoutube(element); 1661 } 1662 }; 1663 }); 1664 } 1665 1666 /** 1667 * Plays a youtube video 1668 */ 1669 function playYoutube(element){ 1670 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 1671 } 1672 1673 /** 1674 * Stops video and audio elements. 1675 */ 1676 function stopMedia(destiny){ 1677 var panel = getSlideOrSection(destiny); 1678 1679 //stopping HTML5 media elements 1680 panel.find('video, audio').each(function(){ 1681 var element = $(this).get(0); 1682 1683 if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { 1684 element.pause(); 1685 } 1686 }); 1687 1688 //youtube videos 1689 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 1690 var element = $(this).get(0); 1691 1692 if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ 1693 $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); 1694 } 1695 }); 1696 } 1697 1698 /** 1699 * Gets the active slide (or section) for the given section 1700 */ 1701 function getSlideOrSection(destiny){ 1702 var slide = destiny.find(SLIDE_ACTIVE_SEL); 1703 if( slide.length ) { 1704 destiny = $(slide); 1705 } 1706 1707 return destiny; 1708 } 1709 1710 /**
1711 * Scrolls to the anchor in the URL when loading the site 1712 */ 1713 function scrollToAnchor(){ 1714 var anchors = getAnchorsURL(); 1715 var sectionAnchor = anchors.section; 1716 var slideAnchor = anchors.slide; 1717 1718 if(sectionAnchor){ //if theres any # 1719 if(options.animateAnchor){ 1720 scrollPageAndSlide(sectionAnchor, slideAnchor); 1721 }else{ 1722 silentMoveTo(sectionAnchor, slideAnchor); 1723 } 1724 } 1725 } 1726 1727 /** 1728 * Detecting any change on the URL to scroll to the given anchor link 1729 * (a way to detect back history button as we play with the hashes on the URL) 1730 */ 1731 function hashChangeHandler(){ 1732 if(!isScrolling && !options.lockAnchors){ 1733 var anchors = getAnchorsURL(); 1734 var sectionAnchor = anchors.section; 1735 var slideAnchor = anchors.slide; 1736 1737 //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 1738 var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); 1739 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving); 1740 1741 if(sectionAnchor.length){ 1742 /*in order to call scrollpage() only once for each destination at a time 1743 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 1744 event is fired on every scroll too.*/ 1745 if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove 1746 || isFirstScrollMove 1747 || (!slideMoving && lastScrolledSlide != slideAnchor )){ 1748 1749 scrollPageAndSlide(sectionAnchor, slideAnchor); 1750 } 1751 } 1752 } 1753 } 1754 1755 //gets the URL anchors (section and slide) 1756 function getAnchorsURL(){ 1757 var section; 1758 var slide; 1759 var hash = window.location.hash; 1760 1761 if(hash.length){ 1762 //getting the anchor link in the URL and deleting the `#` 1763 var anchorsParts = hash.replace('#', '').split('/'); 1764 1765 //using / for visual reasons and not as a section/slide separator #2803 1766 var isFunkyAnchor = hash.indexOf('#/') > -1; 1767 1768 section = isFunkyAnchor ? '/' + anchorsParts[1] : decodeURIComponent(anchorsParts[0]); 1769 1770 var slideAnchor = isFunkyAnchor ? anchorsParts[2] : anchorsParts[1]; 1771 if(slideAnchor && slideAnchor.length){ 1772 slide = decodeURIComponent(slideAnchor); 1773 } 1774 } 1775 1776 return { 1777 section: section, 1778 slide: slide 1779 } 1780 } 1781 1782 //Sliding with arrow keys, both, vertical and horizontal 1783 function keydownHandler(e) { 1784 clearTimeout(keydownId); 1785 1786 var activeElement = $(':focus'); 1787 var keyCode = e.which; 1788 1789 //tab? 1790 if(keyCode === 9){ 1791 // onTab(e); 1792 } 1793 1794 else if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 1795 activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && 1796 options.keyboardScrolling && options.autoScrolling){ 1797 1798 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 1799 var keyControls = [40, 38, 32, 33, 34]; 1800 if($.inArray(keyCode, keyControls) > -1){ 1801 e.preventDefault(); 1802 } 1803 1804 controlPressed = e.ctrlKey; 1805 1806 keydownId = setTimeout(function(){ 1807 onkeydown(e); 1808 },150); 1809 } 1810 } 1811 1812 function tooltipTextHandler(){ 1813 $(this).prev().trigger('click'); 1814 } 1815 1816 //to prevent scrolling while zooming 1817 1818 function keyUpHandler(e){ 1819 if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox 1820 controlPressed = e.ctrlKey; 1821 } 1822 1823 var activeElement = $(':focus'); 1824 var keyCode = e.which; 1825 if(keyCode === 9){ 1826 if(activeElement.hasClass('moveFullpagesTop')){ // tabí¤ë¡ top ë²í¼ ì§ì 1827 $('.moveFullpagesTop')[0].click();
1828 //$(WRAPPER_SEL).fullpage.moveTo(1); // ìµìë¨ì¼ë¡ ì´ë 1829 tabKeyBreakFunc(e); // tabí¤ ì ìë©ì¶¤ 1830 } 1831 if (activeElement.closest('.fp-section').length) onTab(e); 1832 } 1833 } 1834 1835 //binding the mousemove when the mouse's middle button is released 1836 function mouseDownHandler(e){ 1837 //middle button 1838 if (e.which == 2){ 1839 oldPageY = e.pageY; 1840 container.on('mousemove', mouseMoveHandler); 1841 } 1842 } 1843 1844 //unbinding the mousemove when the mouse's middle button is released 1845 function mouseUpHandler(e){ 1846 //middle button 1847 if (e.which == 2){ 1848 container.off('mousemove'); 1849 } 1850 } 1851 1852 //Scrolling horizontally when clicking on the slider controls. 1853 function slideArrowHandler(){ 1854 var section = $(this).closest(SECTION_SEL); 1855 1856 if ($(this).hasClass(SLIDES_PREV)) { 1857 if(isScrollAllowed.m.left){ 1858 moveSlideLeft(section); 1859 } 1860 } else { 1861 if(isScrollAllowed.m.right){ 1862 moveSlideRight(section); 1863 } 1864 } 1865 } 1866 1867 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 1868 function blurHandler(){ 1869 isWindowFocused = false; 1870 controlPressed = false; 1871 } 1872 1873 //Scrolls to the section when clicking the navigation bullet 1874 function sectionBulletHandler(e){ 1875 e.preventDefault(); 1876 var index = $(this).parent().index(); 1877 scrollPage($(SECTION_SEL).eq(index)); 1878 } 1879 1880 //Scrolls the slider to the given slide destination for the given section 1881 function slideBulletHandler(e){ 1882 e.preventDefault(); 1883 var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); 1884 var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); 1885 1886 landscapeScroll(slides, destiny); 1887 } 1888 1889 /** 1890 * Keydown event 1891 */ 1892 function onkeydown(e){ 1893 var shiftPressed = e.shiftKey; 1894 1895 //do nothing if we can not scroll or we are not using horizotnal key arrows. 1896 if(!canScroll && [37,39].indexOf(e.which) < 0){ 1897 return; 1898 } 1899 1900 switch (e.which) { 1901 //up 1902 case 38: 1903 case 33: 1904 if(isScrollAllowed.k.up){ 1905 moveSectionUp(); 1906 } 1907 break; 1908 1909 //down 1910 case 32: //spacebar 1911 if(shiftPressed && isScrollAllowed.k.up){ 1912 moveSectionUp(); 1913 break; 1914 } 1915 /* falls through */ 1916 case 40: 1917 case 34: 1918 if(isScrollAllowed.k.down){ 1919 moveSectionDown(); 1920 } 1921 break; 1922 1923 //Home 1924 case 36: 1925 if(isScrollAllowed.k.up){ 1926 moveTo(1); 1927 } 1928 break; 1929 1930 //End 1931 case 35: 1932 if(isScrollAllowed.k.down){ 1933 moveTo( $(SECTION_SEL).length ); 1934 } 1935 break; 1936 1937 //left 1938 case 37: 1939 if(isScrollAllowed.k.left){ 1940 moveSlideLeft(); 1941 } 1942 break; 1943 1944 //right 1945 case 39: 1946 if(isScrollAllowed.k.right){ 1947 moveSlideRight(); 1948 } 1949 break; 1950 1951 default: 1952 return; // exit this handler for other keys 1953 } 1954 } 1955 1956 /**
1957 * Makes sure the tab key will only focus elements within the current section/slide 1958 * preventing this way from breaking the page. 1959 * Based on "Modals and keyboard traps" 1960 * from https://developers.google.com/web/fundamentals/accessibility/focus/using-tabindex 1961 */ 1962 function onTab(e){ 1963 var isShiftPressed = e.shiftKey; 1964 var activeElement = $(':focus'); 1965 var activeSection = $(SECTION_ACTIVE_SEL); 1966 var activeSlide = activeSection.find(SLIDE_ACTIVE_SEL); 1967 var focusableWrapper = activeSlide.length ? activeSlide : activeSection; 1968 var focusableElements = focusableWrapper.find(focusableElementsString); 1969 1970 function preventAndFocusFirst(e){ 1971 e.preventDefault(); 1972 return focusableElements.first().focus(); 1973 } 1974 1975 //is there an element with focus? 1976 if(activeElement.length){ 1977 if(!activeElement.closest(SECTION_ACTIVE_SEL, SLIDE_ACTIVE_SEL).length){ 1978 // activeElement = preventAndFocusFirst(e); 1979 } 1980 } 1981 1982 //no element if focused? Let's focus the first one of the section/slide 1983 else{ 1984 // preventAndFocusFirst(e); 1985 } 1986 1987 //when reached the first or last focusable element of the section/slide 1988 //we prevent the tab action to keep it in the last focusable element 1989 if(!isShiftPressed && activeElement.is(focusableElements.last()) || 1990 isShiftPressed && activeElement.is(focusableElements.first()) 1991 ){ 1992 // e.preventDefault(); 1993 } 1994 1995 if(!isShiftPressed && activeElement.is(focusableElements.length) && activeElement.closest(SECTION_SEL, SLIDE_SEL).next(SECTION_SEL, SLIDE_SEL).length ){ 1996 moveSectionDown(); 1997 //tabKeyBreakFunc(e); 1998 } else if(isShiftPressed && activeElement.is(focusableElements.first()-1) && activeElement.closest(SECTION_SEL, SLIDE_SEL).prev(SECTION_SEL, SLIDE_SEL).length ){ 1999 moveSectionUp(); 2000 //tabKeyBreakFunc(e); 2001 } 2002 } 2003 2004 /** 2005 * Detecting the direction of the mouse movement. 2006 * Used only for the middle button of the mouse. 2007 */ 2008 var oldPageY = 0; 2009 function mouseMoveHandler(e){ 2010 if(canScroll){ 2011 // moving up 2012 if (e.pageY < oldPageY && isScrollAllowed.m.up){ 2013 moveSectionUp(); 2014 } 2015 2016 // moving down 2017 else if(e.pageY > oldPageY && isScrollAllowed.m.down){ 2018 moveSectionDown(); 2019 } 2020 } 2021 oldPageY = e.pageY; 2022 } 2023 2024 /** 2025 * Scrolls horizontal sliders. 2026 */ 2027 function landscapeScroll(slides, destiny, direction){ 2028 var section = slides.closest(SECTION_SEL); 2029 var v = { 2030 slides: slides, 2031 destiny: destiny, 2032 direction: direction, 2033 destinyPos: destiny.position(), 2034 slideIndex: destiny.index(), 2035 section: section, 2036 sectionIndex: section.index(SECTION_SEL), 2037 anchorLink: section.data('anchor'), 2038 slidesNav: section.find(SLIDES_NAV_SEL), 2039 slideAnchor: getAnchor(destiny), 2040 prevSlide: section.find(SLIDE_ACTIVE_SEL), 2041 prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(), 2042 2043 //caching the value of isResizing at the momment the function is called 2044 //because it will be checked later inside a setTimeout and the value might change 2045 localIsResizing: isResizing 2046 }; 2047 v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); 2048 2049 //important!! Only do it when not resizing 2050 if(!v.localIsResizing){ 2051 //preventing from scrolling to the next/prev section when using scrollHorizontally 2052 canScroll = false; 2053 } 2054 2055 if(options.onSlideLeave){ 2056 2057 //if the site is not just resizing and readjusting the slides 2058 if(!v.localIsResizing && v.xMovement!=='none'){ 2059 if($.isFunction( options.onSlideLeave )){ 2060 if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.direction, v.slideIndex ) === false){ 2061 slideMoving = false; 2062 return; 2063 } 2064 } 2065 } 2066 } 2067 2068 destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); 2069 2070 if(!v.localIsResizing){ 2071 stopMedia(v.prevSlide); 2072 lazyLoad(destiny); 2073 } 2074 2075 if(!options.loopHorizontal && options.controlArrows){ 2076 //hidding it for the fist slide, showing for the rest 2077 section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0); 2078 2079 //hidding it for the last slide, showing for the rest 2080 section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); 2081 } 2082 2083 //only changing the URL if the slides are in the current section (not for resize re-adjusting) 2084 if(section.hasClass(ACTIVE) && !v.localIsResizing){ 2085 setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex); 2086 } 2087 2088 performHorizontalMove(slides, v, true); 2089 } 2090 2091 2092 function afterSlideLoads(v){ 2093 activeSlidesNavigation(v.slidesNav, v.slideIndex); 2094 2095 //if the site is not just resizing and readjusting the slides 2096 if(!v.localIsResizing){ 2097 $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex); 2098 2099 //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally 2100 //and to prevent double scroll right after a windows resize 2101 canScroll = true; 2102 2103 playMedia(v.destiny); 2104 } 2105 2106 //letting them slide again 2107 slideMoving = false; 2108 } 2109 2110 /** 2111 * Performs the horizontal movement. (CSS3 or jQuery) 2112 * 2113 * @param fireCallback {Bool} - determines whether or not to fire the callback 2114 */ 2115 function performHorizontalMove(slides, v, fireCallback){ 2116 var destinyPos = v.destinyPos; 2117 2118 if(options.css3){ 2119 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 2120 2121 addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d)); 2122 2123 afterSlideLoadsId = setTimeout(function(){ 2124 fireCallback && afterSlideLoads(v); 2125 }, options.scrollingSpeed, options.easing); 2126 }else{ 2127 slides.animate({ 2128 scrollLeft : Math.round(destinyPos.left) 2129 }, options.scrollingSpeed, options.easing, function() { 2130 2131 fireCallback && afterSlideLoads(v); 2132 }); 2133 } 2134 } 2135 2136 /** 2137 * Sets the state for the horizontal bullet navigations. 2138 */ 2139 function activeSlidesNavigation(slidesNav, slideIndex){ 2140 slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); 2141 slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); 2142 } 2143 2144 var previousHeight = windowsHeight; 2145 2146 //when resizing the site, we adjust the heights of the sections, slimScroll... 2147 function resizeHandler(){ 2148 //checking if it needs to get responsive 2149 responsive(); 2150 2151 // rebuild immediately on touch devices 2152 if (isTouchDevice) { 2153 var activeElement = $(document.activeElement); 2154 2155 //if the keyboard is NOT visible 2156 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 2157 var currentHeight = $window.height(); 2158 2159 //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) 2160 if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 2161 reBuild(true); 2162 previousHeight = currentHeight; 2163 } 2164 } 2165 }else{ 2166 //in order to call the functions only when the resize is finished 2167 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 2168 clearTimeout(resizeId); 2169 2170 resizeId = setTimeout(function(){ 2171 reBuild(true); 2172 }, 350); 2173 } 2174 } 2175 2176 /** 2177 * Checks if the site needs to get responsive and disables autoScrolling if so. 2178 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 2179 */ 2180 function responsive(){ 2181 var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity 2182 var heightLimit = options.responsiveHeight; 2183 2184 //only calculating what we need. Remember its called on the resize event. 2185 var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; 2186 var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; 2187 2188 if(widthLimit && heightLimit){ 2189 setResponsive(isBreakingPointWidth || isBreakingPointHeight); 2190 } 2191 else if(widthLimit){ 2192 setResponsive(isBreakingPointWidth);
2193 } 2194 else if(heightLimit){ 2195 setResponsive(isBreakingPointHeight); 2196 } 2197 } 2198 2199 /** 2200 * Adds transition animations for the given element 2201 */ 2202 function addAnimation(element){ 2203 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 2204 2205 element.removeClass(NO_TRANSITION); 2206 return element.css({ 2207 '-webkit-transition': transition, 2208 'transition': transition 2209 }); 2210 } 2211 2212 /** 2213 * Remove transition animations for the given element 2214 */ 2215 function removeAnimation(element){ 2216 return element.addClass(NO_TRANSITION); 2217 } 2218 2219 /** 2220 * Activating the vertical navigation bullets according to the given slide name. 2221 */ 2222 function activateNavDots(name, sectionIndex){ 2223 if(options.navigation){ 2224 $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); 2225 if(name){ 2226 $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); 2227 }else{ 2228 $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); 2229 } 2230 } 2231 } 2232 2233 /** 2234 * Activating the website main menu elements according to the given slide name. 2235 */ 2236 function activateMenuElement(name){ 2237 if(options.menu){ 2238 $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); 2239 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); 2240 } 2241 } 2242 2243 /** 2244 * Sets to active the current menu and vertical nav items. 2245 */ 2246 function activateMenuAndNav(anchor, index){ 2247 activateMenuElement(anchor); 2248 activateNavDots(anchor, index); 2249 } 2250 2251 /** 2252 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 2253 * from the current section. 2254 */ 2255 function getYmovement(destiny){ 2256 var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); 2257 var toIndex = destiny.index(SECTION_SEL); 2258 if( fromIndex == toIndex){ 2259 return 'none'; 2260 } 2261 if(fromIndex > toIndex){ 2262 return 'up'; 2263 } 2264 return 'down'; 2265 } 2266 2267 /** 2268 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 2269 * from the current slide. 2270 */ 2271 function getXmovement(fromIndex, toIndex){ 2272 if( fromIndex == toIndex){ 2273 return 'none'; 2274 } 2275 if(fromIndex > toIndex){ 2276 return 'left'; 2277 } 2278 return 'right'; 2279 } 2280 2281 function addTableClass(element){ 2282 //In case we are styling for the 2nd time as in with reponsiveSlides 2283 if(!element.hasClass(TABLE)){ 2284 element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 2285 } 2286 } 2287 2288 function getTableHeight(element){ 2289 var sectionHeight = windowsHeight; 2290 2291 if(options.paddingTop || options.paddingBottom){ 2292 var section = element; 2293 if(!section.hasClass(SECTION)){ 2294 section = element.closest(SECTION_SEL); 2295 } 2296 2297 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 2298 sectionHeight = (windowsHeight - paddings); 2299 } 2300 2301 return sectionHeight; 2302 } 2303 2304 /** 2305 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 2306 */ 2307 function transformContainer(translate3d, animated){ 2308 if(animated){ 2309 addAnimation(container); 2310 }else{ 2311 removeAnimation(container); 2312 } 2313 2314 container.css(getTransforms(translate3d)); 2315 2316 //syncronously removing the class after the animation has been applied. 2317 setTimeout(function(){ 2318 container.removeClass(NO_TRANSITION); 2319 },10); 2320 } 2321 2322 /** 2323 * Gets a section by its anchor / index 2324 */ 2325 function getSectionByAnchor(sectionAnchor){ 2326 var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); 2327 if(!section.length){ 2328 var sectionIndex = typeof sectionAnchor !== 'undefined' ? sectionAnchor -1 : 0; 2329 section = $(SECTION_SEL).eq(sectionIndex); 2330 } 2331 2332 return section; 2333 } 2334 2335 /** 2336 * Gets a slide inside a given section by its anchor / index 2337 */ 2338 function getSlideByAnchor(slideAnchor, section){ 2339 var slide = section.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]');
2340 if(!slide.length){ 2341 slideAnchor = typeof slideAnchor !== 'undefined' ? slideAnchor : 0; 2342 slide = section.find(SLIDE_SEL).eq(slideAnchor); 2343 } 2344 2345 return slide; 2346 } 2347 2348 /** 2349 * Scrolls to the given section and slide anchors 2350 */ 2351 function scrollPageAndSlide(sectionAnchor, slideAnchor){ 2352 var section = getSectionByAnchor(sectionAnchor); 2353 2354 //do nothing if there's no section with the given anchor name 2355 if(!section.length) return; 2356 2357 var slide = getSlideByAnchor(slideAnchor, section); 2358 2359 //we need to scroll to the section and then to the slide 2360 if (sectionAnchor !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ 2361 scrollPage(section, function(){ 2362 scrollSlider(slide); 2363 }); 2364 } 2365 //if we were already in the section 2366 else{ 2367 scrollSlider(slide); 2368 } 2369 } 2370 2371 /** 2372 * Scrolls the slider to the given slide destination for the given section 2373 */ 2374 function scrollSlider(slide){ 2375 if(slide.length){ 2376 landscapeScroll(slide.closest(SLIDES_WRAPPER_SEL), slide); 2377 } 2378 } 2379 2380 /** 2381 * Creates a landscape navigation bar with dots for horizontal sliders. 2382 */ 2383 function addSlidesNavigation(section, numSlides){ 2384 section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>'); 2385 var nav = section.find(SLIDES_NAV_SEL); 2386 2387 //top or bottom 2388 nav.addClass(options.slidesNavPosition); 2389 2390 for(var i=0; i< numSlides; i++){ 2391 nav.find('ul').append('<li><a href="#"><span></span></a></li>'); 2392 } 2393 2394 //centering it 2395 nav.css('margin-left', '-' + (nav.width()/2) + 'px'); 2396 2397 nav.find('li').first().find('a').addClass(ACTIVE); 2398 } 2399 2400 2401 /** 2402 * Sets the state of the website depending on the active section/slide. 2403 * It changes the URL hash when needed and updates the body class. 2404 */ 2405 function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ 2406 var sectionHash = ''; 2407 2408 if(options.anchors.length && !options.lockAnchors){ 2409 2410 //isn't it the first slide? 2411 if(slideIndex){ 2412 if(typeof anchorLink !== 'undefined'){ 2413 sectionHash = anchorLink; 2414 } 2415 2416 //slide without anchor link? We take the index instead. 2417 if(typeof slideAnchor === 'undefined'){ 2418 slideAnchor = slideIndex; 2419 } 2420 2421 lastScrolledSlide = slideAnchor; 2422 setUrlHash(sectionHash + '/' + slideAnchor); 2423 2424 //first slide won't have slide anchor, just the section one 2425 }else if(typeof slideIndex !== 'undefined'){ 2426 lastScrolledSlide = slideAnchor; 2427 setUrlHash(anchorLink); 2428 } 2429 2430 //section without slides 2431 else{ 2432 setUrlHash(anchorLink); 2433 } 2434 } 2435 2436 setBodyClass(); 2437 } 2438 2439 /** 2440 * Sets the URL hash. 2441 */ 2442 function setUrlHash(url){ 2443 if(options.recordHistory){ 2444 location.hash = url; 2445 }else{ 2446 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 2447 if(isTouchDevice || isTouch){ 2448 window.history.replaceState(undefined, undefined, '#' + url); 2449 }else{ 2450 var baseUrl = window.location.href.split('#')[0]; 2451 window.location.replace( baseUrl + '#' + url ); 2452 } 2453 } 2454 } 2455 2456 /** 2457 * Gets the anchor for the given slide / section. Its index will be used if there's none. 2458 */ 2459 function getAnchor(element){ 2460 var anchor = element.data('anchor'); 2461 var index = element.index(); 2462 2463 //Slide without anchor link? We take the index instead. 2464 if(typeof anchor === 'undefined'){ 2465 anchor = index; 2466 } 2467 2468 return anchor; 2469 } 2470 2471 /** 2472 * Sets a class for the body of the page depending on the active section / slide 2473 */ 2474 function setBodyClass(){ 2475 var section = $(SECTION_ACTIVE_SEL); 2476 var slide = section.find(SLIDE_ACTIVE_SEL); 2477 2478 var sectionAnchor = getAnchor(section); 2479 var slideAnchor = getAnchor(slide); 2480 2481 var text = String(sectionAnchor); 2482 2483 if(slide.length){ 2484 text = text + '-' + slideAnchor; 2485 } 2486 2487 //changing slash for dash to make it a valid CSS style 2488 text = text.replace('/', '-').replace('#',''); 2489 2490 //removing previous anchor classes 2491 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 2492 $body[0].className = $body[0].className.replace(classRe, ''); 2493 2494 //adding the current anchor 2495 $body.addClass(VIEWING_PREFIX + '-' + text); 2496 } 2497 2498 /** 2499 * Checks for translate3d support 2500 * @return boolean 2501 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 2502 */ 2503 function support3d() { 2504 var el = document.createElement('p'), 2505 has3d, 2506 transforms = { 2507 'webkitTransform':'-webkit-transform',
2508 'OTransform':'-o-transform', 2509 'msTransform':'-ms-transform', 2510 'MozTransform':'-moz-transform', 2511 'transform':'transform' 2512 }; 2513 2514 // Add it to the body to get the computed style. 2515 document.body.insertBefore(el, null); 2516 2517 for (var t in transforms) { 2518 if (el.style[t] !== undefined) { 2519 el.style[t] = 'translate3d(1px,1px,1px)'; 2520 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 2521 } 2522 } 2523 2524 document.body.removeChild(el); 2525 2526 return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); 2527 } 2528 2529 /** 2530 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 2531 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 2532 */ 2533 function removeMouseWheelHandler(){ 2534 if (document.addEventListener) { 2535 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 2536 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 2537 document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 2538 } else { 2539 document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 2540 } 2541 } 2542 2543 /** 2544 * Adds the auto scrolling action for the mouse wheel and trackpad. 2545 * After this function is called, the mousewheel and trackpad movements will scroll through sections 2546 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 2547 */ 2548 function addMouseWheelHandler(){ 2549 var prefix = ''; 2550 var _addEventListener; 2551 2552 if (window.addEventListener){ 2553 _addEventListener = "addEventListener"; 2554 }else{ 2555 _addEventListener = "attachEvent"; 2556 prefix = 'on'; 2557 } 2558 2559 // detect available wheel event 2560 var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 2561 document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 2562 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 2563 2564 2565 if(support == 'DOMMouseScroll'){ 2566 document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, false); 2567 } 2568 2569 //handle MozMousePixelScroll in older Firefox 2570 else{ 2571 document[ _addEventListener ](prefix + support, MouseWheelHandler, false); 2572 } 2573 } 2574 2575 /** 2576 * Binding the mousemove when the mouse's middle button is pressed 2577 */ 2578 function addMiddleWheelHandler(){ 2579 container 2580 .on('mousedown', mouseDownHandler) 2581 .on('mouseup', mouseUpHandler); 2582 } 2583 2584 /** 2585 * Unbinding the mousemove when the mouse's middle button is released 2586 */ 2587 function removeMiddleWheelHandler(){ 2588 container 2589 .off('mousedown', mouseDownHandler) 2590 .off('mouseup', mouseUpHandler); 2591 } 2592 2593 /** 2594 * Adds the possibility to auto scroll through sections on touch devices. 2595 */ 2596 function addTouchHandler(){ 2597 if(isTouchDevice || isTouch){ 2598 if(options.autoScrolling){ 2599 $body.off(events.touchmove).on(events.touchmove, preventBouncing); 2600 } 2601 2602 $(WRAPPER_SEL) 2603 .off(events.touchstart).on(events.touchstart, touchStartHandler) 2604 .off(events.touchmove).on(events.touchmove, touchMoveHandler); 2605 } 2606 } 2607 2608 /** 2609 * Removes the auto scrolling for touch devices. 2610 */ 2611 function removeTouchHandler(){ 2612 if(isTouchDevice || isTouch){ 2613 if(options.autoScrolling){ 2614 $body.off(events.touchmove); 2615 } 2616 2617 $(WRAPPER_SEL) 2618 .off(events.touchstart) 2619 .off(events.touchmove); 2620 } 2621 } 2622 2623 /* 2624 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11)
2625 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 2626 */ 2627 function getMSPointer(){ 2628 var pointer; 2629 2630 //IE >= 11 & rest of browsers 2631 if(window.PointerEvent){ 2632 pointer = { down: 'pointerdown', move: 'pointermove'}; 2633 } 2634 2635 //IE < 11 2636 else{ 2637 pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; 2638 } 2639 2640 return pointer; 2641 } 2642 2643 /** 2644 * Gets the pageX and pageY properties depending on the browser. 2645 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 2646 */ 2647 function getEventsPage(e){ 2648 var events = []; 2649 2650 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 2651 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 2652 2653 //in touch devices with scroll bar, e.pageY is detected, but we have to deal with touch events. #1008 2654 if(isTouch && isReallyTouch(e) && (options.scrollBar || !options.autoScrolling)){ 2655 events.y = e.touches[0].pageY; 2656 events.x = e.touches[0].pageX; 2657 } 2658 2659 return events; 2660 } 2661 2662 /** 2663 * Slides silently (with no animation) the active slider to the given slide. 2664 * @param noCallback {bool} true or defined -> no callbacks 2665 */ 2666 function silentLandscapeScroll(activeSlide, noCallbacks){ 2667 setScrollingSpeed (0, 'internal'); 2668 2669 if(typeof noCallbacks !== 'undefined'){ 2670 //preventing firing callbacks afterSlideLoad etc. 2671 isResizing = true; 2672 } 2673 2674 landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); 2675 2676 if(typeof noCallbacks !== 'undefined'){ 2677 isResizing = false; 2678 } 2679 2680 setScrollingSpeed(originals.scrollingSpeed, 'internal'); 2681 } 2682 2683 /** 2684 * Scrolls silently (with no animation) the page to the given Y position. 2685 */ 2686 function silentScroll(top){ 2687 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 2688 // that's why we round it to 0. 2689 var roundedTop = Math.round(top); 2690 2691 if (options.css3 && options.autoScrolling && !options.scrollBar){ 2692 var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; 2693 transformContainer(translate3d, false); 2694 } 2695 else if(options.autoScrolling && !options.scrollBar){ 2696 container.css('top', -roundedTop); 2697 } 2698 else{ 2699 $htmlBody.scrollTop(roundedTop); 2700 } 2701 } 2702 2703 /** 2704 * Returns the cross-browser transform string. 2705 */ 2706 function getTransforms(translate3d){ 2707 return { 2708 '-webkit-transform': translate3d, 2709 '-moz-transform': translate3d, 2710 '-ms-transform':translate3d, 2711 'transform': translate3d 2712 }; 2713 } 2714 2715 /** 2716 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 2717 * @type m (mouse) or k (keyboard) 2718 */ 2719 function setIsScrollAllowed(value, direction, type){ 2720 //up, down, left, right 2721 if(direction !== 'all'){ 2722 isScrollAllowed[type][direction] = value; 2723 } 2724 2725 //all directions? 2726 else{ 2727 $.each(Object.keys(isScrollAllowed[type]), function(index, key){ 2728 isScrollAllowed[type][key] = value; 2729 }); 2730 } 2731 } 2732 2733 /* 2734 * Destroys fullpage.js plugin events and optinally its html markup and styles 2735 */ 2736 function destroy(all){ 2737 setAutoScrolling(false, 'internal'); 2738 setAllowScrolling(false); 2739 setKeyboardScrolling(false); 2740 container.addClass(DESTROYED); 2741 2742 clearTimeout(afterSlideLoadsId); 2743 clearTimeout(afterSectionLoadsId); 2744 clearTimeout(resizeId); 2745 clearTimeout(scrollId); 2746 clearTimeout(scrollId2); 2747 2748 $window 2749 .off('scroll', scrollHandler) 2750 .off('hashchange', hashChangeHandler) 2751 .off('resize', resizeHandler); 2752 2753 $document 2754 .off('click touchstart', SECTION_NAV_SEL + ' a') 2755 .off('mouseenter', SECTION_NAV_SEL + ' li') 2756 .off('mouseleave', SECTION_NAV_SEL + ' li') 2757 .off('click touchstart', SLIDES_NAV_LINK_SEL) 2758 .off('mouseover', options.normalScrollElements) 2759 .off('mouseout', options.normalScrollElements); 2760 2761 $(SECTION_SEL) 2762 .off('click touchstart', SLIDES_ARROW_SEL);
2763 2764 clearTimeout(afterSlideLoadsId); 2765 clearTimeout(afterSectionLoadsId); 2766 2767 //lets make a mess! 2768 if(all){ 2769 destroyStructure(); 2770 } 2771 } 2772 2773 /* 2774 * Removes inline styles added by fullpage.js 2775 */ 2776 function destroyStructure(){ 2777 //reseting the `top` or `translate` properties to 0 2778 silentScroll(0); 2779 2780 //loading all the lazy load content 2781 container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 2782 setSrc($(this), 'src'); 2783 }); 2784 2785 container.find('img[data-srcset]').each(function(){ 2786 setSrc($(this), 'srcset'); 2787 }); 2788 2789 $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); 2790 2791 //removing inline styles 2792 $(SECTION_SEL).css( { 2793 'height': '', 2794 'background-color' : '', 2795 'padding': '' 2796 }); 2797 2798 $(SLIDE_SEL).css( { 2799 'width': '' 2800 }); 2801 2802 container.css({ 2803 'height': '', 2804 'position': '', 2805 '-ms-touch-action': '', 2806 'touch-action': '' 2807 }); 2808 2809 $htmlBody.css({ 2810 'overflow': '', 2811 'height': '' 2812 }); 2813 2814 // remove .fp-enabled class 2815 $('html').removeClass(ENABLED); 2816 2817 // remove .fp-responsive class 2818 $body.removeClass(RESPONSIVE); 2819 2820 // remove all of the .fp-viewing- classes 2821 $.each($body.get(0).className.split(/\s+/), function (index, className) { 2822 if (className.indexOf(VIEWING_PREFIX) === 0) { 2823 $body.removeClass(className); 2824 } 2825 }); 2826 2827 //removing added classes 2828 $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ 2829 if(options.scrollOverflowHandler){ 2830 options.scrollOverflowHandler.remove($(this)); 2831 } 2832 $(this).removeClass(TABLE + ' ' + ACTIVE); 2833 $(this).attr('style', $(this).data('fp-styles')); 2834 }); 2835 2836 removeAnimation(container); 2837 2838 //Unwrapping content 2839 container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ 2840 //unwrap not being use in case there's no child element inside and its just text 2841 $(this).replaceWith(this.childNodes); 2842 }); 2843 2844 //removing the applied transition from the fullpage wrapper 2845 container.css({ 2846 '-webkit-transition': 'none', 2847 'transition': 'none' 2848 }); 2849 2850 //scrolling the page to the top with no animation 2851 $htmlBody.scrollTop(0); 2852 2853 //removing selectors 2854 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 2855 $.each(usedSelectors, function(index, value){ 2856 $('.' + value).removeClass(value); 2857 }); 2858 } 2859 2860 /* 2861 * Sets the state for a variable with multiple states (original, and temporal) 2862 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 2863 * This function is used to keep track of both states, the original and the temporal one. 2864 * If type is not 'internal', then we assume the user is globally changing the variable. 2865 */ 2866 function setVariableState(variable, value, type){ 2867 options[variable] = value; 2868 if(type !== 'internal'){ 2869 originals[variable] = value; 2870 } 2871 } 2872 2873 /** 2874 * Displays warnings 2875 */ 2876 function displayWarnings(){ 2877 var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax']; 2878 if($('html').hasClass(ENABLED)){ 2879 showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 2880 return; 2881 } 2882 2883 // Disable mutually exclusive settings 2884 if (options.continuousVertical && 2885 (options.loopTop || options.loopBottom)) { 2886 options.continuousVertical = false; 2887 showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 2888 } 2889 2890 if(options.scrollBar && options.scrollOverflow){ 2891 showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); 2892 } 2893 2894 if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){ 2895 options.continuousVertical = false; 2896 showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 2897 } 2898 2899 if(options.scrollOverflow && !options.scrollOverflowHandler){ 2900 options.scrollOverflow = false; 2901 showError('error', 'The option `scrollOverflow:true` requires the file `scrolloverflow.min.js`. Please include it before fullPage.js.'); 2902 } 2903 2904 //using extensions? Wrong file! 2905 $.each(extensions, function(index, extension){ 2906 //is the option set to true? 2907 if(options[extension]){ 2908 showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension); 2909 } 2910 }); 2911 2912 //anchors can not have the same value as any element ID or NAME 2913 $.each(options.anchors, function(index, name){ 2914 2915 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 2916 var nameAttr = $document.find('[name]').filter(function() { 2917 return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); 2918 }); 2919 2920 var idAttr = $document.find('[id]').filter(function() { 2921 return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); 2922 }); 2923 2924 if(idAttr.length || nameAttr.length ){ 2925 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).');
2926 idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); 2927 nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); 2928 } 2929 }); 2930 } 2931 2932 /** 2933 * Shows a message in the console of the given type. 2934 */ 2935 function showError(type, text){ 2936 console && console[type] && console[type]('fullPage: ' + text); 2937 } 2938 2939 }; //end of $.fn.fullpage 2940}); 2941 2942$(window).on('load',function(){ 2943 $(document).bind('keydown',function(e){ 2944 if (tabKeyBreaked && e.keyCode == 9) { 2945 e.preventDefault(); 2946 e.returnValue = false; 2947 } 2948 }); 2949});
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.