Created
March 10, 2015 20:53
-
-
Save andymason/db180a68839de243874b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define('nyt5/analytics',[],function() { | |
var canonical = document.querySelector("link[rel='canonical']").href, | |
pageview = ['_trackPageview']; | |
if (canonical) { | |
var a = document.createElement("a"); | |
a.href = canonical; | |
if (a.pathname != document.location.pathname) pageview.push(a.pathname); | |
} | |
_gaq = [['_setAccount', 'UA-9262032-1'], pageview]; | |
require(['http://www.google-analytics.com/ga.js']); | |
}); | |
/** | |
* Swiper 3.0.4 | |
* Most modern mobile touch slider and framework with hardware accelerated transitions | |
* | |
* http://www.idangero.us/swiper/ | |
* | |
* Copyright 2015, Vladimir Kharlampidi | |
* The iDangero.us | |
* http://www.idangero.us/ | |
* | |
* Licensed under MIT | |
* | |
* Released on: March 6, 2015 | |
*/ | |
(function () { | |
/*=========================== | |
Swiper | |
===========================*/ | |
window.Swiper = function (container, params) { | |
var defaults = { | |
direction: 'horizontal', | |
touchEventsTarget: 'container', | |
initialSlide: 0, | |
speed: 300, | |
// autoplay | |
autoplay: false, | |
autoplayDisableOnInteraction: true, | |
// Free mode | |
freeMode: false, | |
freeModeMomentum: true, | |
freeModeMomentumRatio: 1, | |
freeModeMomentumBounce: true, | |
freeModeMomentumBounceRatio: 1, | |
// Effects | |
effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' | |
coverflow: { | |
rotate: 50, | |
stretch: 0, | |
depth: 100, | |
modifier: 1, | |
slideShadows : true | |
}, | |
cube: { | |
slideShadows: true, | |
shadow: true, | |
shadowOffset: 20, | |
shadowScale: 0.94 | |
}, | |
fade: { | |
crossFade: false | |
}, | |
// Parallax | |
parallax: false, | |
// Scrollbar | |
scrollbar: null, | |
scrollbarHide: true, | |
// Keyboard Mousewheel | |
keyboardControl: false, | |
mousewheelControl: false, | |
mousewheelForceToAxis: false, | |
// Hash Navigation | |
hashnav: false, | |
// Slides grid | |
spaceBetween: 0, | |
slidesPerView: 1, | |
slidesPerColumn: 1, | |
slidesPerColumnFill: 'column', | |
slidesPerGroup: 1, | |
centeredSlides: false, | |
// Touches | |
touchRatio: 1, | |
touchAngle: 45, | |
simulateTouch: true, | |
shortSwipes: true, | |
longSwipes: true, | |
longSwipesRatio: 0.5, | |
longSwipesMs: 300, | |
followFinger: true, | |
onlyExternal: false, | |
threshold: 0, | |
touchMoveStopPropagation: true, | |
// Pagination | |
pagination: null, | |
paginationClickable: false, | |
paginationHide: false, | |
paginationBulletRender: null, | |
// Resistance | |
resistance: true, | |
resistanceRatio: 0.85, | |
// Next/prev buttons | |
nextButton: null, | |
prevButton: null, | |
// Progress | |
watchSlidesProgress: false, | |
watchSlidesVisibility: false, | |
// Cursor | |
grabCursor: false, | |
// Clicks | |
preventClicks: true, | |
preventClicksPropagation: true, | |
slideToClickedSlide: false, | |
// Lazy Loading | |
lazyLoading: false, | |
lazyLoadingInPrevNext: false, | |
lazyLoadingOnTransitionStart: false, | |
// Images | |
preloadImages: true, | |
updateOnImagesReady: true, | |
// loop | |
loop: false, | |
loopAdditionalSlides: 0, | |
loopedSlides: null, | |
// Control | |
control: undefined, | |
controlInverse: false, | |
// Swiping/no swiping | |
allowSwipeToPrev: true, | |
allowSwipeToNext: true, | |
swipeHandler: null, //'.swipe-handler', | |
noSwiping: true, | |
noSwipingClass: 'swiper-no-swiping', | |
// NS | |
slideClass: 'swiper-slide', | |
slideActiveClass: 'swiper-slide-active', | |
slideVisibleClass: 'swiper-slide-visible', | |
slideDuplicateClass: 'swiper-slide-duplicate', | |
slideNextClass: 'swiper-slide-next', | |
slidePrevClass: 'swiper-slide-prev', | |
wrapperClass: 'swiper-wrapper', | |
bulletClass: 'swiper-pagination-bullet', | |
bulletActiveClass: 'swiper-pagination-bullet-active', | |
buttonDisabledClass: 'swiper-button-disabled', | |
paginationHiddenClass: 'swiper-pagination-hidden', | |
// Observer | |
observer: false, | |
observeParents: false, | |
// Callbacks | |
runCallbacksOnInit: true | |
/* | |
Callbacks: | |
onInit: function (swiper) | |
onDestroy: function (swiper) | |
onClick: function (swiper, e) | |
onTap: function (swiper, e) | |
onDoubleTap: function (swiper, e) | |
onSliderMove: function (swiper, e) | |
onSlideChangeStart: function (swiper) | |
onSlideChangeEnd: function (swiper) | |
onTransitionStart: function (swiper) | |
onTransitionEnd: function (swiper) | |
onImagesReady: function (swiper) | |
onProgress: function (swiper, progress) | |
onTouchStart: function (swiper, e) | |
onTouchMove: function (swiper, e) | |
onTouchMoveOpposite: function (swiper, e) | |
onTouchEnd: function (swiper, e) | |
onReachBeginning: function (swiper) | |
onReachEnd: function (swiper) | |
onSetTransition: function (swiper, duration) | |
onSetTranslate: function (swiper, translate) | |
onAutoplayStart: function (swiper) | |
onAutoplayStop: function (swiper), | |
onLazyImageLoad: function (swiper, slide, image) | |
onLazyImageReady: function (swiper, slide, image) | |
*/ | |
}; | |
params = params || {}; | |
for (var def in defaults) { | |
if (typeof params[def] === 'undefined') { | |
params[def] = defaults[def]; | |
} | |
else if (typeof params[def] === 'object') { | |
for (var deepDef in defaults[def]) { | |
if (typeof params[def][deepDef] === 'undefined') { | |
params[def][deepDef] = defaults[def][deepDef]; | |
} | |
} | |
} | |
} | |
// Swiper | |
var s = this; | |
// Params | |
s.params = params; | |
/*========================= | |
Dom Library and plugins | |
===========================*/ | |
var $; | |
if (typeof Dom7 === 'undefined') { | |
$ = window.Dom7 || window.Zepto || window.jQuery; | |
} | |
else { | |
$ = Dom7; | |
} | |
if (!$) return; | |
/*========================= | |
Preparation - Define Container, Wrapper and Pagination | |
===========================*/ | |
s.container = $(container); | |
if (s.container.length === 0) return; | |
if (s.container.length > 1) { | |
s.container.each(function () { | |
new Swiper(this, params); | |
}); | |
return; | |
} | |
// Save instance in container HTML Element and in data | |
s.container[0].swiper = s; | |
s.container.data('swiper', s); | |
s.container.addClass('swiper-container-' + s.params.direction); | |
if (s.params.freeMode) { | |
s.container.addClass('swiper-container-free-mode'); | |
} | |
// Enable slides progress when required | |
if (s.params.parallax || s.params.watchSlidesVisibility) { | |
s.params.watchSlidesProgress = true; | |
} | |
// Coverflow / 3D | |
if (['cube', 'coverflow'].indexOf(s.params.effect) >= 0) { | |
if (s.support.transforms3d) { | |
s.params.watchSlidesProgress = true; | |
s.container.addClass('swiper-container-3d'); | |
} | |
else { | |
s.params.effect = 'slide'; | |
} | |
} | |
if (s.params.effect !== 'slide') { | |
s.container.addClass('swiper-container-' + s.params.effect); | |
} | |
if (s.params.effect === 'cube') { | |
s.params.resistanceRatio = 0; | |
s.params.slidesPerView = 1; | |
s.params.slidesPerColumn = 1; | |
s.params.slidesPerGroup = 1; | |
s.params.centeredSlides = false; | |
s.params.spaceBetween = 0; | |
} | |
if (s.params.effect === 'fade') { | |
s.params.watchSlidesProgress = true; | |
s.params.spaceBetween = 0; | |
} | |
// Grab Cursor | |
if (s.params.grabCursor && s.support.touch) { | |
s.params.grabCursor = false; | |
} | |
// Wrapper | |
s.wrapper = s.container.children('.' + s.params.wrapperClass); | |
// Pagination | |
if (s.params.pagination) { | |
s.paginationContainer = $(s.params.pagination); | |
if (s.params.paginationClickable) { | |
s.paginationContainer.addClass('swiper-pagination-clickable'); | |
} | |
} | |
// Is Horizontal | |
function isH() { | |
return s.params.direction === 'horizontal'; | |
} | |
// RTL | |
s.rtl = isH() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl'); | |
if (s.rtl) s.container.addClass('swiper-container-rtl'); | |
// Wrong RTL support | |
if (s.rtl) { | |
s.wrongRTL = s.wrapper.css('display') === '-webkit-box'; | |
} | |
// Translate | |
s.translate = 0; | |
// Progress | |
s.progress = 0; | |
// Velocity | |
s.velocity = 0; | |
// Locks, unlocks | |
s.lockSwipeToNext = function () { | |
s.params.allowSwipeToNext = false; | |
}; | |
s.lockSwipeToPrev = function () { | |
s.params.allowSwipeToPrev = false; | |
}; | |
s.lockSwipes = function () { | |
s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false; | |
}; | |
s.unlockSwipeToNext = function () { | |
s.params.allowSwipeToNext = true; | |
}; | |
s.unlockSwipeToPrev = function () { | |
s.params.allowSwipeToPrev = true; | |
}; | |
s.unlockSwipes = function () { | |
s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true; | |
}; | |
// Columns | |
if (s.params.slidesPerColumn > 1) { | |
s.container.addClass('swiper-container-multirow'); | |
} | |
/*========================= | |
Set grab cursor | |
===========================*/ | |
if (s.params.grabCursor) { | |
s.container[0].style.cursor = 'move'; | |
s.container[0].style.cursor = '-webkit-grab'; | |
s.container[0].style.cursor = '-moz-grab'; | |
s.container[0].style.cursor = 'grab'; | |
} | |
/*========================= | |
Update on Images Ready | |
===========================*/ | |
s.imagesToLoad = []; | |
s.imagesLoaded = 0; | |
s.loadImage = function (imgElement, src, checkForComplete, callback) { | |
var image; | |
function onReady () { | |
if (callback) callback(); | |
} | |
if (!imgElement.complete || !checkForComplete) { | |
if (src) { | |
image = new Image(); | |
image.onload = onReady; | |
image.onerror = onReady; | |
image.src = src; | |
} else { | |
onReady(); | |
} | |
} else {//image already loaded... | |
onReady(); | |
} | |
}; | |
s.preloadImages = function () { | |
s.imagesToLoad = s.container.find('img'); | |
function _onReady() { | |
if (typeof s === 'undefined' || s === null) return; | |
if (s.imagesLoaded !== undefined) s.imagesLoaded++; | |
if (s.imagesLoaded === s.imagesToLoad.length) { | |
if (s.params.updateOnImagesReady) s.update(); | |
if (s.params.onImagesReady) s.params.onImagesReady(s); | |
} | |
} | |
for (var i = 0; i < s.imagesToLoad.length; i++) { | |
s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), true, _onReady); | |
} | |
}; | |
/*========================= | |
Autoplay | |
===========================*/ | |
s.autoplayTimeoutId = undefined; | |
s.autoplaying = false; | |
s.autoplayPaused = false; | |
function autoplay() { | |
s.autoplayTimeoutId = setTimeout(function () { | |
if (s.params.loop) { | |
s.fixLoop(); | |
s._slideNext(); | |
} | |
else { | |
if (!s.isEnd) { | |
s._slideNext(); | |
} | |
else { | |
if (!params.autoplayStopOnLast) { | |
s._slideTo(0); | |
} | |
else { | |
s.stopAutoplay(); | |
} | |
} | |
} | |
}, s.params.autoplay); | |
} | |
s.startAutoplay = function () { | |
if (typeof s.autoplayTimeoutId !== 'undefined') return false; | |
if (!s.params.autoplay) return false; | |
if (s.autoplaying) return false; | |
s.autoplaying = true; | |
if (s.params.onAutoplayStart) s.params.onAutoplayStart(s); | |
autoplay(); | |
}; | |
s.stopAutoplay = function (internal) { | |
if (!s.autoplayTimeoutId) return; | |
if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId); | |
s.autoplaying = false; | |
s.autoplayTimeoutId = undefined; | |
if (s.params.onAutoplayStop) s.params.onAutoplayStop(s); | |
}; | |
s.pauseAutoplay = function (speed) { | |
if (s.autoplayPaused) return; | |
if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId); | |
s.autoplayPaused = true; | |
if (speed === 0) { | |
s.autoplayPaused = false; | |
autoplay(); | |
} | |
else { | |
s.wrapper.transitionEnd(function () { | |
s.autoplayPaused = false; | |
if (!s.autoplaying) { | |
s.stopAutoplay(); | |
} | |
else { | |
autoplay(); | |
} | |
}); | |
} | |
}; | |
/*========================= | |
Min/Max Translate | |
===========================*/ | |
s.minTranslate = function () { | |
return (-s.snapGrid[0]); | |
}; | |
s.maxTranslate = function () { | |
return (-s.snapGrid[s.snapGrid.length - 1]); | |
}; | |
/*========================= | |
Slider/slides sizes | |
===========================*/ | |
s.updateContainerSize = function () { | |
s.width = s.container[0].clientWidth; | |
s.height = s.container[0].clientHeight; | |
s.size = isH() ? s.width : s.height; | |
}; | |
s.updateSlidesSize = function () { | |
s.slides = s.wrapper.children('.' + s.params.slideClass); | |
s.snapGrid = []; | |
s.slidesGrid = []; | |
s.slidesSizesGrid = []; | |
var spaceBetween = s.params.spaceBetween, | |
slidePosition = 0, | |
i, | |
prevSlideSize = 0, | |
index = 0; | |
if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) { | |
spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size; | |
} | |
s.virtualWidth = -spaceBetween; | |
// reset margins | |
if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''}); | |
else s.slides.css({marginRight: '', marginBottom: ''}); | |
var slidesNumberEvenToRows; | |
if (s.params.slidesPerColumn > 1) { | |
if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) { | |
slidesNumberEvenToRows = s.slides.length; | |
} | |
else { | |
slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn; | |
} | |
} | |
// Calc slides | |
var slideSize; | |
for (i = 0; i < s.slides.length; i++) { | |
slideSize = 0; | |
var slide = s.slides.eq(i); | |
if (s.params.slidesPerColumn > 1) { | |
// Set slides order | |
var newSlideOrderIndex; | |
var column, row; | |
var slidesPerColumn = s.params.slidesPerColumn; | |
var slidesPerRow; | |
if (s.params.slidesPerColumnFill === 'column') { | |
column = Math.floor(i / slidesPerColumn); | |
row = i - column * slidesPerColumn; | |
newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn; | |
slide | |
.css({ | |
'-webkit-box-ordinal-group': newSlideOrderIndex, | |
'-moz-box-ordinal-group': newSlideOrderIndex, | |
'-ms-flex-order': newSlideOrderIndex, | |
'-webkit-order': newSlideOrderIndex, | |
'order': newSlideOrderIndex | |
}); | |
} | |
else { | |
slidesPerRow = slidesNumberEvenToRows / slidesPerColumn; | |
row = Math.floor(i / slidesPerRow); | |
column = i - row * slidesPerRow; | |
} | |
slide | |
.css({ | |
'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px') | |
}) | |
.attr('data-swiper-column', column) | |
.attr('data-swiper-row', row); | |
} | |
if (slide.css('display') === 'none') continue; | |
if (s.params.slidesPerView === 'auto') { | |
slideSize = isH() ? slide.outerWidth(true) : slide.outerHeight(true); | |
} | |
else { | |
slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView; | |
if (isH()) { | |
s.slides[i].style.width = slideSize + 'px'; | |
} | |
else { | |
s.slides[i].style.height = slideSize + 'px'; | |
} | |
} | |
s.slides[i].swiperSlideSize = slideSize; | |
s.slidesSizesGrid.push(slideSize); | |
if (s.params.centeredSlides) { | |
slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween; | |
if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween; | |
if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0; | |
if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition); | |
s.slidesGrid.push(slidePosition); | |
} | |
else { | |
if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition); | |
s.slidesGrid.push(slidePosition); | |
slidePosition = slidePosition + slideSize + spaceBetween; | |
} | |
s.virtualWidth += slideSize + spaceBetween; | |
prevSlideSize = slideSize; | |
index ++; | |
} | |
s.virtualWidth = Math.max(s.virtualWidth, s.size); | |
var newSlidesGrid; | |
if (s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) { | |
s.wrapper.css({width: s.virtualWidth + s.params.spaceBetween + 'px'}); | |
} | |
if (s.params.slidesPerColumn > 1) { | |
s.virtualWidth = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows; | |
s.virtualWidth = Math.ceil(s.virtualWidth / s.params.slidesPerColumn) - s.params.spaceBetween; | |
s.wrapper.css({width: s.virtualWidth + s.params.spaceBetween + 'px'}); | |
if (s.params.centeredSlides) { | |
newSlidesGrid = []; | |
for (i = 0; i < s.snapGrid.length; i++) { | |
if (s.snapGrid[i] < s.virtualWidth + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]); | |
} | |
s.snapGrid = newSlidesGrid; | |
} | |
} | |
// Remove last grid elements depending on width | |
if (!s.params.centeredSlides) { | |
newSlidesGrid = []; | |
for (i = 0; i < s.snapGrid.length; i++) { | |
if (s.snapGrid[i] <= s.virtualWidth - s.size) { | |
newSlidesGrid.push(s.snapGrid[i]); | |
} | |
} | |
s.snapGrid = newSlidesGrid; | |
if (Math.floor(s.virtualWidth - s.size) > Math.floor(s.snapGrid[s.snapGrid.length - 1])) { | |
s.snapGrid.push(s.virtualWidth - s.size); | |
} | |
} | |
if (s.snapGrid.length === 0) s.snapGrid = [0]; | |
if (s.params.spaceBetween !== 0) { | |
if (isH()) { | |
if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'}); | |
else s.slides.css({marginRight: spaceBetween + 'px'}); | |
} | |
else s.slides.css({marginBottom: spaceBetween + 'px'}); | |
} | |
if (s.params.watchSlidesProgress) { | |
s.updateSlidesOffset(); | |
} | |
}; | |
s.updateSlidesOffset = function () { | |
for (var i = 0; i < s.slides.length; i++) { | |
s.slides[i].swiperSlideOffset = isH() ? s.slides[i].offsetLeft : s.slides[i].offsetTop; | |
} | |
}; | |
/*========================= | |
Slider/slides progress | |
===========================*/ | |
s.updateSlidesProgress = function (translate) { | |
if (typeof translate === 'undefined') { | |
translate = s.translate || 0; | |
} | |
if (s.slides.length === 0) return; | |
if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset(); | |
var offsetCenter = s.params.centeredSlides ? -translate + s.size / 2 : -translate; | |
if (s.rtl) offsetCenter = s.params.centeredSlides ? translate - s.size / 2 : translate; | |
// Visible Slides | |
var containerBox = s.container[0].getBoundingClientRect(); | |
var sideBefore = isH() ? 'left' : 'top'; | |
var sideAfter = isH() ? 'right' : 'bottom'; | |
s.slides.removeClass(s.params.slideVisibleClass); | |
for (var i = 0; i < s.slides.length; i++) { | |
var slide = s.slides[i]; | |
var slideCenterOffset = (s.params.centeredSlides === true) ? slide.swiperSlideSize / 2 : 0; | |
var slideProgress = (offsetCenter - slide.swiperSlideOffset - slideCenterOffset) / (slide.swiperSlideSize + s.params.spaceBetween); | |
if (s.params.watchSlidesVisibility) { | |
var slideBefore = -(offsetCenter - slide.swiperSlideOffset - slideCenterOffset); | |
var slideAfter = slideBefore + s.slidesSizesGrid[i]; | |
var isVisible = | |
(slideBefore >= 0 && slideBefore < s.size) || | |
(slideAfter > 0 && slideAfter <= s.size) || | |
(slideBefore <= 0 && slideAfter >= s.size); | |
if (isVisible) { | |
s.slides.eq(i).addClass(s.params.slideVisibleClass); | |
} | |
} | |
slide.progress = s.rtl ? -slideProgress : slideProgress; | |
} | |
}; | |
s.updateProgress = function (translate) { | |
if (typeof translate === 'undefined') { | |
translate = s.translate || 0; | |
} | |
var translatesDiff = s.maxTranslate() - s.minTranslate(); | |
if (translatesDiff === 0) { | |
s.progress = 0; | |
s.isBeginning = s.isEnd = true; | |
} | |
else { | |
s.progress = (translate - s.minTranslate()) / (translatesDiff); | |
s.isBeginning = s.progress <= 0; | |
s.isEnd = s.progress >= 1; | |
} | |
if (s.isBeginning && s.params.onReachBeginning) s.params.onReachBeginning(s); | |
if (s.isEnd && s.params.onReachEnd) s.params.onReachEnd(s); | |
if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate); | |
if (s.params.onProgress) s.params.onProgress(s, s.progress); | |
}; | |
s.updateActiveIndex = function () { | |
var translate = s.rtl ? s.translate : -s.translate; | |
var newActiveIndex, i, snapIndex; | |
for (i = 0; i < s.slidesGrid.length; i ++) { | |
if (typeof s.slidesGrid[i + 1] !== 'undefined') { | |
if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) { | |
newActiveIndex = i; | |
} | |
else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) { | |
newActiveIndex = i + 1; | |
} | |
} | |
else { | |
if (translate >= s.slidesGrid[i]) { | |
newActiveIndex = i; | |
} | |
} | |
} | |
// Normalize slideIndex | |
if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0; | |
// for (i = 0; i < s.slidesGrid.length; i++) { | |
// if (- translate >= s.slidesGrid[i]) { | |
// newActiveIndex = i; | |
// } | |
// } | |
snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup); | |
if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1; | |
if (newActiveIndex === s.activeIndex) { | |
return; | |
} | |
s.snapIndex = snapIndex; | |
s.previousIndex = s.activeIndex; | |
s.activeIndex = newActiveIndex; | |
s.updateClasses(); | |
}; | |
/*========================= | |
Classes | |
===========================*/ | |
s.updateClasses = function () { | |
s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass); | |
var activeSlide = s.slides.eq(s.activeIndex); | |
// Active classes | |
activeSlide.addClass(s.params.slideActiveClass); | |
activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass); | |
activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass); | |
// Pagination | |
if (s.bullets && s.bullets.length > 0) { | |
s.bullets.removeClass(s.params.bulletActiveClass); | |
var bulletIndex; | |
if (s.params.loop) { | |
bulletIndex = s.activeIndex - s.loopedSlides; | |
if (bulletIndex > s.slides.length - 1 - s.loopedSlides * 2) { | |
bulletIndex = bulletIndex - (s.slides.length - s.loopedSlides * 2); | |
} | |
} | |
else { | |
if (typeof s.snapIndex !== 'undefined') { | |
bulletIndex = s.snapIndex; | |
} | |
else { | |
bulletIndex = s.activeIndex || 0; | |
} | |
} | |
s.bullets.eq(bulletIndex).addClass(s.params.bulletActiveClass); | |
} | |
// Next/active buttons | |
if (!s.params.loop) { | |
if (s.params.prevButton) { | |
if (s.isBeginning) $(s.params.prevButton).addClass(s.params.buttonDisabledClass); | |
else $(s.params.prevButton).removeClass(s.params.buttonDisabledClass); | |
} | |
if (s.params.nextButton) { | |
if (s.isEnd) $(s.params.nextButton).addClass(s.params.buttonDisabledClass); | |
else $(s.params.nextButton).removeClass(s.params.buttonDisabledClass); | |
} | |
} | |
}; | |
/*========================= | |
Pagination | |
===========================*/ | |
s.updatePagination = function () { | |
if (!s.params.pagination) return; | |
if (s.paginationContainer && s.paginationContainer.length > 0) { | |
var bulletsHTML = ''; | |
var numberOfBullets = s.params.loop ? s.slides.length - s.loopedSlides * 2 : s.snapGrid.length; | |
for (var i = 0; i < numberOfBullets; i++) { | |
if (s.params.paginationBulletRender) { | |
bulletsHTML += s.params.paginationBulletRender(i, s.params.bulletClass); | |
} | |
else { | |
bulletsHTML += '<span class="' + s.params.bulletClass + '"></span>'; | |
} | |
} | |
s.paginationContainer.html(bulletsHTML); | |
s.bullets = s.paginationContainer.find('.' + s.params.bulletClass); | |
} | |
}; | |
/*========================= | |
Common update method | |
===========================*/ | |
s.update = function (updateTranslate) { | |
s.updateContainerSize(); | |
s.updateSlidesSize(); | |
s.updateProgress(); | |
s.updatePagination(); | |
s.updateClasses(); | |
if (s.params.scrollbar && s.scrollbar) { | |
s.scrollbar.set(); | |
} | |
function forceSetTranslate() { | |
newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate()); | |
s.setWrapperTranslate(newTranslate); | |
s.updateActiveIndex(); | |
s.updateClasses(); | |
} | |
if (updateTranslate) { | |
var translated, newTranslate; | |
if (s.params.freeMode) { | |
forceSetTranslate(); | |
} | |
else { | |
if (s.params.slidesPerView === 'auto' && s.isEnd && !s.params.centeredSlides) { | |
translated = s.slideTo(s.slides.length - 1, 0, false, true); | |
} | |
else { | |
translated = s.slideTo(s.activeIndex, 0, false, true); | |
} | |
if (!translated) { | |
forceSetTranslate(); | |
} | |
} | |
} | |
}; | |
/*========================= | |
Resize Handler | |
===========================*/ | |
s.onResize = function () { | |
s.updateContainerSize(); | |
s.updateSlidesSize(); | |
s.updateProgress(); | |
if (s.params.slidesPerView === 'auto' || s.params.freeMode) s.updatePagination(); | |
if (s.params.scrollbar && s.scrollbar) { | |
s.scrollbar.set(); | |
} | |
if (s.params.freeMode) { | |
var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate()); | |
s.setWrapperTranslate(newTranslate); | |
s.updateActiveIndex(); | |
s.updateClasses(); | |
} | |
else { | |
s.updateClasses(); | |
if (s.params.slidesPerView === 'auto' && s.isEnd && !s.params.centeredSlides) { | |
s.slideTo(s.slides.length - 1, 0, false, true); | |
} | |
else { | |
s.slideTo(s.activeIndex, 0, false, true); | |
} | |
} | |
}; | |
/*========================= | |
Events | |
===========================*/ | |
//Define Touch Events | |
var desktopEvents = ['mousedown', 'mousemove', 'mouseup']; | |
if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup']; | |
else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp']; | |
s.touchEvents = { | |
start : s.support.touch || !s.params.simulateTouch ? 'touchstart' : desktopEvents[0], | |
move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1], | |
end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2] | |
}; | |
// WP8 Touch Events Fix | |
if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) { | |
(s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction); | |
} | |
// Attach/detach events | |
s.events = function (detach) { | |
var actionDom = detach ? 'off' : 'on'; | |
var action = detach ? 'removeEventListener' : 'addEventListener'; | |
var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0]; | |
var target = s.support.touch ? touchEventsTarget : document; | |
var moveCapture = s.params.nested ? true : false; | |
//Touch Events | |
if (s.browser.ie) { | |
touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false); | |
target[action](s.touchEvents.move, s.onTouchMove, moveCapture); | |
target[action](s.touchEvents.end, s.onTouchEnd, false); | |
} | |
else { | |
if (s.support.touch) { | |
touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false); | |
touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture); | |
touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false); | |
} | |
if (params.simulateTouch && !s.device.ios && !s.device.android) { | |
touchEventsTarget[action]('mousedown', s.onTouchStart, false); | |
target[action]('mousemove', s.onTouchMove, moveCapture); | |
target[action]('mouseup', s.onTouchEnd, false); | |
} | |
} | |
window[action]('resize', s.onResize); | |
// Next, Prev, Index | |
if (s.params.nextButton) $(s.params.nextButton)[actionDom]('click', s.onClickNext); | |
if (s.params.prevButton) $(s.params.prevButton)[actionDom]('click', s.onClickPrev); | |
if (s.params.pagination && s.params.paginationClickable) { | |
$(s.paginationContainer)[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex); | |
} | |
// Prevent Links Clicks | |
if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true); | |
}; | |
s.attachEvents = function (detach) { | |
s.events(); | |
}; | |
s.detachEvents = function () { | |
s.events(true); | |
}; | |
/*========================= | |
Handle Clicks | |
===========================*/ | |
// Prevent Clicks | |
s.allowClick = true; | |
s.preventClicks = function (e) { | |
if (!s.allowClick) { | |
if (s.params.preventClicks) e.preventDefault(); | |
if (s.params.preventClicksPropagation) { | |
e.stopPropagation(); | |
e.stopImmediatePropagation(); | |
} | |
} | |
}; | |
// Clicks | |
s.onClickNext = function (e) { | |
e.preventDefault(); | |
s.slideNext(); | |
}; | |
s.onClickPrev = function (e) { | |
e.preventDefault(); | |
s.slidePrev(); | |
}; | |
s.onClickIndex = function (e) { | |
e.preventDefault(); | |
var index = $(this).index() * s.params.slidesPerGroup; | |
if (s.params.loop) index = index + s.loopedSlides; | |
s.slideTo(index); | |
}; | |
/*========================= | |
Handle Touches | |
===========================*/ | |
function findElementInEvent(e, selector) { | |
var el = $(e.target); | |
if (!el.is(selector)) { | |
if (typeof selector === 'string') { | |
el = el.parents(selector); | |
} | |
else if (selector.nodeType) { | |
var found; | |
el.parents().each(function (index, _el) { | |
if (_el === selector) found = selector; | |
}); | |
if (!found) return undefined; | |
else return selector; | |
} | |
} | |
if (el.length === 0) { | |
return undefined; | |
} | |
return el[0]; | |
} | |
s.updateClickedSlide = function (e) { | |
var slide = findElementInEvent(e, '.' + s.params.slideClass); | |
if (slide) { | |
s.clickedSlide = slide; | |
s.clickedIndex = $(slide).index(); | |
} | |
else { | |
s.clickedSlide = undefined; | |
s.clickedIndex = undefined; | |
return; | |
} | |
if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) { | |
var slideToIndex = s.clickedIndex, | |
realIndex; | |
if (s.params.loop) { | |
realIndex = $(s.clickedSlide).attr('data-swiper-slide-index'); | |
if (slideToIndex > s.slides.length - s.params.slidesPerView) { | |
s.fixLoop(); | |
slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]').eq(0).index(); | |
setTimeout(function () { | |
s.slideTo(slideToIndex); | |
}, 0); | |
} | |
else if (slideToIndex < s.params.slidesPerView - 1) { | |
s.fixLoop(); | |
var duplicatedSlides = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]'); | |
slideToIndex = duplicatedSlides.eq(duplicatedSlides.length - 1).index(); | |
setTimeout(function () { | |
s.slideTo(slideToIndex); | |
}, 0); | |
} | |
else { | |
s.slideTo(slideToIndex); | |
} | |
} | |
else { | |
s.slideTo(slideToIndex); | |
} | |
} | |
}; | |
var isTouched, | |
isMoved, | |
touchStartTime, | |
isScrolling, | |
currentTranslate, | |
startTranslate, | |
allowThresholdMove, | |
// Form elements to match | |
formElements = 'input, select, textarea, button', | |
// Last click time | |
lastClickTime = Date.now(), clickTimeout, | |
//Velocities | |
velocities = [], | |
allowMomentumBounce; | |
// Animating Flag | |
s.animating = false; | |
// Touches information | |
s.touches = { | |
startX: 0, | |
startY: 0, | |
currentX: 0, | |
currentY: 0, | |
diff: 0 | |
}; | |
// Touch handlers | |
var isTouchEvent; | |
s.onTouchStart = function (e) { | |
if (e.originalEvent) e = e.originalEvent; | |
isTouchEvent = e.type === 'touchstart'; | |
if (!isTouchEvent && 'which' in e && e.which === 3) return; | |
if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) { | |
s.allowClick = true; | |
return; | |
} | |
if (s.params.swipeHandler) { | |
if (!findElementInEvent(e, s.params.swipeHandler)) return; | |
} | |
isTouched = true; | |
isMoved = false; | |
isScrolling = undefined; | |
s.touches.startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX; | |
s.touches.startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY; | |
touchStartTime = Date.now(); | |
s.allowClick = true; | |
s.updateContainerSize(); | |
s.swipeDirection = undefined; | |
if (s.params.threshold > 0) allowThresholdMove = false; | |
if (e.type !== 'touchstart') { | |
var preventDefault = true; | |
if ($(e.target).is(formElements)) preventDefault = false; | |
if (document.activeElement && $(document.activeElement).is(formElements)) { | |
document.activeElement.blur(); | |
} | |
if (preventDefault) { | |
e.preventDefault(); | |
} | |
} | |
if (s.params.onTouchStart) s.params.onTouchStart(s, e); | |
}; | |
s.onTouchMove = function (e) { | |
if (e.originalEvent) e = e.originalEvent; | |
if (isTouchEvent && e.type === 'mousemove') return; | |
if (e.preventedByNestedSwiper) return; | |
if (s.params.onlyExternal) { | |
isMoved = true; | |
s.allowClick = false; | |
return; | |
} | |
if (isTouchEvent && document.activeElement) { | |
if (e.target === document.activeElement && $(e.target).is(formElements)) { | |
isMoved = true; | |
s.allowClick = false; | |
return; | |
} | |
} | |
if (s.params.onTouchMove) s.params.onTouchMove(s, e); | |
s.allowClick = false; | |
if (e.targetTouches && e.targetTouches.length > 1) return; | |
s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX; | |
s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY; | |
if (typeof isScrolling === 'undefined') { | |
var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI; | |
isScrolling = isH() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle); | |
// isScrolling = !!(isScrolling || Math.abs(touchesCurrent.y - touchesStart.y) > Math.abs(touchesCurrent.x - touchesStart.x)); | |
} | |
if (isScrolling && s.params.onTouchMoveOpposite) { | |
s.params.onTouchMoveOpposite(s, e); | |
} | |
if (!isTouched) return; | |
if (isScrolling) { | |
isTouched = false; | |
return; | |
} | |
if (s.params.onSliderMove) s.params.onSliderMove(s, e); | |
e.preventDefault(); | |
if (s.params.touchMoveStopPropagation && !s.params.nested) { | |
e.stopPropagation(); | |
} | |
if (!isMoved) { | |
if (params.loop) { | |
s.fixLoop(); | |
} | |
startTranslate = s.params.effect === 'cube' ? ((s.rtl ? -s.translate: s.translate) || 0) : s.getWrapperTranslate(); | |
s.setWrapperTransition(0); | |
if (s.animating) { | |
s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd'); | |
} | |
if (s.params.autoplay && s.autoplaying) { | |
if (s.params.autoplayDisableOnInteraction) { | |
s.stopAutoplay(); | |
} | |
else { | |
s.pauseAutoplay(); | |
} | |
} | |
allowMomentumBounce = false; | |
//Grab Cursor | |
if (s.params.grabCursor) { | |
s.container[0].style.cursor = 'move'; | |
s.container[0].style.cursor = '-webkit-grabbing'; | |
s.container[0].style.cursor = '-moz-grabbin'; | |
s.container[0].style.cursor = 'grabbing'; | |
} | |
} | |
isMoved = true; | |
var diff = s.touches.diff = isH() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY; | |
diff = diff * s.params.touchRatio; | |
if (s.rtl) diff = -diff; | |
s.swipeDirection = diff > 0 ? 'prev' : 'next'; | |
currentTranslate = diff + startTranslate; | |
var disableParentSwiper = true; | |
if ((diff > 0 && currentTranslate > s.minTranslate())) { | |
disableParentSwiper = false; | |
if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio); | |
} | |
else if (diff < 0 && currentTranslate < s.maxTranslate()) { | |
disableParentSwiper = false; | |
if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio); | |
} | |
if (disableParentSwiper) { | |
e.preventedByNestedSwiper = true; | |
} | |
// Directions locks | |
if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) { | |
currentTranslate = startTranslate; | |
} | |
if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) { | |
currentTranslate = startTranslate; | |
} | |
if (!s.params.followFinger) return; | |
// Threshold | |
if (s.params.threshold > 0) { | |
if (Math.abs(diff) > s.params.threshold || allowThresholdMove) { | |
if (!allowThresholdMove) { | |
allowThresholdMove = true; | |
s.touches.startX = s.touches.currentX; | |
s.touches.startY = s.touches.currentY; | |
currentTranslate = startTranslate; | |
s.touches.diff = isH() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY; | |
return; | |
} | |
} | |
else { | |
currentTranslate = startTranslate; | |
return; | |
} | |
} | |
// Update active index in free mode | |
if (s.params.freeMode || s.params.watchSlidesProgress) { | |
s.updateActiveIndex(); | |
} | |
if (s.params.freeMode) { | |
//Velocity | |
if (velocities.length === 0) { | |
velocities.push({ | |
position: s.touches[isH() ? 'startX' : 'startY'], | |
time: touchStartTime | |
}); | |
} | |
velocities.push({ | |
position: s.touches[isH() ? 'currentX' : 'currentY'], | |
time: (new Date()).getTime() | |
}); | |
} | |
// Update progress | |
s.updateProgress(currentTranslate); | |
// Update translate | |
s.setWrapperTranslate(currentTranslate); | |
}; | |
s.onTouchEnd = function (e) { | |
if (e.originalEvent) e = e.originalEvent; | |
if (s.params.onTouchEnd) s.params.onTouchEnd(s, e); | |
if (!isTouched) return; | |
//Return Grab Cursor | |
if (s.params.grabCursor && isMoved && isTouched) { | |
s.container[0].style.cursor = 'move'; | |
s.container[0].style.cursor = '-webkit-grab'; | |
s.container[0].style.cursor = '-moz-grab'; | |
s.container[0].style.cursor = 'grab'; | |
} | |
// Time diff | |
var touchEndTime = Date.now(); | |
var timeDiff = touchEndTime - touchStartTime; | |
// Tap, doubleTap, Click | |
if (s.allowClick) { | |
s.updateClickedSlide(e); | |
if (s.params.onTap) s.params.onTap(s, e); | |
if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) { | |
if (clickTimeout) clearTimeout(clickTimeout); | |
clickTimeout = setTimeout(function () { | |
if (!s) return; | |
if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) { | |
s.paginationContainer.toggleClass(s.params.paginationHiddenClass); | |
} | |
if (s.params.onClick) s.params.onClick(s, e); | |
}, 300); | |
} | |
if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) { | |
if (clickTimeout) clearTimeout(clickTimeout); | |
if (s.params.onDoubleTap) { | |
s.params.onDoubleTap(s, e); | |
} | |
} | |
} | |
lastClickTime = Date.now(); | |
setTimeout(function () { | |
if (s && s.allowClick) s.allowClick = true; | |
}, 0); | |
if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) { | |
isTouched = isMoved = false; | |
return; | |
} | |
isTouched = isMoved = false; | |
var currentPos; | |
if (s.params.followFinger) { | |
currentPos = s.rtl ? s.translate : -s.translate; | |
} | |
else { | |
currentPos = -currentTranslate; | |
} | |
if (s.params.freeMode) { | |
if (currentPos < -s.minTranslate()) { | |
s.slideTo(s.activeIndex); | |
return; | |
} | |
else if (currentPos > -s.maxTranslate()) { | |
s.slideTo(s.slides.length - 1); | |
return; | |
} | |
if (s.params.freeModeMomentum) { | |
if (velocities.length > 1) { | |
var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop(); | |
var distance = lastMoveEvent.position - velocityEvent.position; | |
var time = lastMoveEvent.time - velocityEvent.time; | |
s.velocity = distance / time; | |
s.velocity = s.velocity / 2; | |
if (Math.abs(s.velocity) < 0.02) { | |
s.velocity = 0; | |
} | |
// this implies that the user stopped moving a finger then released. | |
// There would be no events with distance zero, so the last event is stale. | |
if (time > 150 || (new Date().getTime() - lastMoveEvent.time) > 300) { | |
s.velocity = 0; | |
} | |
} else { | |
s.velocity = 0; | |
} | |
velocities.length = 0; | |
var momentumDuration = 1000 * s.params.freeModeMomentumRatio; | |
var momentumDistance = s.velocity * momentumDuration; | |
var newPosition = s.translate + momentumDistance; | |
if (s.rtl) newPosition = - newPosition; | |
var doBounce = false; | |
var afterBouncePosition; | |
var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio; | |
if (newPosition < s.maxTranslate()) { | |
if (s.params.freeModeMomentumBounce) { | |
if (newPosition + s.maxTranslate() < -bounceAmount) { | |
newPosition = s.maxTranslate() - bounceAmount; | |
} | |
afterBouncePosition = s.maxTranslate(); | |
doBounce = true; | |
allowMomentumBounce = true; | |
} | |
else { | |
newPosition = s.maxTranslate(); | |
} | |
} | |
if (newPosition > s.minTranslate()) { | |
if (s.params.freeModeMomentumBounce) { | |
if (newPosition - s.minTranslate() > bounceAmount) { | |
newPosition = s.minTranslate() + bounceAmount; | |
} | |
afterBouncePosition = s.minTranslate(); | |
doBounce = true; | |
allowMomentumBounce = true; | |
} | |
else { | |
newPosition = s.minTranslate(); | |
} | |
} | |
//Fix duration | |
if (s.velocity !== 0) { | |
if (s.rtl) { | |
momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity); | |
} | |
else { | |
momentumDuration = Math.abs((newPosition - s.translate) / s.velocity); | |
} | |
} | |
if (s.params.freeModeMomentumBounce && doBounce) { | |
s.updateProgress(afterBouncePosition); | |
s.setWrapperTransition(momentumDuration); | |
s.setWrapperTranslate(newPosition); | |
s.onTransitionStart(); | |
s.animating = true; | |
s.wrapper.transitionEnd(function () { | |
if (!allowMomentumBounce) return; | |
if (s.params.onMomentumBounce) s.params.onMomentumBounce(s); | |
s.setWrapperTransition(s.params.speed); | |
s.setWrapperTranslate(afterBouncePosition); | |
s.wrapper.transitionEnd(function () { | |
s.onTransitionEnd(); | |
}); | |
}); | |
} else if (s.velocity) { | |
s.updateProgress(newPosition); | |
s.setWrapperTransition(momentumDuration); | |
s.setWrapperTranslate(newPosition); | |
s.onTransitionStart(); | |
if (!s.animating) { | |
s.animating = true; | |
s.wrapper.transitionEnd(function () { | |
s.onTransitionEnd(); | |
}); | |
} | |
} else { | |
s.updateProgress(newPosition); | |
} | |
s.updateActiveIndex(); | |
} | |
if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) { | |
s.updateProgress(); | |
s.updateActiveIndex(); | |
} | |
return; | |
} | |
// Find current slide | |
var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0]; | |
for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) { | |
if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') { | |
if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) { | |
stopIndex = i; | |
groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i]; | |
} | |
} | |
else { | |
if (currentPos >= s.slidesGrid[i]) { | |
stopIndex = i; | |
groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2]; | |
} | |
} | |
} | |
// Find current slide size | |
var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize; | |
if (timeDiff > s.params.longSwipesMs) { | |
// Long touches | |
if (!s.params.longSwipes) { | |
s.slideTo(s.activeIndex); | |
return; | |
} | |
if (s.swipeDirection === 'next') { | |
if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup); | |
else s.slideTo(stopIndex); | |
} | |
if (s.swipeDirection === 'prev') { | |
if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup); | |
else s.slideTo(stopIndex); | |
} | |
} | |
else { | |
// Short swipes | |
if (!s.params.shortSwipes) { | |
s.slideTo(s.activeIndex); | |
return; | |
} | |
if (s.swipeDirection === 'next') { | |
s.slideTo(stopIndex + s.params.slidesPerGroup); | |
} | |
if (s.swipeDirection === 'prev') { | |
s.slideTo(stopIndex); | |
} | |
} | |
}; | |
/*========================= | |
Transitions | |
===========================*/ | |
s._slideTo = function (slideIndex, speed) { | |
return s.slideTo(slideIndex, speed, true, true); | |
}; | |
s.slideTo = function (slideIndex, speed, runCallbacks, internal) { | |
if (typeof runCallbacks === 'undefined') runCallbacks = true; | |
if (typeof slideIndex === 'undefined') slideIndex = 0; | |
if (slideIndex < 0) slideIndex = 0; | |
s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup); | |
if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1; | |
var translate = - s.snapGrid[s.snapIndex]; | |
// Stop autoplay | |
if (s.params.autoplay && s.autoplaying) { | |
if (internal || !s.params.autoplayDisableOnInteraction) { | |
s.pauseAutoplay(speed); | |
} | |
else { | |
s.stopAutoplay(); | |
} | |
} | |
// Update progress | |
s.updateProgress(translate); | |
// Normalize slideIndex | |
for (var i = 0; i < s.slidesGrid.length; i++) { | |
if (- translate >= s.slidesGrid[i]) { | |
slideIndex = i; | |
} | |
} | |
if (typeof speed === 'undefined') speed = s.params.speed; | |
s.previousIndex = s.activeIndex || 0; | |
s.activeIndex = slideIndex; | |
if (translate === s.translate) { | |
s.updateClasses(); | |
return false; | |
} | |
s.onTransitionStart(runCallbacks); | |
var translateX = isH() ? translate : 0, translateY = isH() ? 0 : translate; | |
if (speed === 0) { | |
s.setWrapperTransition(0); | |
s.setWrapperTranslate(translate); | |
s.onTransitionEnd(runCallbacks); | |
} | |
else { | |
s.setWrapperTransition(speed); | |
s.setWrapperTranslate(translate); | |
if (!s.animating) { | |
s.animating = true; | |
s.wrapper.transitionEnd(function () { | |
s.onTransitionEnd(runCallbacks); | |
}); | |
} | |
} | |
s.updateClasses(); | |
return true; | |
}; | |
s.onTransitionStart = function (runCallbacks) { | |
if (typeof runCallbacks === 'undefined') runCallbacks = true; | |
if (s.lazy) s.lazy.onTransitionStart(); | |
if (runCallbacks) { | |
if (s.params.onTransitionStart) s.params.onTransitionStart(s); | |
if (s.params.onSlideChangeStart && s.activeIndex !== s.previousIndex) s.params.onSlideChangeStart(s); | |
} | |
}; | |
s.onTransitionEnd = function (runCallbacks) { | |
s.animating = false; | |
s.setWrapperTransition(0); | |
if (typeof runCallbacks === 'undefined') runCallbacks = true; | |
if (s.lazy) s.lazy.onTransitionEnd(); | |
if (runCallbacks) { | |
if (s.params.onTransitionEnd) s.params.onTransitionEnd(s); | |
if (s.params.onSlideChangeEnd && s.activeIndex !== s.previousIndex) s.params.onSlideChangeEnd(s); | |
} | |
}; | |
s.slideNext = function (runCallbacks, speed, internal) { | |
if (s.params.loop) { | |
if (s.animating) return false; | |
s.fixLoop(); | |
var clientLeft = s.container[0].clientLeft; | |
return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal); | |
} | |
else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal); | |
}; | |
s._slideNext = function (speed) { | |
return s.slideNext(true, speed, true); | |
}; | |
s.slidePrev = function (runCallbacks, speed, internal) { | |
if (s.params.loop) { | |
if (s.animating) return false; | |
s.fixLoop(); | |
var clientLeft = s.container[0].clientLeft; | |
return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal); | |
} | |
else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal); | |
}; | |
s._slidePrev = function (speed) { | |
return s.slidePrev(true, speed, true); | |
}; | |
s.slideReset = function (runCallbacks, speed, internal) { | |
return s.slideTo(s.activeIndex, speed, runCallbacks); | |
}; | |
/*========================= | |
Translate/transition helpers | |
===========================*/ | |
s.setWrapperTransition = function (duration, byController) { | |
s.wrapper.transition(duration); | |
if (s.params.onSetTransition) s.params.onSetTransition(s, duration); | |
if (s.params.effect !== 'slide' && s.effects[s.params.effect]) { | |
s.effects[s.params.effect].setTransition(duration); | |
} | |
if (s.params.parallax && s.parallax) { | |
s.parallax.setTransition(duration); | |
} | |
if (s.params.scrollbar && s.scrollbar) { | |
s.scrollbar.setTransition(duration); | |
} | |
if (s.params.control && s.controller) { | |
s.controller.setTransition(duration, byController); | |
} | |
}; | |
s.setWrapperTranslate = function (translate, updateActiveIndex, byController) { | |
var x = 0, y = 0, z = 0; | |
if (isH()) { | |
x = s.rtl ? -translate : translate; | |
} | |
else { | |
y = translate; | |
} | |
if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)'); | |
else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)'); | |
s.translate = isH() ? x : y; | |
if (updateActiveIndex) s.updateActiveIndex(); | |
if (s.params.effect !== 'slide' && s.effects[s.params.effect]) { | |
s.effects[s.params.effect].setTranslate(s.translate); | |
} | |
if (s.params.parallax && s.parallax) { | |
s.parallax.setTranslate(s.translate); | |
} | |
if (s.params.scrollbar && s.scrollbar) { | |
s.scrollbar.setTranslate(s.translate); | |
} | |
if (s.params.control && s.controller) { | |
s.controller.setTranslate(s.translate, byController); | |
} | |
if (s.params.hashnav && s.hashnav) { | |
s.hashnav.setHash(); | |
} | |
if (s.params.onSetTranslate) s.params.onSetTranslate(s, s.translate); | |
}; | |
s.getTranslate = function (el, axis) { | |
var matrix, curTransform, curStyle, transformMatrix; | |
// automatic axis detection | |
if (typeof axis === 'undefined') { | |
axis = 'x'; | |
} | |
curStyle = window.getComputedStyle(el, null); | |
if (window.WebKitCSSMatrix) { | |
// Some old versions of Webkit choke when 'none' is passed; pass | |
// empty string instead in this case | |
transformMatrix = new WebKitCSSMatrix(curStyle.webkitTransform === 'none' ? '' : curStyle.webkitTransform); | |
} | |
else { | |
transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,'); | |
matrix = transformMatrix.toString().split(','); | |
} | |
if (axis === 'x') { | |
//Latest Chrome and webkits Fix | |
if (window.WebKitCSSMatrix) | |
curTransform = transformMatrix.m41; | |
//Crazy IE10 Matrix | |
else if (matrix.length === 16) | |
curTransform = parseFloat(matrix[12]); | |
//Normal Browsers | |
else | |
curTransform = parseFloat(matrix[4]); | |
} | |
if (axis === 'y') { | |
//Latest Chrome and webkits Fix | |
if (window.WebKitCSSMatrix) | |
curTransform = transformMatrix.m42; | |
//Crazy IE10 Matrix | |
else if (matrix.length === 16) | |
curTransform = parseFloat(matrix[13]); | |
//Normal Browsers | |
else | |
curTransform = parseFloat(matrix[5]); | |
} | |
if (s.rtl && curTransform) curTransform = -curTransform; | |
return curTransform || 0; | |
}; | |
s.getWrapperTranslate = function (axis) { | |
if (typeof axis === 'undefined') { | |
axis = isH() ? 'x' : 'y'; | |
} | |
return s.getTranslate(s.wrapper[0], axis); | |
}; | |
/*========================= | |
Observer | |
===========================*/ | |
s.observers = []; | |
function initObserver(target, options) { | |
options = options || {}; | |
// create an observer instance | |
var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver; | |
var observer = new ObserverFunc(function (mutations) { | |
mutations.forEach(function (mutation) { | |
s.onResize(); | |
if (s.params.onObserverUpdate) s.params.onObserverUpdate(s, mutation); | |
}); | |
}); | |
observer.observe(target, { | |
attributes: typeof options.attributes === 'undefined' ? true : options.attributes, | |
childList: typeof options.childList === 'undefined' ? true : options.childList, | |
characterData: typeof options.characterData === 'undefined' ? true : options.characterData | |
}); | |
s.observers.push(observer); | |
} | |
s.initObservers = function () { | |
if (s.params.observeParents) { | |
var containerParents = s.container.parents(); | |
for (var i = 0; i < containerParents.length; i++) { | |
initObserver(containerParents[i]); | |
} | |
} | |
// Observe container | |
initObserver(s.container[0], {childList: false}); | |
// Observe wrapper | |
initObserver(s.wrapper[0], {attributes: false}); | |
}; | |
s.disconnectObservers = function () { | |
for (var i = 0; i < s.observers.length; i++) { | |
s.observers[i].disconnect(); | |
} | |
s.observers = []; | |
}; | |
/*========================= | |
Loop | |
===========================*/ | |
// Create looped slides | |
s.createLoop = function () { | |
// Remove duplicated slides | |
s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove(); | |
var slides = s.wrapper.children('.' + s.params.slideClass); | |
s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10); | |
s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides; | |
if (s.loopedSlides > slides.length) { | |
s.loopedSlides = slides.length; | |
} | |
var prependSlides = [], appendSlides = [], i; | |
slides.each(function (index, el) { | |
var slide = $(this); | |
if (index < s.loopedSlides) appendSlides.push(el); | |
if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el); | |
slide.attr('data-swiper-slide-index', index); | |
}); | |
for (i = 0; i < appendSlides.length; i++) { | |
s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass)); | |
} | |
for (i = prependSlides.length - 1; i >= 0; i--) { | |
s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass)); | |
} | |
}; | |
s.destroyLoop = function () { | |
s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove(); | |
}; | |
s.fixLoop = function () { | |
var newIndex; | |
//Fix For Negative Oversliding | |
if (s.activeIndex < s.loopedSlides) { | |
newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex; | |
newIndex = newIndex + s.loopedSlides; | |
s.slideTo(newIndex, 0, false, true); | |
} | |
//Fix For Positive Oversliding | |
else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) { | |
newIndex = -s.slides.length + s.activeIndex + s.loopedSlides; | |
newIndex = newIndex + s.loopedSlides; | |
s.slideTo(newIndex, 0, false, true); | |
} | |
}; | |
/*========================= | |
Append/Prepend/Remove Slides | |
===========================*/ | |
s.appendSlide = function (slides) { | |
if (s.params.loop) { | |
s.destroyLoop(); | |
} | |
if (typeof slides === 'object' && slides.length) { | |
for (var i = 0; i < slides.length; i++) { | |
if (slides[i]) s.wrapper.append(slides[i]); | |
} | |
} | |
else { | |
s.wrapper.append(slides); | |
} | |
if (s.params.loop) { | |
s.createLoop(); | |
} | |
if (!(s.params.observer && s.support.observer)) { | |
s.update(true); | |
} | |
}; | |
s.prependSlide = function (slides) { | |
if (s.params.loop) { | |
s.destroyLoop(); | |
} | |
var newActiveIndex = s.activeIndex + 1; | |
if (typeof slides === 'object' && slides.length) { | |
for (var i = 0; i < slides.length; i++) { | |
if (slides[i]) s.wrapper.prepend(slides[i]); | |
} | |
newActiveIndex = s.activeIndex + slides.length; | |
} | |
else { | |
s.wrapper.prepend(slides); | |
} | |
if (s.params.loop) { | |
s.createLoop(); | |
} | |
if (!(s.params.observer && s.support.observer)) { | |
s.update(true); | |
} | |
s.slideTo(newActiveIndex, 0, false); | |
}; | |
s.removeSlide = function (slidesIndexes) { | |
if (s.params.loop) { | |
s.destroyLoop(); | |
} | |
var newActiveIndex = s.activeIndex, | |
indexToRemove; | |
if (typeof slidesIndexes === 'object' && slidesIndexes.length) { | |
for (var i = 0; i < slidesIndexes.length; i++) { | |
indexToRemove = slidesIndexes[i]; | |
if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove(); | |
if (indexToRemove < newActiveIndex) newActiveIndex--; | |
} | |
newActiveIndex = Math.max(newActiveIndex, 0); | |
} | |
else { | |
indexToRemove = slidesIndexes; | |
if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove(); | |
if (indexToRemove < newActiveIndex) newActiveIndex--; | |
newActiveIndex = Math.max(newActiveIndex, 0); | |
} | |
if (!(s.params.observer && s.support.observer)) { | |
s.update(true); | |
} | |
s.slideTo(newActiveIndex, 0, false); | |
}; | |
s.removeAllSlides = function () { | |
var slidesIndexes = []; | |
for (var i = 0; i < s.slides.length; i++) { | |
slidesIndexes.push(i); | |
} | |
s.removeSlide(slidesIndexes); | |
}; | |
/*========================= | |
Effects | |
===========================*/ | |
s.effects = { | |
fade: { | |
setTranslate: function () { | |
for (var i = 0; i < s.slides.length; i++) { | |
var slide = s.slides.eq(i); | |
var offset = slide[0].swiperSlideOffset; | |
var tx = -offset - s.translate; | |
var ty = 0; | |
if (!isH()) { | |
ty = tx; | |
tx = 0; | |
} | |
var slideOpacity = s.params.fade.crossFade ? | |
Math.max(1 - Math.abs(slide[0].progress), 0) : | |
1 + Math.min(Math.max(slide[0].progress, -1), 0); | |
slide | |
.css({ | |
opacity: slideOpacity | |
}) | |
.transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)'); | |
} | |
}, | |
setTransition: function (duration) { | |
s.slides.transition(duration); | |
} | |
}, | |
cube: { | |
setTranslate: function () { | |
var wrapperRotate = 0, cubeShadow; | |
if (s.params.cube.shadow) { | |
if (isH()) { | |
cubeShadow = s.wrapper.find('.swiper-cube-shadow'); | |
if (cubeShadow.length === 0) { | |
cubeShadow = $('<div class="swiper-cube-shadow"></div>'); | |
s.wrapper.append(cubeShadow); | |
} | |
cubeShadow.css({height: s.width + 'px'}); | |
} | |
else { | |
cubeShadow = s.container.find('.swiper-cube-shadow'); | |
if (cubeShadow.length === 0) { | |
cubeShadow = $('<div class="swiper-cube-shadow"></div>'); | |
s.container.append(cubeShadow); | |
} | |
} | |
} | |
for (var i = 0; i < s.slides.length; i++) { | |
var slide = s.slides.eq(i); | |
var slideAngle = i * 90; | |
var round = Math.floor(slideAngle / 360); | |
if (s.rtl) { | |
slideAngle = -slideAngle; | |
round = Math.floor(-slideAngle / 360); | |
} | |
var progress = Math.max(Math.min(slide[0].progress, 1), -1); | |
var tx = 0, ty = 0, tz = 0; | |
if (i % 4 === 0) { | |
tx = - round * 4 * s.size; | |
tz = 0; | |
} | |
else if ((i - 1) % 4 === 0) { | |
tx = 0; | |
tz = - round * 4 * s.size; | |
} | |
else if ((i - 2) % 4 === 0) { | |
tx = s.size + round * 4 * s.size; | |
tz = s.size; | |
} | |
else if ((i - 3) % 4 === 0) { | |
tx = - s.size; | |
tz = 3 * s.size + s.size * 4 * round; | |
} | |
if (s.rtl) { | |
tx = -tx; | |
} | |
if (!isH()) { | |
ty = tx; | |
tx = 0; | |
} | |
var transform = 'rotateX(' + (isH() ? 0 : -slideAngle) + 'deg) rotateY(' + (isH() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)'; | |
if (progress <= 1 && progress > -1) { | |
wrapperRotate = i * 90 + progress * 90; | |
if (s.rtl) wrapperRotate = -i * 90 - progress * 90; | |
} | |
slide.transform(transform); | |
if (s.params.cube.slideShadows) { | |
//Set shadows | |
var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top'); | |
var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom'); | |
if (shadowBefore.length === 0) { | |
shadowBefore = $('<div class="swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '"></div>'); | |
slide.append(shadowBefore); | |
} | |
if (shadowAfter.length === 0) { | |
shadowAfter = $('<div class="swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '"></div>'); | |
slide.append(shadowAfter); | |
} | |
var shadowOpacity = slide[0].progress; | |
if (shadowBefore.length) shadowBefore[0].style.opacity = -slide[0].progress; | |
if (shadowAfter.length) shadowAfter[0].style.opacity = slide[0].progress; | |
} | |
} | |
s.wrapper.css({ | |
'-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px', | |
'-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px', | |
'-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px', | |
'transform-origin': '50% 50% -' + (s.size / 2) + 'px' | |
}); | |
if (s.params.cube.shadow) { | |
if (isH()) { | |
cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')'); | |
} | |
else { | |
var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90; | |
var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2); | |
var scale1 = s.params.cube.shadowScale, | |
scale2 = s.params.cube.shadowScale / multiplier, | |
offset = s.params.cube.shadowOffset; | |
cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)'); | |
} | |
} | |
var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0; | |
s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (isH() ? 0 : wrapperRotate) + 'deg) rotateY(' + (isH() ? -wrapperRotate : 0) + 'deg)'); | |
}, | |
setTransition: function (duration) { | |
s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration); | |
if (s.params.cube.shadow && !isH()) { | |
s.container.find('.swiper-cube-shadow').transition(duration); | |
} | |
} | |
}, | |
coverflow: { | |
setTranslate: function () { | |
var transform = s.translate; | |
var center = isH() ? -transform + s.width / 2 : -transform + s.height / 2; | |
var rotate = isH() ? s.params.coverflow.rotate: -s.params.coverflow.rotate; | |
var translate = s.params.coverflow.depth; | |
//Each slide offset from center | |
for (var i = 0, length = s.slides.length; i < length; i++) { | |
var slide = s.slides.eq(i); | |
var slideSize = s.slidesSizesGrid[i]; | |
var slideOffset = slide[0].swiperSlideOffset; | |
var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier; | |
var rotateY = isH() ? rotate * offsetMultiplier : 0; | |
var rotateX = isH() ? 0 : rotate * offsetMultiplier; | |
// var rotateZ = 0 | |
var translateZ = -translate * Math.abs(offsetMultiplier); | |
var translateY = isH() ? 0 : s.params.coverflow.stretch * (offsetMultiplier); | |
var translateX = isH() ? s.params.coverflow.stretch * (offsetMultiplier) : 0; | |
//Fix for ultra small values | |
if (Math.abs(translateX) < 0.001) translateX = 0; | |
if (Math.abs(translateY) < 0.001) translateY = 0; | |
if (Math.abs(translateZ) < 0.001) translateZ = 0; | |
if (Math.abs(rotateY) < 0.001) rotateY = 0; | |
if (Math.abs(rotateX) < 0.001) rotateX = 0; | |
var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)'; | |
slide.transform(slideTransform); | |
slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1; | |
if (s.params.coverflow.slideShadows) { | |
//Set shadows | |
var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top'); | |
var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom'); | |
if (shadowBefore.length === 0) { | |
shadowBefore = $('<div class="swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '"></div>'); | |
slide.append(shadowBefore); | |
} | |
if (shadowAfter.length === 0) { | |
shadowAfter = $('<div class="swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '"></div>'); | |
slide.append(shadowAfter); | |
} | |
if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0; | |
if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0; | |
} | |
} | |
//Set correct perspective for IE10 | |
if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) { | |
var ws = s.wrapper.style; | |
ws.perspectiveOrigin = center + 'px 50%'; | |
} | |
}, | |
setTransition: function (duration) { | |
s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration); | |
} | |
} | |
}; | |
/*========================= | |
Images Lazy Loading | |
===========================*/ | |
s.lazy = { | |
initialImageLoaded: false, | |
loadImageInSlide: function (index) { | |
if (typeof index === 'undefined') return; | |
if (s.slides.length === 0) return; | |
var slide = s.slides.eq(index); | |
var img = slide.find('img.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)'); | |
if (img.length === 0) return; | |
img.each(function () { | |
var _img = $(this); | |
_img.addClass('swiper-lazy-loading'); | |
var src = _img.attr('data-src'); | |
s.loadImage(_img[0], src, false, function () { | |
_img.attr('src', src); | |
_img.removeAttr('data-src'); | |
_img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading'); | |
slide.find('.swiper-lazy-preloader, .preloader').remove(); | |
if (s.params.onLazyImageLoaded) { | |
s.params.onLazyImageLoaded(s, slide[0], _img[0]); | |
} | |
}); | |
if (s.params.onLazyImageLoad) { | |
s.params.onLazyImageLoad(s, slide[0], _img[0]); | |
} | |
}); | |
}, | |
load: function () { | |
if (s.params.watchSlidesVisibility) { | |
s.wrapper.children('.' + s.params.slideVisibleClass).each(function () { | |
s.lazy.loadImageInSlide($(this).index()); | |
}); | |
} | |
else { | |
if (s.params.slidesPerView > 1) { | |
for (var i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) { | |
if (s.slides[i]) s.lazy.loadImageInSlide(i); | |
} | |
} | |
else { | |
s.lazy.loadImageInSlide(s.activeIndex); | |
} | |
} | |
if (s.params.lazyLoadingInPrevNext) { | |
var nextSlide = s.wrapper.children('.' + s.params.slideNextClass); | |
if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index()); | |
var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass); | |
if (prevSlide.length > 0) s.loadImageInSlide(prevSlide.index()); | |
} | |
}, | |
onTransitionStart: function () { | |
if (s.params.lazyLoading) { | |
if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) { | |
s.lazy.initialImageLoaded = true; | |
s.lazy.load(); | |
} | |
} | |
}, | |
onTransitionEnd: function () { | |
if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) { | |
s.lazy.load(); | |
} | |
} | |
}; | |
/*========================= | |
Scrollbar | |
===========================*/ | |
s.scrollbar = { | |
set: function () { | |
if (!s.params.scrollbar) return; | |
var sb = s.scrollbar; | |
sb.track = $(s.params.scrollbar); | |
sb.drag = sb.track.find('.swiper-scrollbar-drag'); | |
if (sb.drag.length === 0) { | |
sb.drag = $('<div class="swiper-scrollbar-drag"></div>'); | |
sb.track.append(sb.drag); | |
} | |
sb.drag[0].style.width = ''; | |
sb.drag[0].style.height = ''; | |
sb.trackSize = isH() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight; | |
sb.divider = s.size / s.virtualWidth; | |
sb.moveDivider = sb.divider * (sb.trackSize / s.size); | |
sb.dragSize = sb.trackSize * sb.divider; | |
if (isH()) { | |
sb.drag[0].style.width = sb.dragSize + 'px'; | |
} | |
else { | |
sb.drag[0].style.height = sb.dragSize + 'px'; | |
} | |
if (sb.divider >= 1) { | |
sb.track[0].style.display = 'none'; | |
} | |
else { | |
sb.track[0].style.display = ''; | |
} | |
if (s.params.scrollbarHide) { | |
sb.track[0].style.opacity = 0; | |
} | |
}, | |
setTranslate: function () { | |
if (!s.params.scrollbar) return; | |
var diff; | |
var sb = s.scrollbar; | |
var translate = s.translate || 0; | |
var newPos; | |
var newSize = sb.dragSize; | |
newPos = (sb.trackSize - sb.dragSize) * s.progress; | |
if (s.rtl && isH()) { | |
newPos = -newPos; | |
if (newPos > 0) { | |
newSize = sb.dragSize - newPos; | |
newPos = 0; | |
} | |
else if (-newPos + sb.dragSize > sb.trackSize) { | |
newSize = sb.trackSize + newPos; | |
} | |
} | |
else { | |
if (newPos < 0) { | |
newSize = sb.dragSize + newPos; | |
newPos = 0; | |
} | |
else if (newPos + sb.dragSize > sb.trackSize) { | |
newSize = sb.trackSize - newPos; | |
} | |
} | |
if (isH()) { | |
sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)'); | |
sb.drag[0].style.width = newSize + 'px'; | |
} | |
else { | |
sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)'); | |
sb.drag[0].style.height = newSize + 'px'; | |
} | |
if (s.params.scrollbarHide) { | |
clearTimeout(sb.timeout); | |
sb.track[0].style.opacity = 1; | |
sb.timeout = setTimeout(function () { | |
sb.track[0].style.opacity = 0; | |
sb.track.transition(400); | |
}, 1000); | |
} | |
}, | |
setTransition: function (duration) { | |
if (!s.params.scrollbar) return; | |
s.scrollbar.drag.transition(duration); | |
} | |
}; | |
/*========================= | |
Controller | |
===========================*/ | |
s.controller = { | |
setTranslate: function (translate, byController) { | |
var controlled = s.params.control; | |
var multiplier, controlledTranslate; | |
if (s.isArray(controlled)) { | |
for (var i = 0; i < controlled.length; i++) { | |
if (controlled[i] !== byController && controlled[i] instanceof Swiper) { | |
translate = controlled[i].rtl && controlled[i].params.direction === 'horizontal' ? -s.translate : s.translate; | |
multiplier = (controlled[i].maxTranslate() - controlled[i].minTranslate()) / (s.maxTranslate() - s.minTranslate()); | |
controlledTranslate = (translate - s.minTranslate()) * multiplier + controlled[i].minTranslate(); | |
if (s.params.controlInverse) { | |
controlledTranslate = controlled[i].maxTranslate() - controlledTranslate; | |
} | |
controlled[i].updateProgress(controlledTranslate); | |
controlled[i].setWrapperTranslate(controlledTranslate, false, s); | |
controlled[i].updateActiveIndex(); | |
} | |
} | |
} | |
else if (controlled instanceof Swiper && byController !== controlled) { | |
translate = controlled.rtl && controlled.params.direction === 'horizontal' ? -s.translate : s.translate; | |
multiplier = (controlled.maxTranslate() - controlled.minTranslate()) / (s.maxTranslate() - s.minTranslate()); | |
controlledTranslate = (translate - s.minTranslate()) * multiplier + controlled.minTranslate(); | |
if (s.params.controlInverse) { | |
controlledTranslate = controlled.maxTranslate() - controlledTranslate; | |
} | |
controlled.updateProgress(controlledTranslate); | |
controlled.setWrapperTranslate(controlledTranslate, false, s); | |
controlled.updateActiveIndex(); | |
} | |
}, | |
setTransition: function (duration, byController) { | |
var controlled = s.params.control; | |
if (s.isArray(controlled)) { | |
for (var i = 0; i < controlled.length; i++) { | |
if (controlled[i] !== byController && controlled[i] instanceof Swiper) { | |
controlled[i].setWrapperTransition(duration, s); | |
} | |
} | |
} | |
else if (controlled instanceof Swiper && byController !== controlled) { | |
controlled.setWrapperTransition(duration, s); | |
} | |
} | |
}; | |
/*========================= | |
Hash Navigation | |
===========================*/ | |
s.hashnav = { | |
init: function () { | |
if (!s.params.hashnav) return; | |
s.hashnav.initialized = true; | |
var hash = document.location.hash.replace('#', ''); | |
if (!hash) return; | |
var speed = 0; | |
for (var i = 0, length = s.slides.length; i < length; i++) { | |
var slide = s.slides.eq(i); | |
var slideHash = slide.attr('data-hash'); | |
if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) { | |
var index = slide.index(); | |
s.slideTo(index, speed, s.params.runCallbacksOnInit, true); | |
} | |
} | |
}, | |
setHash: function () { | |
if (!s.hashnav.initialized || !s.params.hashnav) return; | |
document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || ''; | |
} | |
}; | |
/*========================= | |
Keyboard Control | |
===========================*/ | |
function handleKeyboard(e) { | |
if (e.originalEvent) e = e.originalEvent; //jquery fix | |
var kc = e.keyCode || e.charCode; | |
if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { | |
return; | |
} | |
if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) { | |
return; | |
} | |
if (kc === 37 || kc === 39 || kc === 38 || kc === 40) { | |
var inView = false; | |
//Check that swiper should be inside of visible area of window | |
if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) { | |
return; | |
} | |
var windowScroll = { | |
left: window.pageXOffset, | |
top: window.pageYOffset | |
}; | |
var windowWidth = window.innerWidth; | |
var windowHeight = window.innerHeight; | |
var swiperOffset = s.container.offset(); | |
var swiperCoord = [ | |
[swiperOffset.left, swiperOffset.top], | |
[swiperOffset.left + s.width, swiperOffset.top], | |
[swiperOffset.left, swiperOffset.top + s.height], | |
[swiperOffset.left + s.width, swiperOffset.top + s.height] | |
]; | |
for (var i = 0; i < swiperCoord.length; i++) { | |
var point = swiperCoord[i]; | |
if ( | |
point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth && | |
point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight | |
) { | |
inView = true; | |
} | |
} | |
if (!inView) return; | |
} | |
if (isH()) { | |
if (kc === 37 || kc === 39) { | |
if (e.preventDefault) e.preventDefault(); | |
else e.returnValue = false; | |
} | |
if (kc === 39) s.slideNext(); | |
if (kc === 37) s.slidePrev(); | |
} | |
else { | |
if (kc === 38 || kc === 40) { | |
if (e.preventDefault) e.preventDefault(); | |
else e.returnValue = false; | |
} | |
if (kc === 40) s.slideNext(); | |
if (kc === 38) s.slidePrev(); | |
} | |
} | |
s.disableKeyboardControl = function () { | |
$(document).off('keydown', handleKeyboard); | |
}; | |
s.enableKeyboardControl = function () { | |
$(document).on('keydown', handleKeyboard); | |
}; | |
/*========================= | |
Mousewheel Control | |
===========================*/ | |
s._wheelEvent = false; | |
s._lastWheelScrollTime = (new Date()).getTime(); | |
if (s.params.mousewheelControl) { | |
if (document.onmousewheel !== undefined) { | |
s._wheelEvent = 'mousewheel'; | |
} | |
if (!s._wheelEvent) { | |
try { | |
new WheelEvent('wheel'); | |
s._wheelEvent = 'wheel'; | |
} catch (e) {} | |
} | |
if (!s._wheelEvent) { | |
s._wheelEvent = 'DOMMouseScroll'; | |
} | |
} | |
function handleMousewheel(e) { | |
if (e.originalEvent) e = e.originalEvent; //jquery fix | |
var we = s._wheelEvent; | |
var delta = 0; | |
//Opera & IE | |
if (e.detail) delta = -e.detail; | |
//WebKits | |
else if (we === 'mousewheel') { | |
if (s.params.mousewheelForceToAxis) { | |
if (isH()) { | |
if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX; | |
else return; | |
} | |
else { | |
if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY; | |
else return; | |
} | |
} | |
else { | |
delta = e.wheelDelta; | |
} | |
} | |
//Old FireFox | |
else if (we === 'DOMMouseScroll') delta = -e.detail; | |
//New FireFox | |
else if (we === 'wheel') { | |
if (s.params.mousewheelForceToAxis) { | |
if (isH()) { | |
if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX; | |
else return; | |
} | |
else { | |
if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY; | |
else return; | |
} | |
} | |
else { | |
delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX : - e.deltaY; | |
} | |
} | |
if (!s.params.freeMode) { | |
if ((new Date()).getTime() - s._lastWheelScrollTime > 60) { | |
if (delta < 0) s.slideNext(); | |
else s.slidePrev(); | |
} | |
s._lastWheelScrollTime = (new Date()).getTime(); | |
} | |
else { | |
//Freemode or scrollContainer: | |
var position = s.getWrapperTranslate() + delta; | |
if (position > 0) position = 0; | |
if (position < s.maxTranslate()) position = s.maxTranslate(); | |
s.setWrapperTransition(0); | |
s.setWrapperTranslate(position); | |
s.updateProgress(); | |
s.updateActiveIndex(); | |
// Return page scroll on edge positions | |
if (position === 0 || position === s.maxTranslate()) return; | |
} | |
if (s.params.autoplay) s.stopAutoplay(); | |
if (e.preventDefault) e.preventDefault(); | |
else e.returnValue = false; | |
return false; | |
} | |
s.disableMousewheelControl = function () { | |
if (!s._wheelEvent) return false; | |
s.container.off(s._wheelEvent, handleMousewheel); | |
return true; | |
}; | |
s.enableMousewheelControl = function () { | |
if (!s._wheelEvent) return false; | |
s.container.on(s._wheelEvent, handleMousewheel); | |
return true; | |
}; | |
/*========================= | |
Parallax | |
===========================*/ | |
function setParallaxTransform(el, progress) { | |
el = $(el); | |
var p, pX, pY, tX, tY; | |
p = el.attr('data-swiper-parallax'); | |
pX = el.attr('data-swiper-parallax-x'); | |
pY = el.attr('data-swiper-parallax-y'); | |
if (!pX && !pY && p) { | |
if (isH()) { | |
pX = p; | |
pY = '0'; | |
} | |
else { | |
pY = p; | |
pX = '0'; | |
} | |
} | |
else { | |
if (pX) pX = pX; | |
else pX = '0'; | |
if (pY) pY = pY; | |
else pY = '0'; | |
} | |
if ((pX).indexOf('%') >= 0) { | |
pX = parseInt(pX, 10) * progress + '%'; | |
} | |
else { | |
pX = pX * progress + 'px' ; | |
} | |
if ((pY).indexOf('%') >= 0) { | |
pY = parseInt(pY, 10) * progress + '%'; | |
} | |
else { | |
pY = pY * progress + 'px' ; | |
} | |
tX = pX; | |
tY = pY; | |
el.transform('translate3d(' + tX + ', ' + tY + ',0px)'); | |
} | |
s.parallax = { | |
setTranslate: function () { | |
s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){ | |
setParallaxTransform(this, s.progress); | |
}); | |
s.slides.each(function () { | |
var slide = $(this); | |
slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () { | |
var progress = Math.min(Math.max(slide[0].progress, -1), 1); | |
setParallaxTransform(this, progress); | |
}); | |
}); | |
}, | |
setTransition: function (duration) { | |
if (typeof duration === 'undefined') duration = s.params.speed; | |
s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){ | |
var el = $(this); | |
var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration; | |
if (duration === 0) parallaxDuration = 0; | |
el.transition(parallaxDuration); | |
}); | |
} | |
}; | |
/*========================= | |
Init/Destroy | |
===========================*/ | |
s.init = function () { | |
if (s.params.loop) s.createLoop(); | |
s.updateContainerSize(); | |
s.updateSlidesSize(); | |
s.updatePagination(); | |
if (s.params.scrollbar && s.scrollbar) { | |
s.scrollbar.set(); | |
} | |
if (s.params.effect !== 'slide' && s.effects[s.params.effect]) { | |
if (!s.params.loop) s.updateProgress(); | |
s.effects[s.params.effect].setTranslate(); | |
} | |
if (s.params.loop) { | |
s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit); | |
} | |
else { | |
s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit); | |
if (s.params.initialSlide === 0) { | |
if (s.parallax && s.params.parallax) s.parallax.setTranslate(); | |
if (s.lazy && s.params.lazyLoading) s.lazy.load(); | |
} | |
} | |
s.attachEvents(); | |
if (s.params.observer && s.support.observer) { | |
s.initObservers(); | |
} | |
if (s.params.preloadImages && !s.params.lazyLoading) { | |
s.preloadImages(); | |
} | |
if (s.params.autoplay) { | |
s.startAutoplay(); | |
} | |
if (s.params.keyboardControl) { | |
if (s.enableKeyboardControl) s.enableKeyboardControl(); | |
} | |
if (s.params.mousewheelControl) { | |
if (s.enableMousewheelControl) s.enableMousewheelControl(); | |
} | |
if (s.params.hashnav) { | |
if (s.hashnav) s.hashnav.init(); | |
} | |
if (s.params.onInit) s.params.onInit(s); | |
}; | |
// Destroy | |
s.destroy = function (deleteInstance) { | |
s.detachEvents(); | |
s.disconnectObservers(); | |
if (s.params.keyboardControl) { | |
if (s.disableKeyboardControl) s.disableKeyboardControl(); | |
} | |
if (s.params.mousewheelControl) { | |
if (s.disableMousewheelControl) s.disableMousewheelControl(); | |
} | |
if (s.params.onDestroy) s.params.onDestroy(); | |
if (deleteInstance !== false) s = null; | |
}; | |
s.init(); | |
// Return swiper instance | |
return s; | |
}; | |
/*================================================== | |
Prototype | |
====================================================*/ | |
Swiper.prototype = { | |
isSafari: (function () { | |
var ua = navigator.userAgent.toLowerCase(); | |
return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0); | |
})(), | |
isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent), | |
isArray: function (arr) { | |
return Object.prototype.toString.apply(arr) === '[object Array]'; | |
}, | |
/*================================================== | |
Browser | |
====================================================*/ | |
browser: { | |
ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled | |
}, | |
/*================================================== | |
Devices | |
====================================================*/ | |
device: (function () { | |
var ua = navigator.userAgent; | |
var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); | |
var ipad = ua.match(/(iPad).*OS\s([\d_]+)/); | |
var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/); | |
var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/); | |
return { | |
ios: ipad || iphone || ipad, | |
android: android | |
}; | |
})(), | |
/*================================================== | |
Feature Detection | |
====================================================*/ | |
support: { | |
touch : (window.Modernizr && Modernizr.touch === true) || (function () { | |
return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch); | |
})(), | |
transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () { | |
var div = document.createElement('div').style; | |
return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div); | |
})(), | |
flexbox: (function () { | |
var div = document.createElement('div').style; | |
var styles = ('WebkitBox msFlexbox MsFlexbox WebkitFlex MozBox flex').split(' '); | |
for (var i = 0; i < styles.length; i++) { | |
if (styles[i] in div) return true; | |
} | |
})(), | |
observer: (function () { | |
return ('MutationObserver' in window || 'WebkitMutationObserver' in window); | |
})() | |
} | |
}; | |
/*=========================== | |
Dom7 Library | |
===========================*/ | |
var Dom7 = (function () { | |
var Dom7 = function (arr) { | |
var _this = this, i = 0; | |
// Create array-like object | |
for (i = 0; i < arr.length; i++) { | |
_this[i] = arr[i]; | |
} | |
_this.length = arr.length; | |
// Return collection with methods | |
return this; | |
}; | |
var $ = function (selector, context) { | |
var arr = [], i = 0; | |
if (selector && !context) { | |
if (selector instanceof Dom7) { | |
return selector; | |
} | |
} | |
if (selector) { | |
// String | |
if (typeof selector === 'string') { | |
var els, tempParent, html = selector.trim(); | |
if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) { | |
var toCreate = 'div'; | |
if (html.indexOf('<li') === 0) toCreate = 'ul'; | |
if (html.indexOf('<tr') === 0) toCreate = 'tbody'; | |
if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr'; | |
if (html.indexOf('<tbody') === 0) toCreate = 'table'; | |
if (html.indexOf('<option') === 0) toCreate = 'select'; | |
tempParent = document.createElement(toCreate); | |
tempParent.innerHTML = selector; | |
for (i = 0; i < tempParent.childNodes.length; i++) { | |
arr.push(tempParent.childNodes[i]); | |
} | |
} | |
else { | |
if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) { | |
// Pure ID selector | |
els = [document.getElementById(selector.split('#')[1])]; | |
} | |
else { | |
// Other selectors | |
els = (context || document).querySelectorAll(selector); | |
} | |
for (i = 0; i < els.length; i++) { | |
if (els[i]) arr.push(els[i]); | |
} | |
} | |
} | |
// Node/element | |
else if (selector.nodeType || selector === window || selector === document) { | |
arr.push(selector); | |
} | |
//Array of elements or instance of Dom | |
else if (selector.length > 0 && selector[0].nodeType) { | |
for (i = 0; i < selector.length; i++) { | |
arr.push(selector[i]); | |
} | |
} | |
} | |
return new Dom7(arr); | |
}; | |
Dom7.prototype = { | |
// Classes and attriutes | |
addClass: function (className) { | |
if (typeof className === 'undefined') { | |
return this; | |
} | |
var classes = className.split(' '); | |
for (var i = 0; i < classes.length; i++) { | |
for (var j = 0; j < this.length; j++) { | |
this[j].classList.add(classes[i]); | |
} | |
} | |
return this; | |
}, | |
removeClass: function (className) { | |
var classes = className.split(' '); | |
for (var i = 0; i < classes.length; i++) { | |
for (var j = 0; j < this.length; j++) { | |
this[j].classList.remove(classes[i]); | |
} | |
} | |
return this; | |
}, | |
hasClass: function (className) { | |
if (!this[0]) return false; | |
else return this[0].classList.contains(className); | |
}, | |
toggleClass: function (className) { | |
var classes = className.split(' '); | |
for (var i = 0; i < classes.length; i++) { | |
for (var j = 0; j < this.length; j++) { | |
this[j].classList.toggle(classes[i]); | |
} | |
} | |
return this; | |
}, | |
attr: function (attrs, value) { | |
if (arguments.length === 1 && typeof attrs === 'string') { | |
// Get attr | |
if (this[0]) return this[0].getAttribute(attrs); | |
else return undefined; | |
} | |
else { | |
// Set attrs | |
for (var i = 0; i < this.length; i++) { | |
if (arguments.length === 2) { | |
// String | |
this[i].setAttribute(attrs, value); | |
} | |
else { | |
// Object | |
for (var attrName in attrs) { | |
this[i][attrName] = attrs[attrName]; | |
this[i].setAttribute(attrName, attrs[attrName]); | |
} | |
} | |
} | |
return this; | |
} | |
}, | |
removeAttr: function (attr) { | |
for (var i = 0; i < this.length; i++) { | |
this[i].removeAttribute(attr); | |
} | |
}, | |
data: function (key, value) { | |
if (typeof value === 'undefined') { | |
// Get value | |
if (this[0]) { | |
var dataKey = this[0].getAttribute('data-' + key); | |
if (dataKey) return dataKey; | |
else if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) return this[0].dom7ElementDataStorage[key]; | |
else return undefined; | |
} | |
else return undefined; | |
} | |
else { | |
// Set value | |
for (var i = 0; i < this.length; i++) { | |
var el = this[i]; | |
if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {}; | |
el.dom7ElementDataStorage[key] = value; | |
} | |
return this; | |
} | |
}, | |
// Transforms | |
transform : function (transform) { | |
for (var i = 0; i < this.length; i++) { | |
var elStyle = this[i].style; | |
elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform; | |
} | |
return this; | |
}, | |
transition: function (duration) { | |
if (typeof duration !== 'string') { | |
duration = duration + 'ms'; | |
} | |
for (var i = 0; i < this.length; i++) { | |
var elStyle = this[i].style; | |
elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration; | |
} | |
return this; | |
}, | |
//Events | |
on: function (eventName, targetSelector, listener, capture) { | |
function handleLiveEvent(e) { | |
var target = e.target; | |
if ($(target).is(targetSelector)) listener.call(target, e); | |
else { | |
var parents = $(target).parents(); | |
for (var k = 0; k < parents.length; k++) { | |
if ($(parents[k]).is(targetSelector)) listener.call(parents[k], e); | |
} | |
} | |
} | |
var events = eventName.split(' '); | |
var i, j; | |
for (i = 0; i < this.length; i++) { | |
if (typeof targetSelector === 'function' || targetSelector === false) { | |
// Usual events | |
if (typeof targetSelector === 'function') { | |
listener = arguments[1]; | |
capture = arguments[2] || false; | |
} | |
for (j = 0; j < events.length; j++) { | |
this[i].addEventListener(events[j], listener, capture); | |
} | |
} | |
else { | |
//Live events | |
for (j = 0; j < events.length; j++) { | |
if (!this[i].dom7LiveListeners) this[i].dom7LiveListeners = []; | |
this[i].dom7LiveListeners.push({listener: listener, liveListener: handleLiveEvent}); | |
this[i].addEventListener(events[j], handleLiveEvent, capture); | |
} | |
} | |
} | |
return this; | |
}, | |
off: function (eventName, targetSelector, listener, capture) { | |
var events = eventName.split(' '); | |
for (var i = 0; i < events.length; i++) { | |
for (var j = 0; j < this.length; j++) { | |
if (typeof targetSelector === 'function' || targetSelector === false) { | |
// Usual events | |
if (typeof targetSelector === 'function') { | |
listener = arguments[1]; | |
capture = arguments[2] || false; | |
} | |
this[j].removeEventListener(events[i], listener, capture); | |
} | |
else { | |
// Live event | |
if (this[j].dom7LiveListeners) { | |
for (var k = 0; k < this[j].dom7LiveListeners.length; k++) { | |
if (this[j].dom7LiveListeners[k].listener === listener) { | |
this[j].removeEventListener(events[i], this[j].dom7LiveListeners[k].liveListener, capture); | |
} | |
} | |
} | |
} | |
} | |
} | |
return this; | |
}, | |
once: function (eventName, targetSelector, listener, capture) { | |
var dom = this; | |
if (typeof targetSelector === 'function') { | |
targetSelector = false; | |
listener = arguments[1]; | |
capture = arguments[2]; | |
} | |
function proxy(e) { | |
listener(e); | |
dom.off(eventName, targetSelector, proxy, capture); | |
} | |
dom.on(eventName, targetSelector, proxy, capture); | |
}, | |
trigger: function (eventName, eventData) { | |
for (var i = 0; i < this.length; i++) { | |
var evt; | |
try { | |
evt = new CustomEvent(eventName, {detail: eventData, bubbles: true, cancelable: true}); | |
} | |
catch (e) { | |
evt = document.createEvent('Event'); | |
evt.initEvent(eventName, true, true); | |
evt.detail = eventData; | |
} | |
this[i].dispatchEvent(evt); | |
} | |
return this; | |
}, | |
transitionEnd: function (callback) { | |
var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'], | |
i, j, dom = this; | |
function fireCallBack(e) { | |
/*jshint validthis:true */ | |
if (e.target !== this) return; | |
callback.call(this, e); | |
for (i = 0; i < events.length; i++) { | |
dom.off(events[i], fireCallBack); | |
} | |
} | |
if (callback) { | |
for (i = 0; i < events.length; i++) { | |
dom.on(events[i], fireCallBack); | |
} | |
} | |
return this; | |
}, | |
// Sizing/Styles | |
width: function () { | |
if (this[0] === window) { | |
return window.innerWidth; | |
} | |
else { | |
if (this.length > 0) { | |
return parseFloat(this.css('width')); | |
} | |
else { | |
return null; | |
} | |
} | |
}, | |
outerWidth: function (includeMargins) { | |
if (this.length > 0) { | |
if (includeMargins) | |
return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left')); | |
else | |
return this[0].offsetWidth; | |
} | |
else return null; | |
}, | |
height: function () { | |
if (this[0] === window) { | |
return window.innerHeight; | |
} | |
else { | |
if (this.length > 0) { | |
return parseFloat(this.css('height')); | |
} | |
else { | |
return null; | |
} | |
} | |
}, | |
outerHeight: function (includeMargins) { | |
if (this.length > 0) { | |
if (includeMargins) | |
return this[0].offsetHeight + parseFloat(this.css('margin-top')) + parseFloat(this.css('margin-bottom')); | |
else | |
return this[0].offsetHeight; | |
} | |
else return null; | |
}, | |
offset: function () { | |
if (this.length > 0) { | |
var el = this[0]; | |
var box = el.getBoundingClientRect(); | |
var body = document.body; | |
var clientTop = el.clientTop || body.clientTop || 0; | |
var clientLeft = el.clientLeft || body.clientLeft || 0; | |
var scrollTop = window.pageYOffset || el.scrollTop; | |
var scrollLeft = window.pageXOffset || el.scrollLeft; | |
return { | |
top: box.top + scrollTop - clientTop, | |
left: box.left + scrollLeft - clientLeft | |
}; | |
} | |
else { | |
return null; | |
} | |
}, | |
css: function (props, value) { | |
var i; | |
if (arguments.length === 1) { | |
if (typeof props === 'string') { | |
if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props); | |
} | |
else { | |
for (i = 0; i < this.length; i++) { | |
for (var prop in props) { | |
this[i].style[prop] = props[prop]; | |
} | |
} | |
return this; | |
} | |
} | |
if (arguments.length === 2 && typeof props === 'string') { | |
for (i = 0; i < this.length; i++) { | |
this[i].style[props] = value; | |
} | |
return this; | |
} | |
return this; | |
}, | |
//Dom manipulation | |
each: function (callback) { | |
for (var i = 0; i < this.length; i++) { | |
callback.call(this[i], i, this[i]); | |
} | |
return this; | |
}, | |
html: function (html) { | |
if (typeof html === 'undefined') { | |
return this[0] ? this[0].innerHTML : undefined; | |
} | |
else { | |
for (var i = 0; i < this.length; i++) { | |
this[i].innerHTML = html; | |
} | |
return this; | |
} | |
}, | |
is: function (selector) { | |
if (!this[0]) return false; | |
var compareWith, i; | |
if (typeof selector === 'string') { | |
var el = this[0]; | |
if (el === document) return selector === document; | |
if (el === window) return selector === window; | |
if (el.matches) return el.matches(selector); | |
else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector); | |
else if (el.mozMatchesSelector) return el.mozMatchesSelector(selector); | |
else if (el.msMatchesSelector) return el.msMatchesSelector(selector); | |
else { | |
compareWith = $(selector); | |
for (i = 0; i < compareWith.length; i++) { | |
if (compareWith[i] === this[0]) return true; | |
} | |
return false; | |
} | |
} | |
else if (selector === document) return this[0] === document; | |
else if (selector === window) return this[0] === window; | |
else { | |
if (selector.nodeType || selector instanceof Dom7) { | |
compareWith = selector.nodeType ? [selector] : selector; | |
for (i = 0; i < compareWith.length; i++) { | |
if (compareWith[i] === this[0]) return true; | |
} | |
return false; | |
} | |
return false; | |
} | |
}, | |
index: function () { | |
if (this[0]) { | |
var child = this[0]; | |
var i = 0; | |
while ((child = child.previousSibling) !== null) { | |
if (child.nodeType === 1) i++; | |
} | |
return i; | |
} | |
else return undefined; | |
}, | |
eq: function (index) { | |
if (typeof index === 'undefined') return this; | |
var length = this.length; | |
var returnIndex; | |
if (index > length - 1) { | |
return new Dom7([]); | |
} | |
if (index < 0) { | |
returnIndex = length + index; | |
if (returnIndex < 0) return new Dom7([]); | |
else return new Dom7([this[returnIndex]]); | |
} | |
return new Dom7([this[index]]); | |
}, | |
append: function (newChild) { | |
var i, j; | |
for (i = 0; i < this.length; i++) { | |
if (typeof newChild === 'string') { | |
var tempDiv = document.createElement('div'); | |
tempDiv.innerHTML = newChild; | |
while (tempDiv.firstChild) { | |
this[i].appendChild(tempDiv.firstChild); | |
} | |
} | |
else if (newChild instanceof Dom7) { | |
for (j = 0; j < newChild.length; j++) { | |
this[i].appendChild(newChild[j]); | |
} | |
} | |
else { | |
this[i].appendChild(newChild); | |
} | |
} | |
return this; | |
}, | |
prepend: function (newChild) { | |
var i, j; | |
for (i = 0; i < this.length; i++) { | |
if (typeof newChild === 'string') { | |
var tempDiv = document.createElement('div'); | |
tempDiv.innerHTML = newChild; | |
for (j = tempDiv.childNodes.length - 1; j >= 0; j--) { | |
this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]); | |
} | |
// this[i].insertAdjacentHTML('afterbegin', newChild); | |
} | |
else if (newChild instanceof Dom7) { | |
for (j = 0; j < newChild.length; j++) { | |
this[i].insertBefore(newChild[j], this[i].childNodes[0]); | |
} | |
} | |
else { | |
this[i].insertBefore(newChild, this[i].childNodes[0]); | |
} | |
} | |
return this; | |
}, | |
insertBefore: function (selector) { | |
var before = $(selector); | |
for (var i = 0; i < this.length; i++) { | |
if (before.length === 1) { | |
before[0].parentNode.insertBefore(this[i], before[0]); | |
} | |
else if (before.length > 1) { | |
for (var j = 0; j < before.length; j++) { | |
before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]); | |
} | |
} | |
} | |
}, | |
insertAfter: function (selector) { | |
var after = $(selector); | |
for (var i = 0; i < this.length; i++) { | |
if (after.length === 1) { | |
after[0].parentNode.insertBefore(this[i], after[0].nextSibling); | |
} | |
else if (after.length > 1) { | |
for (var j = 0; j < after.length; j++) { | |
after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling); | |
} | |
} | |
} | |
}, | |
next: function (selector) { | |
if (this.length > 0) { | |
if (selector) { | |
if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) return new Dom7([this[0].nextElementSibling]); | |
else return new Dom7([]); | |
} | |
else { | |
if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]); | |
else return new Dom7([]); | |
} | |
} | |
else return new Dom7([]); | |
}, | |
nextAll: function (selector) { | |
var nextEls = []; | |
var el = this[0]; | |
if (!el) return new Dom7([]); | |
while (el.nextElementSibling) { | |
var next = el.nextElementSibling; | |
if (selector) { | |
if($(next).is(selector)) nextEls.push(next); | |
} | |
else nextEls.push(next); | |
el = next; | |
} | |
return new Dom7(nextEls); | |
}, | |
prev: function (selector) { | |
if (this.length > 0) { | |
if (selector) { | |
if (this[0].previousElementSibling && $(this[0].previousElementSibling).is(selector)) return new Dom7([this[0].previousElementSibling]); | |
else return new Dom7([]); | |
} | |
else { | |
if (this[0].previousElementSibling) return new Dom7([this[0].previousElementSibling]); | |
else return new Dom7([]); | |
} | |
} | |
else return new Dom7([]); | |
}, | |
prevAll: function (selector) { | |
var prevEls = []; | |
var el = this[0]; | |
if (!el) return new Dom7([]); | |
while (el.previousElementSibling) { | |
var prev = el.previousElementSibling; | |
if (selector) { | |
if($(prev).is(selector)) prevEls.push(prev); | |
} | |
else prevEls.push(prev); | |
el = prev; | |
} | |
return new Dom7(prevEls); | |
}, | |
parent: function (selector) { | |
var parents = []; | |
for (var i = 0; i < this.length; i++) { | |
if (selector) { | |
if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode); | |
} | |
else { | |
parents.push(this[i].parentNode); | |
} | |
} | |
return $($.unique(parents)); | |
}, | |
parents: function (selector) { | |
var parents = []; | |
for (var i = 0; i < this.length; i++) { | |
var parent = this[i].parentNode; | |
while (parent) { | |
if (selector) { | |
if ($(parent).is(selector)) parents.push(parent); | |
} | |
else { | |
parents.push(parent); | |
} | |
parent = parent.parentNode; | |
} | |
} | |
return $($.unique(parents)); | |
}, | |
find : function (selector) { | |
var foundElements = []; | |
for (var i = 0; i < this.length; i++) { | |
var found = this[i].querySelectorAll(selector); | |
for (var j = 0; j < found.length; j++) { | |
foundElements.push(found[j]); | |
} | |
} | |
return new Dom7(foundElements); | |
}, | |
children: function (selector) { | |
var children = []; | |
for (var i = 0; i < this.length; i++) { | |
var childNodes = this[i].childNodes; | |
for (var j = 0; j < childNodes.length; j++) { | |
if (!selector) { | |
if (childNodes[j].nodeType === 1) children.push(childNodes[j]); | |
} | |
else { | |
if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) children.push(childNodes[j]); | |
} | |
} | |
} | |
return new Dom7($.unique(children)); | |
}, | |
remove: function () { | |
for (var i = 0; i < this.length; i++) { | |
if (this[i].parentNode) this[i].parentNode.removeChild(this[i]); | |
} | |
return this; | |
}, | |
add: function () { | |
var dom = this; | |
var i, j; | |
for (i = 0; i < arguments.length; i++) { | |
var toAdd = $(arguments[i]); | |
for (j = 0; j < toAdd.length; j++) { | |
dom[dom.length] = toAdd[j]; | |
dom.length++; | |
} | |
} | |
return dom; | |
} | |
}; | |
$.fn = Dom7.prototype; | |
$.unique = function (arr) { | |
var unique = []; | |
for (var i = 0; i < arr.length; i++) { | |
if (unique.indexOf(arr[i]) === -1) unique.push(arr[i]); | |
} | |
return unique; | |
}; | |
return $; | |
})(); | |
/*=========================== | |
Add .swiper plugin from Dom libraries | |
===========================*/ | |
var swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7']; | |
function addLibraryPlugin(lib) { | |
lib.fn.swiper = function (params) { | |
var firstInstance; | |
lib(this).each(function () { | |
var s = new Swiper(this, params); | |
if (!firstInstance) firstInstance = s; | |
}); | |
return firstInstance; | |
}; | |
} | |
for (var i = 0; i < swiperDomPlugins.length; i++) { | |
if (window[swiperDomPlugins[i]]) { | |
addLibraryPlugin(window[swiperDomPlugins[i]]); | |
} | |
} | |
// Required DOM Plugins | |
var domLib; | |
if (typeof Dom7 === 'undefined') { | |
domLib = window.Dom7 || window.Zepto || window.jQuery; | |
} | |
else { | |
domLib = Dom7; | |
} | |
if (domLib) { | |
if (!('transitionEnd' in domLib.fn)) { | |
domLib.fn.transitionEnd = function (callback) { | |
var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'], | |
i, j, dom = this; | |
function fireCallBack(e) { | |
/*jshint validthis:true */ | |
if (e.target !== this) return; | |
callback.call(this, e); | |
for (i = 0; i < events.length; i++) { | |
dom.off(events[i], fireCallBack); | |
} | |
} | |
if (callback) { | |
for (i = 0; i < events.length; i++) { | |
dom.on(events[i], fireCallBack); | |
} | |
} | |
return this; | |
}; | |
} | |
if (!('transform' in domLib.fn)) { | |
domLib.fn.transform = function (transform) { | |
for (var i = 0; i < this.length; i++) { | |
var elStyle = this[i].style; | |
elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform; | |
} | |
return this; | |
}; | |
} | |
if (!('transition' in domLib.fn)) { | |
domLib.fn.transition = function (duration) { | |
if (typeof duration !== 'string') { | |
duration = duration + 'ms'; | |
} | |
for (var i = 0; i < this.length; i++) { | |
var elStyle = this[i].style; | |
elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration; | |
} | |
return this; | |
}; | |
} | |
} | |
})(); | |
/*=========================== | |
Swiper AMD Export | |
===========================*/ | |
if (typeof(module) !== 'undefined') | |
{ | |
module.exports = Swiper; | |
} | |
else if (typeof define === 'function' && define.amd) { | |
define('swiper-script',[], function () { | |
return Swiper; | |
}); | |
}; | |
// resize graphics based on class names | |
define('node_modules/nytg-resizer/script',[ | |
'jquery/nyt', | |
'underscore/nyt', | |
'foundation/views/base-view', | |
'foundation/views/page-manager' | |
], function($, _, BaseView, PageManager) { | |
var GraphicsResizer = BaseView.extend({ | |
sizes: { | |
180: ".g-show-xsmall", | |
300: ".g-show-small", | |
460: ".g-show-smallplus", | |
600: ".g-show-submedium", | |
720: ".g-show-medium", | |
945: ".g-show-large", | |
1050: ".g-show-xlarge" | |
}, | |
initialize: function(options) { | |
// only want one resizer on the page | |
if ($("html").hasClass("g-resizer-init")) return false; | |
this.selector = _.values(this.sizes).join(", "); | |
this.widths = _.map(_.keys(this.sizes), Number); | |
_.bindAll(this, "render", "selectElements"); | |
this.selectElements(); | |
this.pageManager.on("nyt:page-resize", this.render); | |
this.render(); | |
$("html").addClass("g-resizer-init"); | |
$(document).ready(this.selectElements); | |
}, | |
render: function() { | |
var self = this; | |
self.elements.each(function() { | |
var element = $(this); | |
var parentWidth = element.parent().width(); | |
var width = _.max(_.filter(self.widths, function(width) { return width <= parentWidth; })); | |
var css = self.sizes[width] || ""; | |
var show = element.hasClass(css.replace(".", "")); | |
element.toggle(show); | |
}); | |
}, | |
selectElements: function() { | |
this.elements = $(this.selector); | |
this.elements.hide(); | |
this.render(); | |
} | |
}); | |
return new GraphicsResizer(); | |
}); | |
define('jquery',["jquery/nyt"], function ($) { return $ }); | |
/** | |
* @preserve LaziestLoader - v0.5.1 - 2014-06-19 | |
* A responsive lazy loader for jQuery. | |
* http://sjwilliams.github.io/laziestloader/ | |
* Copyright (c) 2014 Josh Williams; Licensed MIT | |
*/ | |
(function(factory) { | |
if (typeof define === 'function' && define.amd) { | |
define('node_modules/laziestloader/jquery.laziestloader',['jquery'], factory); | |
} else { | |
factory(jQuery); | |
} | |
}(function($) { | |
var laziestLoader = function(options, callback) { | |
var $w = $(window), | |
$elements = this, | |
$loaded = $(), // elements with the correct source set | |
retina = window.devicePixelRatio > 1, | |
didScroll = false; | |
options = $.extend(true, { | |
threshold: 0, | |
sizePattern: /{{SIZE}}/ig, | |
getSource: getSource, | |
scrollThrottle: 250, // time in ms to throttle scroll. Increase for better performance. | |
sizeOffsetPercent: 0, // prefer smaller images | |
setSourceMode: true // plugin sets source attribute of the element. Set to false if you would like to, instead, use the callback to completely manage the element on trigger. | |
}, options); | |
/** | |
* Generate source path of image to load. Take into account | |
* type of data supplied and whether or not a retina | |
* image is available. | |
* | |
* Basic option: data attributes specifing a single image to load, | |
* regardless of viewport. | |
* Eg: | |
* | |
* <img data-src="yourimage.jpg"> | |
* <img data-src="yourimage.jpg" data-src-retina="yourretinaimage.jpg"> | |
* | |
* Range of sizes: specify a string path with a {{size}} that | |
* will be replaced by an integer from a list of available sizes. | |
* Eg: | |
* | |
* <img data-pattern="path/toyourimage-{{size}}.jpg" data-size="[320, 640, 970]"> | |
* <img data-pattern="path/toyourimage-{{size}}.jpg" data-pattern-retina="path/toyourimage-{{size}}@2x.jpg" data-size="[320, 640, 970]"> | |
* <img data-pattern="path/toyourimage/{{size}}/slug.jpg" data-pattern-retina="path/toyourimage/{{size}}/[email protected]" data-size="[320, 640, 970]"> | |
* | |
* Range of sizes, with slugs: specify a string path with a {{size}} that | |
* will be replaced by a slug representing an image size. | |
* Eg: | |
* | |
* <img data-pattern="path/toyourimage-{{size}}.jpg" data-size="[{width: 320, slug: 'small'},{width:900, slug: 'large'}]"> | |
* | |
* @param {jQuery object} $el | |
* @return {String} | |
*/ | |
function getSource($el) { | |
var source, slug; | |
var data = $el.data(); | |
if (data.pattern && data.widths && $.isArray(data.widths)) { | |
source = retina ? data.patternRetina : data.pattern; | |
source = source || data.pattern; | |
// width or slug version? | |
if (typeof data.widths[0] === 'object') { | |
slug = (function() { | |
var widths = $.map(data.widths, function(val) { | |
return val.size; | |
}); | |
var bestFitWidth = bestFit($el.width(), widths); | |
// match best width back to its corresponding slug | |
for (var i = data.widths.length - 1; i >= 0; i--) { | |
if (data.widths[i].size === bestFitWidth) { | |
return data.widths[i].slug; | |
} | |
} | |
})(); | |
source = source.replace(options.sizePattern, slug); | |
} else { | |
source = source.replace(options.sizePattern, bestFit($el.width(), data.widths)); | |
} | |
} else { | |
source = retina ? data.srcRetina : data.src; | |
source = source || data.src; | |
} | |
return source; | |
} | |
/** | |
* Reflect loaded state in class names | |
* and fire event. | |
* | |
* @param {jQuery Object} $el | |
*/ | |
function onLoad($el) { | |
$el.addClass('ll-loaded').removeClass('ll-notloaded'); | |
$el.trigger('loaded'); | |
if (typeof callback === 'function') { | |
callback.call($el); | |
} | |
} | |
/** | |
* Attach event handler that sets correct | |
* media source for the elements' width, or | |
* allows callback to manipulate element | |
* exclusively. | |
*/ | |
function bindLoader() { | |
$elements.one('laziestloader', function() { | |
var $el = $(this); | |
var source; | |
// set height? | |
if ($el.data().ratio) { | |
setHeight.call(this); | |
} | |
// set content. default: set element source | |
if (options.setSourceMode) { | |
source = options.getSource($el); | |
if (source && this.getAttribute('src') !== source) { | |
this.setAttribute('src', source); | |
} | |
} | |
// Determine when to fire `loaded` event. Wait until | |
// media is truly loaded if possible, otherwise immediately | |
if (options.setSourceMode && (this.nodeName === 'IMG' || this.nodeName === 'VIDEO' || this.nodeName === 'AUDIO') ) { | |
if (this.nodeName === 'IMG') { | |
this.onload = function() { | |
onLoad($el); | |
} | |
} else { | |
this.onloadstart = function() { | |
onLoad($el); | |
} | |
} | |
} else { | |
onLoad($el); | |
} | |
}); | |
} | |
/** | |
* Remove even handler from elements | |
*/ | |
function unbindLoader() { | |
$elements.off('laziestloader'); | |
} | |
/** | |
* Find the best sized image, opting for larger over smaller | |
* | |
* @param {Number} targetWidth element width | |
* @param {Array} widths array of numbers | |
* @return {Number} | |
*/ | |
var bestFit = laziestLoader.bestFit = function(targetWidth, widths) { | |
var selectedWidth = widths[widths.length - 1], | |
i = widths.length, | |
offset = targetWidth * (options.sizeOffsetPercent / 100); | |
// sort smallest to largest | |
widths.sort(function(a, b) { | |
return a - b; | |
}); | |
while (i--) { | |
if ((targetWidth - offset) <= widths[i]) { | |
selectedWidth = widths[i]; | |
} | |
} | |
return selectedWidth; | |
}; | |
/** | |
* Cycle through elements that haven't had their | |
* source set and, if they're in the viewport within | |
* the threshold, load their media | |
*/ | |
function laziestloader() { | |
var $inview = $elements.not($loaded).filter(function() { | |
var $el = $(this), | |
threshold = options.threshold; | |
if ($el.is(':hidden')) return; | |
var wt = $w.scrollTop(), | |
wb = wt + $w.height(), | |
et = $el.offset().top, | |
eb = et + $el.height(); | |
return eb >= wt - threshold && et <= wb + threshold; | |
}); | |
$inview.trigger('laziestloader'); | |
$loaded.add($inview); | |
} | |
function setHeight() { | |
var $el = $(this), | |
data = $el.data(); | |
data.ratio = data.ratio || data.heightMultiplier; // backwards compatible for old data-height-multiplier code. | |
if (data.ratio) { | |
$el.css({ | |
height: Math.round($el.width() * data.ratio) | |
}); | |
} | |
} | |
// add inital state classes, and check if | |
// element dimensions need to be set. | |
$elements.addClass('ll-init ll-notloaded').each(setHeight); | |
bindLoader(); | |
// throttled scroll events | |
$w.scroll(function() { | |
didScroll = true; | |
}); | |
setInterval(function() { | |
if (didScroll) { | |
didScroll = false; | |
laziestloader(); | |
} | |
}, options.scrollThrottle); | |
// reset state on resize | |
$w.resize(function() { | |
$loaded = $(); | |
unbindLoader(); | |
bindLoader(); | |
laziestloader(); | |
}); | |
laziestloader(); | |
return this; | |
}; | |
$.fn.laziestloader = laziestLoader; | |
})); | |
/*! LaziestLoader - v0.0.2 - 2014-02-25 | |
* A responsive-aware jQuery plugin to smartly lazy load images and other elements. | |
* https://github.com/sjwilliams/laziestloader | |
* Thanks to LuÃs Almeida for 'unveil,' on which this project is based. | |
* Copyright (c) 2014 Josh Williams; Licensed MIT | |
*/ | |
define('resizerScript',[ | |
"jquery/nyt", | |
"node_modules/nytg-resizer/script", | |
"node_modules/laziestloader/jquery.laziestloader" | |
], function($, GraphicsResizer) { | |
$(".g-aiImg").laziestloader({ threshold: 1000 }); | |
var isEmbeddedTemplate = $('html').hasClass('page-interactive-embedded'); | |
if (isEmbeddedTemplate) { | |
var embedWidth = $(window).width(); | |
require([ | |
"shared/interactive/instances/app-communicator", | |
"foundation/views/page-manager" | |
], function(AppCommunicator, PageManager) { | |
AppCommunicator.triggerResize(); | |
PageManager.on("nyt:page-resize", function() { | |
// Currently can't listen to "lazy loader" event, so just wait 500ms for now | |
var windowWidth = $(window).width(); | |
if (embedWidth != windowWidth) { | |
embedWidth = windowWidth; | |
setTimeout(function() { | |
AppCommunicator.triggerResize(); | |
}, 500); | |
} | |
}); | |
}); | |
} | |
return GraphicsResizer; | |
}); | |
require([ | |
'jquery/nyt', | |
'underscore/1.6', | |
'foundation/views/page-manager', | |
'nyt5/analytics', | |
'swiper-script', | |
// 'd3/3', | |
// 'queue/1' | |
'resizerScript', // uncomment this line to include resizerScript | |
'shared/sharetools/views/sharetools' | |
// 'lib/text-balancer' // uncomment to balance headlines | |
], function($, _, PageManager, Analytics, Swiper, resizerScript, ShareTools) { | |
var swipey; | |
var ga_slug = "2015-03-10-ukraine-endgame"; | |
var savedIndexes = [0]; | |
function init() { | |
var isDesktop = (PageManager.getDevice() != "mobile") && (window.innerWidth > 601); | |
// add extrasharetools at end of story | |
new ShareTools({ | |
el: $(".fs-sharetools"), | |
// todo | |
url: "http://www.nytimes.com/interactive/2015/03/06/world/europe/russias-endgame-in-ukraine.html", | |
showAllModalSettings: { | |
modalTitle: 'Share this graphic', | |
tailDirection: 'up-left' | |
}, | |
}); | |
if (!isDesktop) { | |
// add initial mobile page view | |
_gaq.push(["_trackEvent", ga_slug, 'mobile-page-0']); | |
// move header into slides | |
var header = $('#story header.story-header'); | |
header.prependTo( ".g-header-slide" ) | |
// todo why not do this in css cant remember | |
$('footer.story-footer, footer.page-footer').hide(); | |
$('.story.theme-interactive').css('margin',0); | |
$('#main').css('padding',0); | |
//updatePagination(); | |
updateSlideHeights(); | |
swipey = new Swiper ('.swiper-container', { | |
direction: 'vertical', | |
loop: false, | |
pagination: '.swiper-pagination', | |
mousewheelControl: true, | |
keyboardControl: true, | |
// nextButton: '.g-next', | |
onSlideChangeStart: function() { | |
// if (!swipey.isEnd && (swipey.previousIndex > swipey.activeIndex) ) $('.g-next').css('opacity',0.6).css('pointer-events','all') | |
var active = swipey.slides[swipey.activeIndex]; | |
var mapslug = $(active).attr('data-mapslug'); | |
// console.log(mapslug); | |
$('.bg-map').not('.bg-map-'+mapslug).removeClass('bg-map-active'); | |
$('.bg-map-'+mapslug).addClass('bg-map-active'); | |
// Track mobile scroll index | |
if ( _.indexOf(savedIndexes, swipey.activeIndex) < 0 ) { | |
savedIndexes.push(swipey.activeIndex); | |
_gaq.push(["_trackEvent", ga_slug, 'mobile-page-' + swipey.activeIndex]); | |
} | |
}, | |
onSlideChangeEnd: function() { | |
updateSlideHeights(); | |
swipey.updateClasses(); | |
}, | |
onReachEnd: function() { } | |
}) | |
// gross hacks to make sure menus hide on first swipe on mobile | |
// basically, need to fool mobile browser into thinking the page scrolled down | |
// so, first swipe scrolls a hidden, long div that is then pushed to the back and pointer-event:none'd | |
// can't display:none the div because then the mobile browser will realize the page isn't more than | |
// one screen tall and menus will re-emerge. :( | |
$(window).scrollTop(0); | |
var touched; | |
$(window).bind('touchmove', function(event){ | |
if (touched) return; | |
touched = true; | |
// mbloch kludge: advance to next slide on the first touchmove event (after a brief delay) | |
setTimeout(function() { | |
swipey.slideNext(true, 500); | |
// swipey.updateClasses(); | |
// updateSlideHeights(); | |
}, 100) | |
$('#g-graphic-swipehelper') | |
.css('z-index',-100) | |
.css('pointer-events','none'); | |
}) | |
$(window).scroll(function() { | |
// lol needed to make sure dot hilites reset | |
return; | |
setTimeout(function(){ swipey.updateClasses(); }, 500); | |
setTimeout(function(){ swipey.updateClasses(); }, 1000); | |
setTimeout(function(){ swipey.updateClasses(); }, 1500); | |
}) | |
if ( window.innerHeight < window.innerWidth ) handleOrientation('viewport-landscape'); | |
PageManager.listenTo(PageManager, 'nyt:page-resize', updateSlideHeights); | |
PageManager.listenTo(PageManager, 'nyt:page-orientation', handleOrientation); | |
} | |
} | |
init(); | |
// | |
// | |
// | |
function handleOrientation(orientation) { | |
console.log(orientation) | |
var m = $('#disallow-landscape-modal'); | |
if (orientation === 'viewport-landscape') { m.show(); } | |
else { | |
m.hide(); | |
setTimeout(function(){ | |
swipey.slideTo(0); | |
updateSlideHeights(); | |
swipey.updateClasses(); | |
}, 500); | |
} | |
} | |
function updateSlideHeights() { | |
// console.log(window.innerWidth) | |
// console.log(window.innerHeight) | |
updatePageHeight(); | |
updatePagination(); | |
// header.height(targetHeight); | |
} | |
function updatePagination() { | |
if (swipey) setTimeout(function(){ swipey.updatePagination(); }, 1500); | |
} | |
function updatePageHeight() { | |
var mastheadHeight = $('#masthead').height(); | |
var targetHeight = window.innerHeight-mastheadHeight; | |
$('.swiper-container, #story header.story-header').height(targetHeight); | |
} | |
}); // end require | |
; | |
define("script", function(){}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment