sm-extend.js 141 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376
  1. /*!
  2. * =====================================================
  3. * SUI Mobile - http://m.sui.taobao.org/
  4. *
  5. * =====================================================
  6. */
  7. /*===========================
  8. Swiper
  9. ===========================*/
  10. /* global WebKitCSSMatrix:true */
  11. /* global Modernizr:true */
  12. /* global DocumentTouch:true */
  13. +function($){
  14. "use strict";
  15. var Swiper = function (container, params) {
  16. // if (!(this instanceof Swiper)) return new Swiper(container, params);
  17. var defaults = this.defaults;
  18. var initalVirtualTranslate = params && params.virtualTranslate;
  19. params = params || {};
  20. for (var def in defaults) {
  21. if (typeof params[def] === 'undefined') {
  22. params[def] = defaults[def];
  23. }
  24. else if (typeof params[def] === 'object') {
  25. for (var deepDef in defaults[def]) {
  26. if (typeof params[def][deepDef] === 'undefined') {
  27. params[def][deepDef] = defaults[def][deepDef];
  28. }
  29. }
  30. }
  31. }
  32. // Swiper
  33. var s = this;
  34. // Params
  35. s.params = params;
  36. // Classname
  37. s.classNames = [];
  38. // Export it to Swiper instance
  39. s.$ = $;
  40. /*=========================
  41. Preparation - Define Container, Wrapper and Pagination
  42. ===========================*/
  43. s.container = $(container);
  44. if (s.container.length === 0) return;
  45. if (s.container.length > 1) {
  46. s.container.each(function () {
  47. new $.Swiper(this, params);
  48. });
  49. return;
  50. }
  51. // Save instance in container HTML Element and in data
  52. s.container[0].swiper = s;
  53. s.container.data('swiper', s);
  54. s.classNames.push('swiper-container-' + s.params.direction);
  55. if (s.params.freeMode) {
  56. s.classNames.push('swiper-container-free-mode');
  57. }
  58. if (!s.support.flexbox) {
  59. s.classNames.push('swiper-container-no-flexbox');
  60. s.params.slidesPerColumn = 1;
  61. }
  62. // Enable slides progress when required
  63. if (s.params.parallax || s.params.watchSlidesVisibility) {
  64. s.params.watchSlidesProgress = true;
  65. }
  66. // Coverflow / 3D
  67. if (['cube', 'coverflow'].indexOf(s.params.effect) >= 0) {
  68. if (s.support.transforms3d) {
  69. s.params.watchSlidesProgress = true;
  70. s.classNames.push('swiper-container-3d');
  71. }
  72. else {
  73. s.params.effect = 'slide';
  74. }
  75. }
  76. if (s.params.effect !== 'slide') {
  77. s.classNames.push('swiper-container-' + s.params.effect);
  78. }
  79. if (s.params.effect === 'cube') {
  80. s.params.resistanceRatio = 0;
  81. s.params.slidesPerView = 1;
  82. s.params.slidesPerColumn = 1;
  83. s.params.slidesPerGroup = 1;
  84. s.params.centeredSlides = false;
  85. s.params.spaceBetween = 0;
  86. s.params.virtualTranslate = true;
  87. s.params.setWrapperSize = false;
  88. }
  89. if (s.params.effect === 'fade') {
  90. s.params.slidesPerView = 1;
  91. s.params.slidesPerColumn = 1;
  92. s.params.slidesPerGroup = 1;
  93. s.params.watchSlidesProgress = true;
  94. s.params.spaceBetween = 0;
  95. if (typeof initalVirtualTranslate === 'undefined') {
  96. s.params.virtualTranslate = true;
  97. }
  98. }
  99. // Grab Cursor
  100. if (s.params.grabCursor && s.support.touch) {
  101. s.params.grabCursor = false;
  102. }
  103. // Wrapper
  104. s.wrapper = s.container.children('.' + s.params.wrapperClass);
  105. // Pagination
  106. if (s.params.pagination) {
  107. s.paginationContainer = $(s.params.pagination);
  108. if (s.params.paginationClickable) {
  109. s.paginationContainer.addClass('swiper-pagination-clickable');
  110. }
  111. }
  112. // Is Horizontal
  113. function isH() {
  114. return s.params.direction === 'horizontal';
  115. }
  116. // RTL
  117. s.rtl = isH() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');
  118. if (s.rtl) {
  119. s.classNames.push('swiper-container-rtl');
  120. }
  121. // Wrong RTL support
  122. if (s.rtl) {
  123. s.wrongRTL = s.wrapper.css('display') === '-webkit-box';
  124. }
  125. // Columns
  126. if (s.params.slidesPerColumn > 1) {
  127. s.classNames.push('swiper-container-multirow');
  128. }
  129. // Check for Android
  130. if (s.device.android) {
  131. s.classNames.push('swiper-container-android');
  132. }
  133. // Add classes
  134. s.container.addClass(s.classNames.join(' '));
  135. // Translate
  136. s.translate = 0;
  137. // Progress
  138. s.progress = 0;
  139. // Velocity
  140. s.velocity = 0;
  141. // Locks, unlocks
  142. s.lockSwipeToNext = function () {
  143. s.params.allowSwipeToNext = false;
  144. };
  145. s.lockSwipeToPrev = function () {
  146. s.params.allowSwipeToPrev = false;
  147. };
  148. s.lockSwipes = function () {
  149. s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;
  150. };
  151. s.unlockSwipeToNext = function () {
  152. s.params.allowSwipeToNext = true;
  153. };
  154. s.unlockSwipeToPrev = function () {
  155. s.params.allowSwipeToPrev = true;
  156. };
  157. s.unlockSwipes = function () {
  158. s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;
  159. };
  160. /*=========================
  161. Set grab cursor
  162. ===========================*/
  163. if (s.params.grabCursor) {
  164. s.container[0].style.cursor = 'move';
  165. s.container[0].style.cursor = '-webkit-grab';
  166. s.container[0].style.cursor = '-moz-grab';
  167. s.container[0].style.cursor = 'grab';
  168. }
  169. /*=========================
  170. Update on Images Ready
  171. ===========================*/
  172. s.imagesToLoad = [];
  173. s.imagesLoaded = 0;
  174. s.loadImage = function (imgElement, src, checkForComplete, callback) {
  175. var image;
  176. function onReady () {
  177. if (callback) callback();
  178. }
  179. if (!imgElement.complete || !checkForComplete) {
  180. if (src) {
  181. image = new Image();
  182. image.onload = onReady;
  183. image.onerror = onReady;
  184. image.src = src;
  185. } else {
  186. onReady();
  187. }
  188. } else {//image already loaded...
  189. onReady();
  190. }
  191. };
  192. s.preloadImages = function () {
  193. s.imagesToLoad = s.container.find('img');
  194. function _onReady() {
  195. if (typeof s === 'undefined' || s === null) return;
  196. if (s.imagesLoaded !== undefined) s.imagesLoaded++;
  197. if (s.imagesLoaded === s.imagesToLoad.length) {
  198. if (s.params.updateOnImagesReady) s.update();
  199. s.emit('onImagesReady', s);
  200. }
  201. }
  202. for (var i = 0; i < s.imagesToLoad.length; i++) {
  203. s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), true, _onReady);
  204. }
  205. };
  206. /*=========================
  207. Autoplay
  208. ===========================*/
  209. s.autoplayTimeoutId = undefined;
  210. s.autoplaying = false;
  211. s.autoplayPaused = false;
  212. function autoplay() {
  213. s.autoplayTimeoutId = setTimeout(function () {
  214. if (s.params.loop) {
  215. s.fixLoop();
  216. s._slideNext();
  217. }
  218. else {
  219. if (!s.isEnd) {
  220. s._slideNext();
  221. }
  222. else {
  223. if (!params.autoplayStopOnLast) {
  224. s._slideTo(0);
  225. }
  226. else {
  227. s.stopAutoplay();
  228. }
  229. }
  230. }
  231. }, s.params.autoplay);
  232. }
  233. s.startAutoplay = function () {
  234. if (typeof s.autoplayTimeoutId !== 'undefined') return false;
  235. if (!s.params.autoplay) return false;
  236. if (s.autoplaying) return false;
  237. s.autoplaying = true;
  238. s.emit('onAutoplayStart', s);
  239. autoplay();
  240. };
  241. s.stopAutoplay = function () {
  242. if (!s.autoplayTimeoutId) return;
  243. if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
  244. s.autoplaying = false;
  245. s.autoplayTimeoutId = undefined;
  246. s.emit('onAutoplayStop', s);
  247. };
  248. s.pauseAutoplay = function (speed) {
  249. if (s.autoplayPaused) return;
  250. if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
  251. s.autoplayPaused = true;
  252. if (speed === 0) {
  253. s.autoplayPaused = false;
  254. autoplay();
  255. }
  256. else {
  257. s.wrapper.transitionEnd(function () {
  258. s.autoplayPaused = false;
  259. if (!s.autoplaying) {
  260. s.stopAutoplay();
  261. }
  262. else {
  263. autoplay();
  264. }
  265. });
  266. }
  267. };
  268. /*=========================
  269. Min/Max Translate
  270. ===========================*/
  271. s.minTranslate = function () {
  272. return (-s.snapGrid[0]);
  273. };
  274. s.maxTranslate = function () {
  275. return (-s.snapGrid[s.snapGrid.length - 1]);
  276. };
  277. /*=========================
  278. Slider/slides sizes
  279. ===========================*/
  280. s.updateContainerSize = function () {
  281. s.width = s.container[0].clientWidth;
  282. s.height = s.container[0].clientHeight;
  283. s.size = isH() ? s.width : s.height;
  284. };
  285. s.updateSlidesSize = function () {
  286. s.slides = s.wrapper.children('.' + s.params.slideClass);
  287. s.snapGrid = [];
  288. s.slidesGrid = [];
  289. s.slidesSizesGrid = [];
  290. var spaceBetween = s.params.spaceBetween,
  291. slidePosition = 0,
  292. i,
  293. prevSlideSize = 0,
  294. index = 0;
  295. if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
  296. spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;
  297. }
  298. s.virtualSize = -spaceBetween;
  299. // reset margins
  300. if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});
  301. else s.slides.css({marginRight: '', marginBottom: ''});
  302. var slidesNumberEvenToRows;
  303. if (s.params.slidesPerColumn > 1) {
  304. if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {
  305. slidesNumberEvenToRows = s.slides.length;
  306. }
  307. else {
  308. slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;
  309. }
  310. }
  311. // Calc slides
  312. var slideSize;
  313. for (i = 0; i < s.slides.length; i++) {
  314. slideSize = 0;
  315. var slide = s.slides.eq(i);
  316. if (s.params.slidesPerColumn > 1) {
  317. // Set slides order
  318. var newSlideOrderIndex;
  319. var column, row;
  320. var slidesPerColumn = s.params.slidesPerColumn;
  321. var slidesPerRow;
  322. if (s.params.slidesPerColumnFill === 'column') {
  323. column = Math.floor(i / slidesPerColumn);
  324. row = i - column * slidesPerColumn;
  325. newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;
  326. slide
  327. .css({
  328. '-webkit-box-ordinal-group': newSlideOrderIndex,
  329. '-moz-box-ordinal-group': newSlideOrderIndex,
  330. '-ms-flex-order': newSlideOrderIndex,
  331. '-webkit-order': newSlideOrderIndex,
  332. 'order': newSlideOrderIndex
  333. });
  334. }
  335. else {
  336. slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;
  337. row = Math.floor(i / slidesPerRow);
  338. column = i - row * slidesPerRow;
  339. }
  340. slide
  341. .css({
  342. 'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')
  343. })
  344. .attr('data-swiper-column', column)
  345. .attr('data-swiper-row', row);
  346. }
  347. if (slide.css('display') === 'none') continue;
  348. if (s.params.slidesPerView === 'auto') {
  349. slideSize = isH() ? slide.outerWidth(true) : slide.outerHeight(true);
  350. }
  351. else {
  352. slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;
  353. if (isH()) {
  354. s.slides[i].style.width = slideSize + 'px';
  355. }
  356. else {
  357. s.slides[i].style.height = slideSize + 'px';
  358. }
  359. }
  360. s.slides[i].swiperSlideSize = slideSize;
  361. s.slidesSizesGrid.push(slideSize);
  362. if (s.params.centeredSlides) {
  363. slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
  364. if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;
  365. if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
  366. if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
  367. s.slidesGrid.push(slidePosition);
  368. }
  369. else {
  370. if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
  371. s.slidesGrid.push(slidePosition);
  372. slidePosition = slidePosition + slideSize + spaceBetween;
  373. }
  374. s.virtualSize += slideSize + spaceBetween;
  375. prevSlideSize = slideSize;
  376. index ++;
  377. }
  378. s.virtualSize = Math.max(s.virtualSize, s.size);
  379. var newSlidesGrid;
  380. if (
  381. s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {
  382. s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
  383. }
  384. if (!s.support.flexbox || s.params.setWrapperSize) {
  385. if (isH()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
  386. else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});
  387. }
  388. if (s.params.slidesPerColumn > 1) {
  389. s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;
  390. s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;
  391. s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
  392. if (s.params.centeredSlides) {
  393. newSlidesGrid = [];
  394. for (i = 0; i < s.snapGrid.length; i++) {
  395. if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);
  396. }
  397. s.snapGrid = newSlidesGrid;
  398. }
  399. }
  400. // Remove last grid elements depending on width
  401. if (!s.params.centeredSlides) {
  402. newSlidesGrid = [];
  403. for (i = 0; i < s.snapGrid.length; i++) {
  404. if (s.snapGrid[i] <= s.virtualSize - s.size) {
  405. newSlidesGrid.push(s.snapGrid[i]);
  406. }
  407. }
  408. s.snapGrid = newSlidesGrid;
  409. if (Math.floor(s.virtualSize - s.size) > Math.floor(s.snapGrid[s.snapGrid.length - 1])) {
  410. s.snapGrid.push(s.virtualSize - s.size);
  411. }
  412. }
  413. if (s.snapGrid.length === 0) s.snapGrid = [0];
  414. if (s.params.spaceBetween !== 0) {
  415. if (isH()) {
  416. if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});
  417. else s.slides.css({marginRight: spaceBetween + 'px'});
  418. }
  419. else s.slides.css({marginBottom: spaceBetween + 'px'});
  420. }
  421. if (s.params.watchSlidesProgress) {
  422. s.updateSlidesOffset();
  423. }
  424. };
  425. s.updateSlidesOffset = function () {
  426. for (var i = 0; i < s.slides.length; i++) {
  427. s.slides[i].swiperSlideOffset = isH() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;
  428. }
  429. };
  430. /*=========================
  431. Slider/slides progress
  432. ===========================*/
  433. s.updateSlidesProgress = function (translate) {
  434. if (typeof translate === 'undefined') {
  435. translate = s.translate || 0;
  436. }
  437. if (s.slides.length === 0) return;
  438. if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();
  439. var offsetCenter = s.params.centeredSlides ? -translate + s.size / 2 : -translate;
  440. if (s.rtl) offsetCenter = s.params.centeredSlides ? translate - s.size / 2 : translate;
  441. // Visible Slides
  442. s.slides.removeClass(s.params.slideVisibleClass);
  443. for (var i = 0; i < s.slides.length; i++) {
  444. var slide = s.slides[i];
  445. var slideCenterOffset = (s.params.centeredSlides === true) ? slide.swiperSlideSize / 2 : 0;
  446. var slideProgress = (offsetCenter - slide.swiperSlideOffset - slideCenterOffset) / (slide.swiperSlideSize + s.params.spaceBetween);
  447. if (s.params.watchSlidesVisibility) {
  448. var slideBefore = -(offsetCenter - slide.swiperSlideOffset - slideCenterOffset);
  449. var slideAfter = slideBefore + s.slidesSizesGrid[i];
  450. var isVisible =
  451. (slideBefore >= 0 && slideBefore < s.size) ||
  452. (slideAfter > 0 && slideAfter <= s.size) ||
  453. (slideBefore <= 0 && slideAfter >= s.size);
  454. if (isVisible) {
  455. s.slides.eq(i).addClass(s.params.slideVisibleClass);
  456. }
  457. }
  458. slide.progress = s.rtl ? -slideProgress : slideProgress;
  459. }
  460. };
  461. s.updateProgress = function (translate) {
  462. if (typeof translate === 'undefined') {
  463. translate = s.translate || 0;
  464. }
  465. var translatesDiff = s.maxTranslate() - s.minTranslate();
  466. if (translatesDiff === 0) {
  467. s.progress = 0;
  468. s.isBeginning = s.isEnd = true;
  469. }
  470. else {
  471. s.progress = (translate - s.minTranslate()) / (translatesDiff);
  472. s.isBeginning = s.progress <= 0;
  473. s.isEnd = s.progress >= 1;
  474. }
  475. if (s.isBeginning) s.emit('onReachBeginning', s);
  476. if (s.isEnd) s.emit('onReachEnd', s);
  477. if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);
  478. s.emit('onProgress', s, s.progress);
  479. };
  480. s.updateActiveIndex = function () {
  481. var translate = s.rtl ? s.translate : -s.translate;
  482. var newActiveIndex, i, snapIndex;
  483. for (i = 0; i < s.slidesGrid.length; i ++) {
  484. if (typeof s.slidesGrid[i + 1] !== 'undefined') {
  485. if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {
  486. newActiveIndex = i;
  487. }
  488. else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {
  489. newActiveIndex = i + 1;
  490. }
  491. }
  492. else {
  493. if (translate >= s.slidesGrid[i]) {
  494. newActiveIndex = i;
  495. }
  496. }
  497. }
  498. // Normalize slideIndex
  499. if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;
  500. // for (i = 0; i < s.slidesGrid.length; i++) {
  501. // if (- translate >= s.slidesGrid[i]) {
  502. // newActiveIndex = i;
  503. // }
  504. // }
  505. snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);
  506. if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;
  507. if (newActiveIndex === s.activeIndex) {
  508. return;
  509. }
  510. s.snapIndex = snapIndex;
  511. s.previousIndex = s.activeIndex;
  512. s.activeIndex = newActiveIndex;
  513. s.updateClasses();
  514. };
  515. /*=========================
  516. Classes
  517. ===========================*/
  518. s.updateClasses = function () {
  519. s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);
  520. var activeSlide = s.slides.eq(s.activeIndex);
  521. // Active classes
  522. activeSlide.addClass(s.params.slideActiveClass);
  523. activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);
  524. activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);
  525. // Pagination
  526. if (s.bullets && s.bullets.length > 0) {
  527. s.bullets.removeClass(s.params.bulletActiveClass);
  528. var bulletIndex;
  529. if (s.params.loop) {
  530. bulletIndex = Math.ceil(s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup;
  531. if (bulletIndex > s.slides.length - 1 - s.loopedSlides * 2) {
  532. bulletIndex = bulletIndex - (s.slides.length - s.loopedSlides * 2);
  533. }
  534. if (bulletIndex > s.bullets.length - 1) bulletIndex = bulletIndex - s.bullets.length;
  535. }
  536. else {
  537. if (typeof s.snapIndex !== 'undefined') {
  538. bulletIndex = s.snapIndex;
  539. }
  540. else {
  541. bulletIndex = s.activeIndex || 0;
  542. }
  543. }
  544. if (s.paginationContainer.length > 1) {
  545. s.bullets.each(function () {
  546. if ($(this).index() === bulletIndex) $(this).addClass(s.params.bulletActiveClass);
  547. });
  548. }
  549. else {
  550. s.bullets.eq(bulletIndex).addClass(s.params.bulletActiveClass);
  551. }
  552. }
  553. // Next/active buttons
  554. if (!s.params.loop) {
  555. if (s.params.prevButton) {
  556. if (s.isBeginning) {
  557. $(s.params.prevButton).addClass(s.params.buttonDisabledClass);
  558. if (s.params.a11y && s.a11y) s.a11y.disable($(s.params.prevButton));
  559. }
  560. else {
  561. $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);
  562. if (s.params.a11y && s.a11y) s.a11y.enable($(s.params.prevButton));
  563. }
  564. }
  565. if (s.params.nextButton) {
  566. if (s.isEnd) {
  567. $(s.params.nextButton).addClass(s.params.buttonDisabledClass);
  568. if (s.params.a11y && s.a11y) s.a11y.disable($(s.params.nextButton));
  569. }
  570. else {
  571. $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);
  572. if (s.params.a11y && s.a11y) s.a11y.enable($(s.params.nextButton));
  573. }
  574. }
  575. }
  576. };
  577. /*=========================
  578. Pagination
  579. ===========================*/
  580. s.updatePagination = function () {
  581. if (!s.params.pagination) return;
  582. if (s.paginationContainer && s.paginationContainer.length > 0) {
  583. var bulletsHTML = '';
  584. var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;
  585. for (var i = 0; i < numberOfBullets; i++) {
  586. if (s.params.paginationBulletRender) {
  587. bulletsHTML += s.params.paginationBulletRender(i, s.params.bulletClass);
  588. }
  589. else {
  590. bulletsHTML += '<span class="' + s.params.bulletClass + '"></span>';
  591. }
  592. }
  593. s.paginationContainer.html(bulletsHTML);
  594. s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);
  595. }
  596. };
  597. /*=========================
  598. Common update method
  599. ===========================*/
  600. s.update = function (updateTranslate) {
  601. s.updateContainerSize();
  602. s.updateSlidesSize();
  603. s.updateProgress();
  604. s.updatePagination();
  605. s.updateClasses();
  606. if (s.params.scrollbar && s.scrollbar) {
  607. s.scrollbar.set();
  608. }
  609. function forceSetTranslate() {
  610. newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
  611. s.setWrapperTranslate(newTranslate);
  612. s.updateActiveIndex();
  613. s.updateClasses();
  614. }
  615. if (updateTranslate) {
  616. var translated, newTranslate;
  617. if (s.params.freeMode) {
  618. forceSetTranslate();
  619. }
  620. else {
  621. if (s.params.slidesPerView === 'auto' && s.isEnd && !s.params.centeredSlides) {
  622. translated = s.slideTo(s.slides.length - 1, 0, false, true);
  623. }
  624. else {
  625. translated = s.slideTo(s.activeIndex, 0, false, true);
  626. }
  627. if (!translated) {
  628. forceSetTranslate();
  629. }
  630. }
  631. }
  632. };
  633. /*=========================
  634. Resize Handler
  635. ===========================*/
  636. s.onResize = function () {
  637. s.updateContainerSize();
  638. s.updateSlidesSize();
  639. s.updateProgress();
  640. if (s.params.slidesPerView === 'auto' || s.params.freeMode) s.updatePagination();
  641. if (s.params.scrollbar && s.scrollbar) {
  642. s.scrollbar.set();
  643. }
  644. if (s.params.freeMode) {
  645. var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
  646. s.setWrapperTranslate(newTranslate);
  647. s.updateActiveIndex();
  648. s.updateClasses();
  649. }
  650. else {
  651. s.updateClasses();
  652. if (s.params.slidesPerView === 'auto' && s.isEnd && !s.params.centeredSlides) {
  653. s.slideTo(s.slides.length - 1, 0, false, true);
  654. }
  655. else {
  656. s.slideTo(s.activeIndex, 0, false, true);
  657. }
  658. }
  659. };
  660. /*=========================
  661. Events
  662. ===========================*/
  663. //Define Touch Events
  664. var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];
  665. if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];
  666. else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];
  667. s.touchEvents = {
  668. start : s.support.touch || !s.params.simulateTouch ? 'touchstart' : desktopEvents[0],
  669. move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],
  670. end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]
  671. };
  672. // WP8 Touch Events Fix
  673. if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {
  674. (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);
  675. }
  676. // Attach/detach events
  677. s.initEvents = function (detach) {
  678. var actionDom = detach ? 'off' : 'on';
  679. var action = detach ? 'removeEventListener' : 'addEventListener';
  680. var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];
  681. var target = s.support.touch ? touchEventsTarget : document;
  682. var moveCapture = s.params.nested ? true : false;
  683. //Touch Events
  684. if (s.browser.ie) {
  685. touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);
  686. target[action](s.touchEvents.move, s.onTouchMove, moveCapture);
  687. target[action](s.touchEvents.end, s.onTouchEnd, false);
  688. }
  689. else {
  690. if (s.support.touch) {
  691. touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);
  692. touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);
  693. touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);
  694. }
  695. if (params.simulateTouch && !s.device.ios && !s.device.android) {
  696. touchEventsTarget[action]('mousedown', s.onTouchStart, false);
  697. target[action]('mousemove', s.onTouchMove, moveCapture);
  698. target[action]('mouseup', s.onTouchEnd, false);
  699. }
  700. }
  701. window[action]('resize', s.onResize);
  702. // Next, Prev, Index
  703. if (s.params.nextButton) {
  704. $(s.params.nextButton)[actionDom]('click', s.onClickNext);
  705. if (s.params.a11y && s.a11y) $(s.params.nextButton)[actionDom]('keydown', s.a11y.onEnterKey);
  706. }
  707. if (s.params.prevButton) {
  708. $(s.params.prevButton)[actionDom]('click', s.onClickPrev);
  709. if (s.params.a11y && s.a11y) $(s.params.prevButton)[actionDom]('keydown', s.a11y.onEnterKey);
  710. }
  711. if (s.params.pagination && s.params.paginationClickable) {
  712. $(s.paginationContainer)[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);
  713. }
  714. // Prevent Links Clicks
  715. if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);
  716. };
  717. s.attachEvents = function () {
  718. s.initEvents();
  719. };
  720. s.detachEvents = function () {
  721. s.initEvents(true);
  722. };
  723. /*=========================
  724. Handle Clicks
  725. ===========================*/
  726. // Prevent Clicks
  727. s.allowClick = true;
  728. s.preventClicks = function (e) {
  729. if (!s.allowClick) {
  730. if (s.params.preventClicks) e.preventDefault();
  731. if (s.params.preventClicksPropagation) {
  732. e.stopPropagation();
  733. e.stopImmediatePropagation();
  734. }
  735. }
  736. };
  737. // Clicks
  738. s.onClickNext = function (e) {
  739. e.preventDefault();
  740. s.slideNext();
  741. };
  742. s.onClickPrev = function (e) {
  743. e.preventDefault();
  744. s.slidePrev();
  745. };
  746. s.onClickIndex = function (e) {
  747. e.preventDefault();
  748. var index = $(this).index() * s.params.slidesPerGroup;
  749. if (s.params.loop) index = index + s.loopedSlides;
  750. s.slideTo(index);
  751. };
  752. /*=========================
  753. Handle Touches
  754. ===========================*/
  755. function findElementInEvent(e, selector) {
  756. var el = $(e.target);
  757. if (!el.is(selector)) {
  758. if (typeof selector === 'string') {
  759. el = el.parents(selector);
  760. }
  761. else if (selector.nodeType) {
  762. var found;
  763. el.parents().each(function (index, _el) {
  764. if (_el === selector) found = selector;
  765. });
  766. if (!found) return undefined;
  767. else return selector;
  768. }
  769. }
  770. if (el.length === 0) {
  771. return undefined;
  772. }
  773. return el[0];
  774. }
  775. s.updateClickedSlide = function (e) {
  776. var slide = findElementInEvent(e, '.' + s.params.slideClass);
  777. if (slide) {
  778. s.clickedSlide = slide;
  779. s.clickedIndex = $(slide).index();
  780. }
  781. else {
  782. s.clickedSlide = undefined;
  783. s.clickedIndex = undefined;
  784. return;
  785. }
  786. if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {
  787. var slideToIndex = s.clickedIndex,
  788. realIndex;
  789. if (s.params.loop) {
  790. realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');
  791. if (slideToIndex > s.slides.length - s.params.slidesPerView) {
  792. s.fixLoop();
  793. slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]').eq(0).index();
  794. setTimeout(function () {
  795. s.slideTo(slideToIndex);
  796. }, 0);
  797. }
  798. else if (slideToIndex < s.params.slidesPerView - 1) {
  799. s.fixLoop();
  800. var duplicatedSlides = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]');
  801. slideToIndex = duplicatedSlides.eq(duplicatedSlides.length - 1).index();
  802. setTimeout(function () {
  803. s.slideTo(slideToIndex);
  804. }, 0);
  805. }
  806. else {
  807. s.slideTo(slideToIndex);
  808. }
  809. }
  810. else {
  811. s.slideTo(slideToIndex);
  812. }
  813. }
  814. };
  815. var isTouched,
  816. isMoved,
  817. touchStartTime,
  818. isScrolling,
  819. currentTranslate,
  820. startTranslate,
  821. allowThresholdMove,
  822. // Form elements to match
  823. formElements = 'input, select, textarea, button',
  824. // Last click time
  825. lastClickTime = Date.now(), clickTimeout,
  826. //Velocities
  827. velocities = [],
  828. allowMomentumBounce;
  829. // Animating Flag
  830. s.animating = false;
  831. // Touches information
  832. s.touches = {
  833. startX: 0,
  834. startY: 0,
  835. currentX: 0,
  836. currentY: 0,
  837. diff: 0
  838. };
  839. // Touch handlers
  840. var isTouchEvent, startMoving;
  841. s.onTouchStart = function (e) {
  842. if (e.originalEvent) e = e.originalEvent;
  843. isTouchEvent = e.type === 'touchstart';
  844. if (!isTouchEvent && 'which' in e && e.which === 3) return;
  845. if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {
  846. s.allowClick = true;
  847. return;
  848. }
  849. if (s.params.swipeHandler) {
  850. if (!findElementInEvent(e, s.params.swipeHandler)) return;
  851. }
  852. isTouched = true;
  853. isMoved = false;
  854. isScrolling = undefined;
  855. startMoving = undefined;
  856. s.touches.startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
  857. s.touches.startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
  858. touchStartTime = Date.now();
  859. s.allowClick = true;
  860. s.updateContainerSize();
  861. s.swipeDirection = undefined;
  862. if (s.params.threshold > 0) allowThresholdMove = false;
  863. if (e.type !== 'touchstart') {
  864. var preventDefault = true;
  865. if ($(e.target).is(formElements)) preventDefault = false;
  866. if (document.activeElement && $(document.activeElement).is(formElements)) {
  867. document.activeElement.blur();
  868. }
  869. if (preventDefault) {
  870. e.preventDefault();
  871. }
  872. }
  873. s.emit('onTouchStart', s, e);
  874. };
  875. s.onTouchMove = function (e) {
  876. if (e.originalEvent) e = e.originalEvent;
  877. if (isTouchEvent && e.type === 'mousemove') return;
  878. if (e.preventedByNestedSwiper) return;
  879. if (s.params.onlyExternal) {
  880. isMoved = true;
  881. s.allowClick = false;
  882. return;
  883. }
  884. if (isTouchEvent && document.activeElement) {
  885. if (e.target === document.activeElement && $(e.target).is(formElements)) {
  886. isMoved = true;
  887. s.allowClick = false;
  888. return;
  889. }
  890. }
  891. s.emit('onTouchMove', s, e);
  892. if (e.targetTouches && e.targetTouches.length > 1) return;
  893. s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
  894. s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
  895. if (typeof isScrolling === 'undefined') {
  896. var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;
  897. isScrolling = isH() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);
  898. }
  899. if (isScrolling) {
  900. s.emit('onTouchMoveOpposite', s, e);
  901. }
  902. if (typeof startMoving === 'undefined' && s.browser.ieTouch) {
  903. if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {
  904. startMoving = true;
  905. }
  906. }
  907. if (!isTouched) return;
  908. if (isScrolling) {
  909. isTouched = false;
  910. return;
  911. }
  912. if (!startMoving && s.browser.ieTouch) {
  913. return;
  914. }
  915. s.allowClick = false;
  916. s.emit('onSliderMove', s, e);
  917. e.preventDefault();
  918. if (s.params.touchMoveStopPropagation && !s.params.nested) {
  919. e.stopPropagation();
  920. }
  921. if (!isMoved) {
  922. if (params.loop) {
  923. s.fixLoop();
  924. }
  925. startTranslate = s.getWrapperTranslate();
  926. s.setWrapperTransition(0);
  927. if (s.animating) {
  928. s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');
  929. }
  930. if (s.params.autoplay && s.autoplaying) {
  931. if (s.params.autoplayDisableOnInteraction) {
  932. s.stopAutoplay();
  933. }
  934. else {
  935. s.pauseAutoplay();
  936. }
  937. }
  938. allowMomentumBounce = false;
  939. //Grab Cursor
  940. if (s.params.grabCursor) {
  941. s.container[0].style.cursor = 'move';
  942. s.container[0].style.cursor = '-webkit-grabbing';
  943. s.container[0].style.cursor = '-moz-grabbin';
  944. s.container[0].style.cursor = 'grabbing';
  945. }
  946. }
  947. isMoved = true;
  948. var diff = s.touches.diff = isH() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
  949. diff = diff * s.params.touchRatio;
  950. if (s.rtl) diff = -diff;
  951. s.swipeDirection = diff > 0 ? 'prev' : 'next';
  952. currentTranslate = diff + startTranslate;
  953. var disableParentSwiper = true;
  954. if ((diff > 0 && currentTranslate > s.minTranslate())) {
  955. disableParentSwiper = false;
  956. if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);
  957. }
  958. else if (diff < 0 && currentTranslate < s.maxTranslate()) {
  959. disableParentSwiper = false;
  960. if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);
  961. }
  962. if (disableParentSwiper) {
  963. e.preventedByNestedSwiper = true;
  964. }
  965. // Directions locks
  966. if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {
  967. currentTranslate = startTranslate;
  968. }
  969. if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {
  970. currentTranslate = startTranslate;
  971. }
  972. if (!s.params.followFinger) return;
  973. // Threshold
  974. if (s.params.threshold > 0) {
  975. if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {
  976. if (!allowThresholdMove) {
  977. allowThresholdMove = true;
  978. s.touches.startX = s.touches.currentX;
  979. s.touches.startY = s.touches.currentY;
  980. currentTranslate = startTranslate;
  981. s.touches.diff = isH() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
  982. return;
  983. }
  984. }
  985. else {
  986. currentTranslate = startTranslate;
  987. return;
  988. }
  989. }
  990. // Update active index in free mode
  991. if (s.params.freeMode || s.params.watchSlidesProgress) {
  992. s.updateActiveIndex();
  993. }
  994. if (s.params.freeMode) {
  995. //Velocity
  996. if (velocities.length === 0) {
  997. velocities.push({
  998. position: s.touches[isH() ? 'startX' : 'startY'],
  999. time: touchStartTime
  1000. });
  1001. }
  1002. velocities.push({
  1003. position: s.touches[isH() ? 'currentX' : 'currentY'],
  1004. time: (new Date()).getTime()
  1005. });
  1006. }
  1007. // Update progress
  1008. s.updateProgress(currentTranslate);
  1009. // Update translate
  1010. s.setWrapperTranslate(currentTranslate);
  1011. };
  1012. s.onTouchEnd = function (e) {
  1013. if (e.originalEvent) e = e.originalEvent;
  1014. s.emit('onTouchEnd', s, e);
  1015. if (!isTouched) return;
  1016. //Return Grab Cursor
  1017. if (s.params.grabCursor && isMoved && isTouched) {
  1018. s.container[0].style.cursor = 'move';
  1019. s.container[0].style.cursor = '-webkit-grab';
  1020. s.container[0].style.cursor = '-moz-grab';
  1021. s.container[0].style.cursor = 'grab';
  1022. }
  1023. // Time diff
  1024. var touchEndTime = Date.now();
  1025. var timeDiff = touchEndTime - touchStartTime;
  1026. // Tap, doubleTap, Click
  1027. if (s.allowClick) {
  1028. s.updateClickedSlide(e);
  1029. s.emit('onTap', s, e);
  1030. if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {
  1031. if (clickTimeout) clearTimeout(clickTimeout);
  1032. clickTimeout = setTimeout(function () {
  1033. if (!s) return;
  1034. if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {
  1035. s.paginationContainer.toggleClass(s.params.paginationHiddenClass);
  1036. }
  1037. s.emit('onClick', s, e);
  1038. }, 300);
  1039. }
  1040. if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {
  1041. if (clickTimeout) clearTimeout(clickTimeout);
  1042. s.emit('onDoubleTap', s, e);
  1043. }
  1044. }
  1045. lastClickTime = Date.now();
  1046. setTimeout(function () {
  1047. if (s && s.allowClick) s.allowClick = true;
  1048. }, 0);
  1049. if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {
  1050. isTouched = isMoved = false;
  1051. return;
  1052. }
  1053. isTouched = isMoved = false;
  1054. var currentPos;
  1055. if (s.params.followFinger) {
  1056. currentPos = s.rtl ? s.translate : -s.translate;
  1057. }
  1058. else {
  1059. currentPos = -currentTranslate;
  1060. }
  1061. if (s.params.freeMode) {
  1062. if (currentPos < -s.minTranslate()) {
  1063. s.slideTo(s.activeIndex);
  1064. return;
  1065. }
  1066. else if (currentPos > -s.maxTranslate()) {
  1067. s.slideTo(s.slides.length - 1);
  1068. return;
  1069. }
  1070. if (s.params.freeModeMomentum) {
  1071. if (velocities.length > 1) {
  1072. var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();
  1073. var distance = lastMoveEvent.position - velocityEvent.position;
  1074. var time = lastMoveEvent.time - velocityEvent.time;
  1075. s.velocity = distance / time;
  1076. s.velocity = s.velocity / 2;
  1077. if (Math.abs(s.velocity) < 0.02) {
  1078. s.velocity = 0;
  1079. }
  1080. // this implies that the user stopped moving a finger then released.
  1081. // There would be no events with distance zero, so the last event is stale.
  1082. if (time > 150 || (new Date().getTime() - lastMoveEvent.time) > 300) {
  1083. s.velocity = 0;
  1084. }
  1085. } else {
  1086. s.velocity = 0;
  1087. }
  1088. velocities.length = 0;
  1089. var momentumDuration = 1000 * s.params.freeModeMomentumRatio;
  1090. var momentumDistance = s.velocity * momentumDuration;
  1091. var newPosition = s.translate + momentumDistance;
  1092. if (s.rtl) newPosition = - newPosition;
  1093. var doBounce = false;
  1094. var afterBouncePosition;
  1095. var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;
  1096. if (newPosition < s.maxTranslate()) {
  1097. if (s.params.freeModeMomentumBounce) {
  1098. if (newPosition + s.maxTranslate() < -bounceAmount) {
  1099. newPosition = s.maxTranslate() - bounceAmount;
  1100. }
  1101. afterBouncePosition = s.maxTranslate();
  1102. doBounce = true;
  1103. allowMomentumBounce = true;
  1104. }
  1105. else {
  1106. newPosition = s.maxTranslate();
  1107. }
  1108. }
  1109. if (newPosition > s.minTranslate()) {
  1110. if (s.params.freeModeMomentumBounce) {
  1111. if (newPosition - s.minTranslate() > bounceAmount) {
  1112. newPosition = s.minTranslate() + bounceAmount;
  1113. }
  1114. afterBouncePosition = s.minTranslate();
  1115. doBounce = true;
  1116. allowMomentumBounce = true;
  1117. }
  1118. else {
  1119. newPosition = s.minTranslate();
  1120. }
  1121. }
  1122. //Fix duration
  1123. if (s.velocity !== 0) {
  1124. if (s.rtl) {
  1125. momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);
  1126. }
  1127. else {
  1128. momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);
  1129. }
  1130. }
  1131. if (s.params.freeModeMomentumBounce && doBounce) {
  1132. s.updateProgress(afterBouncePosition);
  1133. s.setWrapperTransition(momentumDuration);
  1134. s.setWrapperTranslate(newPosition);
  1135. s.onTransitionStart();
  1136. s.animating = true;
  1137. s.wrapper.transitionEnd(function () {
  1138. if (!allowMomentumBounce) return;
  1139. s.emit('onMomentumBounce', s);
  1140. s.setWrapperTransition(s.params.speed);
  1141. s.setWrapperTranslate(afterBouncePosition);
  1142. s.wrapper.transitionEnd(function () {
  1143. s.onTransitionEnd();
  1144. });
  1145. });
  1146. } else if (s.velocity) {
  1147. s.updateProgress(newPosition);
  1148. s.setWrapperTransition(momentumDuration);
  1149. s.setWrapperTranslate(newPosition);
  1150. s.onTransitionStart();
  1151. if (!s.animating) {
  1152. s.animating = true;
  1153. s.wrapper.transitionEnd(function () {
  1154. s.onTransitionEnd();
  1155. });
  1156. }
  1157. } else {
  1158. s.updateProgress(newPosition);
  1159. }
  1160. s.updateActiveIndex();
  1161. }
  1162. if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {
  1163. s.updateProgress();
  1164. s.updateActiveIndex();
  1165. }
  1166. return;
  1167. }
  1168. // Find current slide
  1169. var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];
  1170. for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {
  1171. if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {
  1172. if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {
  1173. stopIndex = i;
  1174. groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];
  1175. }
  1176. }
  1177. else {
  1178. if (currentPos >= s.slidesGrid[i]) {
  1179. stopIndex = i;
  1180. groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];
  1181. }
  1182. }
  1183. }
  1184. // Find current slide size
  1185. var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;
  1186. if (timeDiff > s.params.longSwipesMs) {
  1187. // Long touches
  1188. if (!s.params.longSwipes) {
  1189. s.slideTo(s.activeIndex);
  1190. return;
  1191. }
  1192. if (s.swipeDirection === 'next') {
  1193. if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);
  1194. else s.slideTo(stopIndex);
  1195. }
  1196. if (s.swipeDirection === 'prev') {
  1197. if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);
  1198. else s.slideTo(stopIndex);
  1199. }
  1200. }
  1201. else {
  1202. // Short swipes
  1203. if (!s.params.shortSwipes) {
  1204. s.slideTo(s.activeIndex);
  1205. return;
  1206. }
  1207. if (s.swipeDirection === 'next') {
  1208. s.slideTo(stopIndex + s.params.slidesPerGroup);
  1209. }
  1210. if (s.swipeDirection === 'prev') {
  1211. s.slideTo(stopIndex);
  1212. }
  1213. }
  1214. };
  1215. /*=========================
  1216. Transitions
  1217. ===========================*/
  1218. s._slideTo = function (slideIndex, speed) {
  1219. return s.slideTo(slideIndex, speed, true, true);
  1220. };
  1221. s.slideTo = function (slideIndex, speed, runCallbacks, internal) {
  1222. if (typeof runCallbacks === 'undefined') runCallbacks = true;
  1223. if (typeof slideIndex === 'undefined') slideIndex = 0;
  1224. if (slideIndex < 0) slideIndex = 0;
  1225. s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);
  1226. if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;
  1227. var translate = - s.snapGrid[s.snapIndex];
  1228. // Stop autoplay
  1229. if (s.params.autoplay && s.autoplaying) {
  1230. if (internal || !s.params.autoplayDisableOnInteraction) {
  1231. s.pauseAutoplay(speed);
  1232. }
  1233. else {
  1234. s.stopAutoplay();
  1235. }
  1236. }
  1237. // Update progress
  1238. s.updateProgress(translate);
  1239. // Normalize slideIndex
  1240. for (var i = 0; i < s.slidesGrid.length; i++) {
  1241. if (- translate >= s.slidesGrid[i]) {
  1242. slideIndex = i;
  1243. }
  1244. }
  1245. if (typeof speed === 'undefined') speed = s.params.speed;
  1246. s.previousIndex = s.activeIndex || 0;
  1247. s.activeIndex = slideIndex;
  1248. if (translate === s.translate) {
  1249. s.updateClasses();
  1250. return false;
  1251. }
  1252. s.onTransitionStart(runCallbacks);
  1253. if (speed === 0) {
  1254. s.setWrapperTransition(0);
  1255. s.setWrapperTranslate(translate);
  1256. s.onTransitionEnd(runCallbacks);
  1257. }
  1258. else {
  1259. s.setWrapperTransition(speed);
  1260. s.setWrapperTranslate(translate);
  1261. if (!s.animating) {
  1262. s.animating = true;
  1263. s.wrapper.transitionEnd(function () {
  1264. s.onTransitionEnd(runCallbacks);
  1265. });
  1266. }
  1267. }
  1268. s.updateClasses();
  1269. return true;
  1270. };
  1271. s.onTransitionStart = function (runCallbacks) {
  1272. if (typeof runCallbacks === 'undefined') runCallbacks = true;
  1273. if (s.lazy) s.lazy.onTransitionStart();
  1274. if (runCallbacks) {
  1275. s.emit('onTransitionStart', s);
  1276. if (s.activeIndex !== s.previousIndex) {
  1277. s.emit('onSlideChangeStart', s);
  1278. }
  1279. }
  1280. };
  1281. s.onTransitionEnd = function (runCallbacks) {
  1282. s.animating = false;
  1283. s.setWrapperTransition(0);
  1284. if (typeof runCallbacks === 'undefined') runCallbacks = true;
  1285. if (s.lazy) s.lazy.onTransitionEnd();
  1286. if (runCallbacks) {
  1287. s.emit('onTransitionEnd', s);
  1288. if (s.activeIndex !== s.previousIndex) {
  1289. s.emit('onSlideChangeEnd', s);
  1290. }
  1291. }
  1292. if (s.params.hashnav && s.hashnav) {
  1293. s.hashnav.setHash();
  1294. }
  1295. };
  1296. s.slideNext = function (runCallbacks, speed, internal) {
  1297. if (s.params.loop) {
  1298. if (s.animating) return false;
  1299. s.fixLoop();
  1300. return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
  1301. }
  1302. else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
  1303. };
  1304. s._slideNext = function (speed) {
  1305. return s.slideNext(true, speed, true);
  1306. };
  1307. s.slidePrev = function (runCallbacks, speed, internal) {
  1308. if (s.params.loop) {
  1309. if (s.animating) return false;
  1310. s.fixLoop();
  1311. return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
  1312. }
  1313. else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
  1314. };
  1315. s._slidePrev = function (speed) {
  1316. return s.slidePrev(true, speed, true);
  1317. };
  1318. s.slideReset = function (runCallbacks, speed) {
  1319. return s.slideTo(s.activeIndex, speed, runCallbacks);
  1320. };
  1321. /*=========================
  1322. Translate/transition helpers
  1323. ===========================*/
  1324. s.setWrapperTransition = function (duration, byController) {
  1325. s.wrapper.transition(duration);
  1326. if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
  1327. s.effects[s.params.effect].setTransition(duration);
  1328. }
  1329. if (s.params.parallax && s.parallax) {
  1330. s.parallax.setTransition(duration);
  1331. }
  1332. if (s.params.scrollbar && s.scrollbar) {
  1333. s.scrollbar.setTransition(duration);
  1334. }
  1335. if (s.params.control && s.controller) {
  1336. s.controller.setTransition(duration, byController);
  1337. }
  1338. s.emit('onSetTransition', s, duration);
  1339. };
  1340. s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {
  1341. var x = 0, y = 0, z = 0;
  1342. if (isH()) {
  1343. x = s.rtl ? -translate : translate;
  1344. }
  1345. else {
  1346. y = translate;
  1347. }
  1348. if (!s.params.virtualTranslate) {
  1349. if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');
  1350. else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');
  1351. }
  1352. s.translate = isH() ? x : y;
  1353. if (updateActiveIndex) s.updateActiveIndex();
  1354. if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
  1355. s.effects[s.params.effect].setTranslate(s.translate);
  1356. }
  1357. if (s.params.parallax && s.parallax) {
  1358. s.parallax.setTranslate(s.translate);
  1359. }
  1360. if (s.params.scrollbar && s.scrollbar) {
  1361. s.scrollbar.setTranslate(s.translate);
  1362. }
  1363. if (s.params.control && s.controller) {
  1364. s.controller.setTranslate(s.translate, byController);
  1365. }
  1366. s.emit('onSetTranslate', s, s.translate);
  1367. };
  1368. s.getTranslate = function (el, axis) {
  1369. var matrix, curTransform, curStyle, transformMatrix;
  1370. // automatic axis detection
  1371. if (typeof axis === 'undefined') {
  1372. axis = 'x';
  1373. }
  1374. if (s.params.virtualTranslate) {
  1375. return s.rtl ? -s.translate : s.translate;
  1376. }
  1377. curStyle = window.getComputedStyle(el, null);
  1378. if (window.WebKitCSSMatrix) {
  1379. // Some old versions of Webkit choke when 'none' is passed; pass
  1380. // empty string instead in this case
  1381. transformMatrix = new WebKitCSSMatrix(curStyle.webkitTransform === 'none' ? '' : curStyle.webkitTransform);
  1382. }
  1383. else {
  1384. transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
  1385. matrix = transformMatrix.toString().split(',');
  1386. }
  1387. if (axis === 'x') {
  1388. //Latest Chrome and webkits Fix
  1389. if (window.WebKitCSSMatrix)
  1390. curTransform = transformMatrix.m41;
  1391. //Crazy IE10 Matrix
  1392. else if (matrix.length === 16)
  1393. curTransform = parseFloat(matrix[12]);
  1394. //Normal Browsers
  1395. else
  1396. curTransform = parseFloat(matrix[4]);
  1397. }
  1398. if (axis === 'y') {
  1399. //Latest Chrome and webkits Fix
  1400. if (window.WebKitCSSMatrix)
  1401. curTransform = transformMatrix.m42;
  1402. //Crazy IE10 Matrix
  1403. else if (matrix.length === 16)
  1404. curTransform = parseFloat(matrix[13]);
  1405. //Normal Browsers
  1406. else
  1407. curTransform = parseFloat(matrix[5]);
  1408. }
  1409. if (s.rtl && curTransform) curTransform = -curTransform;
  1410. return curTransform || 0;
  1411. };
  1412. s.getWrapperTranslate = function (axis) {
  1413. if (typeof axis === 'undefined') {
  1414. axis = isH() ? 'x' : 'y';
  1415. }
  1416. return s.getTranslate(s.wrapper[0], axis);
  1417. };
  1418. /*=========================
  1419. Observer
  1420. ===========================*/
  1421. s.observers = [];
  1422. function initObserver(target, options) {
  1423. options = options || {};
  1424. // create an observer instance
  1425. var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
  1426. var observer = new ObserverFunc(function (mutations) {
  1427. mutations.forEach(function (mutation) {
  1428. s.onResize();
  1429. s.emit('onObserverUpdate', s, mutation);
  1430. });
  1431. });
  1432. observer.observe(target, {
  1433. attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
  1434. childList: typeof options.childList === 'undefined' ? true : options.childList,
  1435. characterData: typeof options.characterData === 'undefined' ? true : options.characterData
  1436. });
  1437. s.observers.push(observer);
  1438. }
  1439. s.initObservers = function () {
  1440. if (s.params.observeParents) {
  1441. var containerParents = s.container.parents();
  1442. for (var i = 0; i < containerParents.length; i++) {
  1443. initObserver(containerParents[i]);
  1444. }
  1445. }
  1446. // Observe container
  1447. initObserver(s.container[0], {childList: false});
  1448. // Observe wrapper
  1449. initObserver(s.wrapper[0], {attributes: false});
  1450. };
  1451. s.disconnectObservers = function () {
  1452. for (var i = 0; i < s.observers.length; i++) {
  1453. s.observers[i].disconnect();
  1454. }
  1455. s.observers = [];
  1456. };
  1457. /*=========================
  1458. Loop
  1459. ===========================*/
  1460. // Create looped slides
  1461. s.createLoop = function () {
  1462. // Remove duplicated slides
  1463. s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
  1464. var slides = s.wrapper.children('.' + s.params.slideClass);
  1465. s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);
  1466. s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;
  1467. if (s.loopedSlides > slides.length) {
  1468. s.loopedSlides = slides.length;
  1469. }
  1470. var prependSlides = [], appendSlides = [], i;
  1471. slides.each(function (index, el) {
  1472. var slide = $(this);
  1473. if (index < s.loopedSlides) appendSlides.push(el);
  1474. if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);
  1475. slide.attr('data-swiper-slide-index', index);
  1476. });
  1477. for (i = 0; i < appendSlides.length; i++) {
  1478. s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
  1479. }
  1480. for (i = prependSlides.length - 1; i >= 0; i--) {
  1481. s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
  1482. }
  1483. };
  1484. s.destroyLoop = function () {
  1485. s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
  1486. s.slides.removeAttr('data-swiper-slide-index');
  1487. };
  1488. s.fixLoop = function () {
  1489. var newIndex;
  1490. //Fix For Negative Oversliding
  1491. if (s.activeIndex < s.loopedSlides) {
  1492. newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;
  1493. newIndex = newIndex + s.loopedSlides;
  1494. s.slideTo(newIndex, 0, false, true);
  1495. }
  1496. //Fix For Positive Oversliding
  1497. else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {
  1498. newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;
  1499. newIndex = newIndex + s.loopedSlides;
  1500. s.slideTo(newIndex, 0, false, true);
  1501. }
  1502. };
  1503. /*=========================
  1504. Append/Prepend/Remove Slides
  1505. ===========================*/
  1506. s.appendSlide = function (slides) {
  1507. if (s.params.loop) {
  1508. s.destroyLoop();
  1509. }
  1510. if (typeof slides === 'object' && slides.length) {
  1511. for (var i = 0; i < slides.length; i++) {
  1512. if (slides[i]) s.wrapper.append(slides[i]);
  1513. }
  1514. }
  1515. else {
  1516. s.wrapper.append(slides);
  1517. }
  1518. if (s.params.loop) {
  1519. s.createLoop();
  1520. }
  1521. if (!(s.params.observer && s.support.observer)) {
  1522. s.update(true);
  1523. }
  1524. };
  1525. s.prependSlide = function (slides) {
  1526. if (s.params.loop) {
  1527. s.destroyLoop();
  1528. }
  1529. var newActiveIndex = s.activeIndex + 1;
  1530. if (typeof slides === 'object' && slides.length) {
  1531. for (var i = 0; i < slides.length; i++) {
  1532. if (slides[i]) s.wrapper.prepend(slides[i]);
  1533. }
  1534. newActiveIndex = s.activeIndex + slides.length;
  1535. }
  1536. else {
  1537. s.wrapper.prepend(slides);
  1538. }
  1539. if (s.params.loop) {
  1540. s.createLoop();
  1541. }
  1542. if (!(s.params.observer && s.support.observer)) {
  1543. s.update(true);
  1544. }
  1545. s.slideTo(newActiveIndex, 0, false);
  1546. };
  1547. s.removeSlide = function (slidesIndexes) {
  1548. if (s.params.loop) {
  1549. s.destroyLoop();
  1550. }
  1551. var newActiveIndex = s.activeIndex,
  1552. indexToRemove;
  1553. if (typeof slidesIndexes === 'object' && slidesIndexes.length) {
  1554. for (var i = 0; i < slidesIndexes.length; i++) {
  1555. indexToRemove = slidesIndexes[i];
  1556. if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
  1557. if (indexToRemove < newActiveIndex) newActiveIndex--;
  1558. }
  1559. newActiveIndex = Math.max(newActiveIndex, 0);
  1560. }
  1561. else {
  1562. indexToRemove = slidesIndexes;
  1563. if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
  1564. if (indexToRemove < newActiveIndex) newActiveIndex--;
  1565. newActiveIndex = Math.max(newActiveIndex, 0);
  1566. }
  1567. if (!(s.params.observer && s.support.observer)) {
  1568. s.update(true);
  1569. }
  1570. s.slideTo(newActiveIndex, 0, false);
  1571. };
  1572. s.removeAllSlides = function () {
  1573. var slidesIndexes = [];
  1574. for (var i = 0; i < s.slides.length; i++) {
  1575. slidesIndexes.push(i);
  1576. }
  1577. s.removeSlide(slidesIndexes);
  1578. };
  1579. /*=========================
  1580. Effects
  1581. ===========================*/
  1582. s.effects = {
  1583. fade: {
  1584. fadeIndex: null,
  1585. setTranslate: function () {
  1586. for (var i = 0; i < s.slides.length; i++) {
  1587. var slide = s.slides.eq(i);
  1588. var offset = slide[0].swiperSlideOffset;
  1589. var tx = -offset;
  1590. if (!s.params.virtualTranslate) tx = tx - s.translate;
  1591. var ty = 0;
  1592. if (!isH()) {
  1593. ty = tx;
  1594. tx = 0;
  1595. }
  1596. var slideOpacity = s.params.fade.crossFade ?
  1597. Math.max(1 - Math.abs(slide[0].progress), 0) :
  1598. 1 + Math.min(Math.max(slide[0].progress, -1), 0);
  1599. if (slideOpacity > 0 && slideOpacity < 1) {
  1600. s.effects.fade.fadeIndex = i;
  1601. }
  1602. slide
  1603. .css({
  1604. opacity: slideOpacity
  1605. })
  1606. .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');
  1607. }
  1608. },
  1609. setTransition: function (duration) {
  1610. s.slides.transition(duration);
  1611. if (s.params.virtualTranslate && duration !== 0) {
  1612. var fadeIndex = s.effects.fade.fadeIndex !== null ? s.effects.fade.fadeIndex : s.activeIndex;
  1613. s.slides.eq(fadeIndex).transitionEnd(function () {
  1614. var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];
  1615. for (var i = 0; i < triggerEvents.length; i++) {
  1616. s.wrapper.trigger(triggerEvents[i]);
  1617. }
  1618. });
  1619. }
  1620. }
  1621. },
  1622. cube: {
  1623. setTranslate: function () {
  1624. var wrapperRotate = 0, cubeShadow;
  1625. if (s.params.cube.shadow) {
  1626. if (isH()) {
  1627. cubeShadow = s.wrapper.find('.swiper-cube-shadow');
  1628. if (cubeShadow.length === 0) {
  1629. cubeShadow = $('<div class="swiper-cube-shadow"></div>');
  1630. s.wrapper.append(cubeShadow);
  1631. }
  1632. cubeShadow.css({height: s.width + 'px'});
  1633. }
  1634. else {
  1635. cubeShadow = s.container.find('.swiper-cube-shadow');
  1636. if (cubeShadow.length === 0) {
  1637. cubeShadow = $('<div class="swiper-cube-shadow"></div>');
  1638. s.container.append(cubeShadow);
  1639. }
  1640. }
  1641. }
  1642. for (var i = 0; i < s.slides.length; i++) {
  1643. var slide = s.slides.eq(i);
  1644. var slideAngle = i * 90;
  1645. var round = Math.floor(slideAngle / 360);
  1646. if (s.rtl) {
  1647. slideAngle = -slideAngle;
  1648. round = Math.floor(-slideAngle / 360);
  1649. }
  1650. var progress = Math.max(Math.min(slide[0].progress, 1), -1);
  1651. var tx = 0, ty = 0, tz = 0;
  1652. if (i % 4 === 0) {
  1653. tx = - round * 4 * s.size;
  1654. tz = 0;
  1655. }
  1656. else if ((i - 1) % 4 === 0) {
  1657. tx = 0;
  1658. tz = - round * 4 * s.size;
  1659. }
  1660. else if ((i - 2) % 4 === 0) {
  1661. tx = s.size + round * 4 * s.size;
  1662. tz = s.size;
  1663. }
  1664. else if ((i - 3) % 4 === 0) {
  1665. tx = - s.size;
  1666. tz = 3 * s.size + s.size * 4 * round;
  1667. }
  1668. if (s.rtl) {
  1669. tx = -tx;
  1670. }
  1671. if (!isH()) {
  1672. ty = tx;
  1673. tx = 0;
  1674. }
  1675. var transform = 'rotateX(' + (isH() ? 0 : -slideAngle) + 'deg) rotateY(' + (isH() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';
  1676. if (progress <= 1 && progress > -1) {
  1677. wrapperRotate = i * 90 + progress * 90;
  1678. if (s.rtl) wrapperRotate = -i * 90 - progress * 90;
  1679. }
  1680. slide.transform(transform);
  1681. if (s.params.cube.slideShadows) {
  1682. //Set shadows
  1683. var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
  1684. var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
  1685. if (shadowBefore.length === 0) {
  1686. shadowBefore = $('<div class="swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '"></div>');
  1687. slide.append(shadowBefore);
  1688. }
  1689. if (shadowAfter.length === 0) {
  1690. shadowAfter = $('<div class="swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '"></div>');
  1691. slide.append(shadowAfter);
  1692. }
  1693. if (shadowBefore.length) shadowBefore[0].style.opacity = -slide[0].progress;
  1694. if (shadowAfter.length) shadowAfter[0].style.opacity = slide[0].progress;
  1695. }
  1696. }
  1697. s.wrapper.css({
  1698. '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
  1699. '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
  1700. '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
  1701. 'transform-origin': '50% 50% -' + (s.size / 2) + 'px'
  1702. });
  1703. if (s.params.cube.shadow) {
  1704. if (isH()) {
  1705. 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) + ')');
  1706. }
  1707. else {
  1708. var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
  1709. var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
  1710. var scale1 = s.params.cube.shadowScale,
  1711. scale2 = s.params.cube.shadowScale / multiplier,
  1712. offset = s.params.cube.shadowOffset;
  1713. cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');
  1714. }
  1715. }
  1716. var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;
  1717. s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (isH() ? 0 : wrapperRotate) + 'deg) rotateY(' + (isH() ? -wrapperRotate : 0) + 'deg)');
  1718. },
  1719. setTransition: function (duration) {
  1720. s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
  1721. if (s.params.cube.shadow && !isH()) {
  1722. s.container.find('.swiper-cube-shadow').transition(duration);
  1723. }
  1724. }
  1725. },
  1726. coverflow: {
  1727. setTranslate: function () {
  1728. var transform = s.translate;
  1729. var center = isH() ? -transform + s.width / 2 : -transform + s.height / 2;
  1730. var rotate = isH() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;
  1731. var translate = s.params.coverflow.depth;
  1732. //Each slide offset from center
  1733. for (var i = 0, length = s.slides.length; i < length; i++) {
  1734. var slide = s.slides.eq(i);
  1735. var slideSize = s.slidesSizesGrid[i];
  1736. var slideOffset = slide[0].swiperSlideOffset;
  1737. var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;
  1738. var rotateY = isH() ? rotate * offsetMultiplier : 0;
  1739. var rotateX = isH() ? 0 : rotate * offsetMultiplier;
  1740. // var rotateZ = 0
  1741. var translateZ = -translate * Math.abs(offsetMultiplier);
  1742. var translateY = isH() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);
  1743. var translateX = isH() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;
  1744. //Fix for ultra small values
  1745. if (Math.abs(translateX) < 0.001) translateX = 0;
  1746. if (Math.abs(translateY) < 0.001) translateY = 0;
  1747. if (Math.abs(translateZ) < 0.001) translateZ = 0;
  1748. if (Math.abs(rotateY) < 0.001) rotateY = 0;
  1749. if (Math.abs(rotateX) < 0.001) rotateX = 0;
  1750. var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';
  1751. slide.transform(slideTransform);
  1752. slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
  1753. if (s.params.coverflow.slideShadows) {
  1754. //Set shadows
  1755. var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
  1756. var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
  1757. if (shadowBefore.length === 0) {
  1758. shadowBefore = $('<div class="swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '"></div>');
  1759. slide.append(shadowBefore);
  1760. }
  1761. if (shadowAfter.length === 0) {
  1762. shadowAfter = $('<div class="swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '"></div>');
  1763. slide.append(shadowAfter);
  1764. }
  1765. if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
  1766. if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;
  1767. }
  1768. }
  1769. //Set correct perspective for IE10
  1770. if (s.browser.ie) {
  1771. var ws = s.wrapper[0].style;
  1772. ws.perspectiveOrigin = center + 'px 50%';
  1773. }
  1774. },
  1775. setTransition: function (duration) {
  1776. s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
  1777. }
  1778. }
  1779. };
  1780. /*=========================
  1781. Images Lazy Loading
  1782. ===========================*/
  1783. s.lazy = {
  1784. initialImageLoaded: false,
  1785. loadImageInSlide: function (index) {
  1786. if (typeof index === 'undefined') return;
  1787. if (s.slides.length === 0) return;
  1788. var slide = s.slides.eq(index);
  1789. var img = slide.find('img.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');
  1790. if (img.length === 0) return;
  1791. img.each(function () {
  1792. var _img = $(this);
  1793. _img.addClass('swiper-lazy-loading');
  1794. var src = _img.attr('data-src');
  1795. s.loadImage(_img[0], src, false, function () {
  1796. _img.attr('src', src);
  1797. _img.removeAttr('data-src');
  1798. _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');
  1799. slide.find('.swiper-lazy-preloader, .preloader').remove();
  1800. s.emit('onLazyImageReady', s, slide[0], _img[0]);
  1801. });
  1802. s.emit('onLazyImageLoad', s, slide[0], _img[0]);
  1803. });
  1804. },
  1805. load: function () {
  1806. if (s.params.watchSlidesVisibility) {
  1807. s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {
  1808. s.lazy.loadImageInSlide($(this).index());
  1809. });
  1810. }
  1811. else {
  1812. if (s.params.slidesPerView > 1) {
  1813. for (var i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {
  1814. if (s.slides[i]) s.lazy.loadImageInSlide(i);
  1815. }
  1816. }
  1817. else {
  1818. s.lazy.loadImageInSlide(s.activeIndex);
  1819. }
  1820. }
  1821. if (s.params.lazyLoadingInPrevNext) {
  1822. var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);
  1823. if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());
  1824. var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);
  1825. if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());
  1826. }
  1827. },
  1828. onTransitionStart: function () {
  1829. if (s.params.lazyLoading) {
  1830. if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {
  1831. s.lazy.initialImageLoaded = true;
  1832. s.lazy.load();
  1833. }
  1834. }
  1835. },
  1836. onTransitionEnd: function () {
  1837. if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {
  1838. s.lazy.load();
  1839. }
  1840. }
  1841. };
  1842. /*=========================
  1843. Scrollbar
  1844. ===========================*/
  1845. s.scrollbar = {
  1846. set: function () {
  1847. if (!s.params.scrollbar) return;
  1848. var sb = s.scrollbar;
  1849. sb.track = $(s.params.scrollbar);
  1850. sb.drag = sb.track.find('.swiper-scrollbar-drag');
  1851. if (sb.drag.length === 0) {
  1852. sb.drag = $('<div class="swiper-scrollbar-drag"></div>');
  1853. sb.track.append(sb.drag);
  1854. }
  1855. sb.drag[0].style.width = '';
  1856. sb.drag[0].style.height = '';
  1857. sb.trackSize = isH() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;
  1858. sb.divider = s.size / s.virtualSize;
  1859. sb.moveDivider = sb.divider * (sb.trackSize / s.size);
  1860. sb.dragSize = sb.trackSize * sb.divider;
  1861. if (isH()) {
  1862. sb.drag[0].style.width = sb.dragSize + 'px';
  1863. }
  1864. else {
  1865. sb.drag[0].style.height = sb.dragSize + 'px';
  1866. }
  1867. if (sb.divider >= 1) {
  1868. sb.track[0].style.display = 'none';
  1869. }
  1870. else {
  1871. sb.track[0].style.display = '';
  1872. }
  1873. if (s.params.scrollbarHide) {
  1874. sb.track[0].style.opacity = 0;
  1875. }
  1876. },
  1877. setTranslate: function () {
  1878. if (!s.params.scrollbar) return;
  1879. var sb = s.scrollbar;
  1880. var newPos;
  1881. var newSize = sb.dragSize;
  1882. newPos = (sb.trackSize - sb.dragSize) * s.progress;
  1883. if (s.rtl && isH()) {
  1884. newPos = -newPos;
  1885. if (newPos > 0) {
  1886. newSize = sb.dragSize - newPos;
  1887. newPos = 0;
  1888. }
  1889. else if (-newPos + sb.dragSize > sb.trackSize) {
  1890. newSize = sb.trackSize + newPos;
  1891. }
  1892. }
  1893. else {
  1894. if (newPos < 0) {
  1895. newSize = sb.dragSize + newPos;
  1896. newPos = 0;
  1897. }
  1898. else if (newPos + sb.dragSize > sb.trackSize) {
  1899. newSize = sb.trackSize - newPos;
  1900. }
  1901. }
  1902. if (isH()) {
  1903. if (s.support.transforms3d) {
  1904. sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');
  1905. }
  1906. else {
  1907. sb.drag.transform('translateX(' + (newPos) + 'px)');
  1908. }
  1909. sb.drag[0].style.width = newSize + 'px';
  1910. }
  1911. else {
  1912. if (s.support.transforms3d) {
  1913. sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');
  1914. }
  1915. else {
  1916. sb.drag.transform('translateY(' + (newPos) + 'px)');
  1917. }
  1918. sb.drag[0].style.height = newSize + 'px';
  1919. }
  1920. if (s.params.scrollbarHide) {
  1921. clearTimeout(sb.timeout);
  1922. sb.track[0].style.opacity = 1;
  1923. sb.timeout = setTimeout(function () {
  1924. sb.track[0].style.opacity = 0;
  1925. sb.track.transition(400);
  1926. }, 1000);
  1927. }
  1928. },
  1929. setTransition: function (duration) {
  1930. if (!s.params.scrollbar) return;
  1931. s.scrollbar.drag.transition(duration);
  1932. }
  1933. };
  1934. /*=========================
  1935. Controller
  1936. ===========================*/
  1937. s.controller = {
  1938. setTranslate: function (translate, byController) {
  1939. var controlled = s.params.control;
  1940. var multiplier, controlledTranslate;
  1941. if (s.isArray(controlled)) {
  1942. for (var i = 0; i < controlled.length; i++) {
  1943. if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
  1944. translate = controlled[i].rtl && controlled[i].params.direction === 'horizontal' ? -s.translate : s.translate;
  1945. multiplier = (controlled[i].maxTranslate() - controlled[i].minTranslate()) / (s.maxTranslate() - s.minTranslate());
  1946. controlledTranslate = (translate - s.minTranslate()) * multiplier + controlled[i].minTranslate();
  1947. if (s.params.controlInverse) {
  1948. controlledTranslate = controlled[i].maxTranslate() - controlledTranslate;
  1949. }
  1950. controlled[i].updateProgress(controlledTranslate);
  1951. controlled[i].setWrapperTranslate(controlledTranslate, false, s);
  1952. controlled[i].updateActiveIndex();
  1953. }
  1954. }
  1955. }
  1956. else if (controlled instanceof Swiper && byController !== controlled) {
  1957. translate = controlled.rtl && controlled.params.direction === 'horizontal' ? -s.translate : s.translate;
  1958. multiplier = (controlled.maxTranslate() - controlled.minTranslate()) / (s.maxTranslate() - s.minTranslate());
  1959. controlledTranslate = (translate - s.minTranslate()) * multiplier + controlled.minTranslate();
  1960. if (s.params.controlInverse) {
  1961. controlledTranslate = controlled.maxTranslate() - controlledTranslate;
  1962. }
  1963. controlled.updateProgress(controlledTranslate);
  1964. controlled.setWrapperTranslate(controlledTranslate, false, s);
  1965. controlled.updateActiveIndex();
  1966. }
  1967. },
  1968. setTransition: function (duration, byController) {
  1969. var controlled = s.params.control;
  1970. if (s.isArray(controlled)) {
  1971. for (var i = 0; i < controlled.length; i++) {
  1972. if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
  1973. controlled[i].setWrapperTransition(duration, s);
  1974. }
  1975. }
  1976. }
  1977. else if (controlled instanceof Swiper && byController !== controlled) {
  1978. controlled.setWrapperTransition(duration, s);
  1979. }
  1980. }
  1981. };
  1982. /*=========================
  1983. Parallax
  1984. ===========================*/
  1985. function setParallaxTransform(el, progress) {
  1986. el = $(el);
  1987. var p, pX, pY;
  1988. p = el.attr('data-swiper-parallax') || '0';
  1989. pX = el.attr('data-swiper-parallax-x');
  1990. pY = el.attr('data-swiper-parallax-y');
  1991. if (pX || pY) {
  1992. pX = pX || '0';
  1993. pY = pY || '0';
  1994. }
  1995. else {
  1996. if (isH()) {
  1997. pX = p;
  1998. pY = '0';
  1999. }
  2000. else {
  2001. pY = p;
  2002. pX = '0';
  2003. }
  2004. }
  2005. if ((pX).indexOf('%') >= 0) {
  2006. pX = parseInt(pX, 10) * progress + '%';
  2007. }
  2008. else {
  2009. pX = pX * progress + 'px' ;
  2010. }
  2011. if ((pY).indexOf('%') >= 0) {
  2012. pY = parseInt(pY, 10) * progress + '%';
  2013. }
  2014. else {
  2015. pY = pY * progress + 'px' ;
  2016. }
  2017. el.transform('translate3d(' + pX + ', ' + pY + ',0px)');
  2018. }
  2019. s.parallax = {
  2020. setTranslate: function () {
  2021. s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
  2022. setParallaxTransform(this, s.progress);
  2023. });
  2024. s.slides.each(function () {
  2025. var slide = $(this);
  2026. slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {
  2027. var progress = Math.min(Math.max(slide[0].progress, -1), 1);
  2028. setParallaxTransform(this, progress);
  2029. });
  2030. });
  2031. },
  2032. setTransition: function (duration) {
  2033. if (typeof duration === 'undefined') duration = s.params.speed;
  2034. s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
  2035. var el = $(this);
  2036. var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;
  2037. if (duration === 0) parallaxDuration = 0;
  2038. el.transition(parallaxDuration);
  2039. });
  2040. }
  2041. };
  2042. /*=========================
  2043. Plugins API. Collect all and init all plugins
  2044. ===========================*/
  2045. s._plugins = [];
  2046. for (var plugin in s.plugins) {
  2047. if(s.plugins.hasOwnProperty(plugin)){
  2048. var p = s.plugins[plugin](s, s.params[plugin]);
  2049. if (p) s._plugins.push(p);
  2050. }
  2051. }
  2052. // Method to call all plugins event/method
  2053. s.callPlugins = function (eventName) {
  2054. for (var i = 0; i < s._plugins.length; i++) {
  2055. if (eventName in s._plugins[i]) {
  2056. s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
  2057. }
  2058. }
  2059. };
  2060. /*=========================
  2061. Events/Callbacks/Plugins Emitter
  2062. ===========================*/
  2063. function normalizeEventName (eventName) {
  2064. if (eventName.indexOf('on') !== 0) {
  2065. if (eventName[0] !== eventName[0].toUpperCase()) {
  2066. eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);
  2067. }
  2068. else {
  2069. eventName = 'on' + eventName;
  2070. }
  2071. }
  2072. return eventName;
  2073. }
  2074. s.emitterEventListeners = {
  2075. };
  2076. s.emit = function (eventName) {
  2077. // Trigger callbacks
  2078. if (s.params[eventName]) {
  2079. s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
  2080. }
  2081. var i;
  2082. // 图片浏览器点击关闭后,swiper也关闭了,但会执行到此处
  2083. if (!s) return;
  2084. // Trigger events
  2085. if (s.emitterEventListeners[eventName]) {
  2086. for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
  2087. s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
  2088. }
  2089. }
  2090. // Trigger plugins
  2091. if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
  2092. };
  2093. s.on = function (eventName, handler) {
  2094. eventName = normalizeEventName(eventName);
  2095. if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];
  2096. s.emitterEventListeners[eventName].push(handler);
  2097. return s;
  2098. };
  2099. s.off = function (eventName, handler) {
  2100. var i;
  2101. eventName = normalizeEventName(eventName);
  2102. if (typeof handler === 'undefined') {
  2103. // Remove all handlers for such event
  2104. s.emitterEventListeners[eventName] = [];
  2105. return s;
  2106. }
  2107. if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;
  2108. for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
  2109. if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);
  2110. }
  2111. return s;
  2112. };
  2113. s.once = function (eventName, handler) {
  2114. eventName = normalizeEventName(eventName);
  2115. var _handler = function () {
  2116. handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
  2117. s.off(eventName, _handler);
  2118. };
  2119. s.on(eventName, _handler);
  2120. return s;
  2121. };
  2122. // Accessibility tools
  2123. s.a11y = {
  2124. makeFocusable: function ($el) {
  2125. $el[0].tabIndex = '0';
  2126. return $el;
  2127. },
  2128. addRole: function ($el, role) {
  2129. $el.attr('role', role);
  2130. return $el;
  2131. },
  2132. addLabel: function ($el, label) {
  2133. $el.attr('aria-label', label);
  2134. return $el;
  2135. },
  2136. disable: function ($el) {
  2137. $el.attr('aria-disabled', true);
  2138. return $el;
  2139. },
  2140. enable: function ($el) {
  2141. $el.attr('aria-disabled', false);
  2142. return $el;
  2143. },
  2144. onEnterKey: function (event) {
  2145. if (event.keyCode !== 13) return;
  2146. if ($(event.target).is(s.params.nextButton)) {
  2147. s.onClickNext(event);
  2148. if (s.isEnd) {
  2149. s.a11y.notify(s.params.lastSlideMsg);
  2150. }
  2151. else {
  2152. s.a11y.notify(s.params.nextSlideMsg);
  2153. }
  2154. }
  2155. else if ($(event.target).is(s.params.prevButton)) {
  2156. s.onClickPrev(event);
  2157. if (s.isBeginning) {
  2158. s.a11y.notify(s.params.firstSlideMsg);
  2159. }
  2160. else {
  2161. s.a11y.notify(s.params.prevSlideMsg);
  2162. }
  2163. }
  2164. },
  2165. liveRegion: $('<span class="swiper-notification" aria-live="assertive" aria-atomic="true"></span>'),
  2166. notify: function (message) {
  2167. var notification = s.a11y.liveRegion;
  2168. if (notification.length === 0) return;
  2169. notification.html('');
  2170. notification.html(message);
  2171. },
  2172. init: function () {
  2173. // Setup accessibility
  2174. if (s.params.nextButton) {
  2175. var nextButton = $(s.params.nextButton);
  2176. s.a11y.makeFocusable(nextButton);
  2177. s.a11y.addRole(nextButton, 'button');
  2178. s.a11y.addLabel(nextButton, s.params.nextSlideMsg);
  2179. }
  2180. if (s.params.prevButton) {
  2181. var prevButton = $(s.params.prevButton);
  2182. s.a11y.makeFocusable(prevButton);
  2183. s.a11y.addRole(prevButton, 'button');
  2184. s.a11y.addLabel(prevButton, s.params.prevSlideMsg);
  2185. }
  2186. $(s.container).append(s.a11y.liveRegion);
  2187. },
  2188. destroy: function () {
  2189. if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();
  2190. }
  2191. };
  2192. /*=========================
  2193. Init/Destroy
  2194. ===========================*/
  2195. s.init = function () {
  2196. if (s.params.loop) s.createLoop();
  2197. s.updateContainerSize();
  2198. s.updateSlidesSize();
  2199. s.updatePagination();
  2200. if (s.params.scrollbar && s.scrollbar) {
  2201. s.scrollbar.set();
  2202. }
  2203. if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
  2204. if (!s.params.loop) s.updateProgress();
  2205. s.effects[s.params.effect].setTranslate();
  2206. }
  2207. if (s.params.loop) {
  2208. s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);
  2209. }
  2210. else {
  2211. s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);
  2212. if (s.params.initialSlide === 0) {
  2213. if (s.parallax && s.params.parallax) s.parallax.setTranslate();
  2214. if (s.lazy && s.params.lazyLoading) s.lazy.load();
  2215. }
  2216. }
  2217. s.attachEvents();
  2218. if (s.params.observer && s.support.observer) {
  2219. s.initObservers();
  2220. }
  2221. if (s.params.preloadImages && !s.params.lazyLoading) {
  2222. s.preloadImages();
  2223. }
  2224. if (s.params.autoplay) {
  2225. s.startAutoplay();
  2226. }
  2227. if (s.params.keyboardControl) {
  2228. if (s.enableKeyboardControl) s.enableKeyboardControl();
  2229. }
  2230. if (s.params.mousewheelControl) {
  2231. if (s.enableMousewheelControl) s.enableMousewheelControl();
  2232. }
  2233. if (s.params.hashnav) {
  2234. if (s.hashnav) s.hashnav.init();
  2235. }
  2236. if (s.params.a11y && s.a11y) s.a11y.init();
  2237. s.emit('onInit', s);
  2238. };
  2239. // Cleanup dynamic styles
  2240. s.cleanupStyles = function () {
  2241. // Container
  2242. s.container.removeClass(s.classNames.join(' ')).removeAttr('style');
  2243. // Wrapper
  2244. s.wrapper.removeAttr('style');
  2245. // Slides
  2246. if (s.slides && s.slides.length) {
  2247. s.slides
  2248. .removeClass([
  2249. s.params.slideVisibleClass,
  2250. s.params.slideActiveClass,
  2251. s.params.slideNextClass,
  2252. s.params.slidePrevClass
  2253. ].join(' '))
  2254. .removeAttr('style')
  2255. .removeAttr('data-swiper-column')
  2256. .removeAttr('data-swiper-row');
  2257. }
  2258. // Pagination/Bullets
  2259. if (s.paginationContainer && s.paginationContainer.length) {
  2260. s.paginationContainer.removeClass(s.params.paginationHiddenClass);
  2261. }
  2262. if (s.bullets && s.bullets.length) {
  2263. s.bullets.removeClass(s.params.bulletActiveClass);
  2264. }
  2265. // Buttons
  2266. if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);
  2267. if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);
  2268. // Scrollbar
  2269. if (s.params.scrollbar && s.scrollbar) {
  2270. if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');
  2271. if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');
  2272. }
  2273. };
  2274. // Destroy
  2275. s.destroy = function (deleteInstance, cleanupStyles) {
  2276. // Detach evebts
  2277. s.detachEvents();
  2278. // Stop autoplay
  2279. s.stopAutoplay();
  2280. // Destroy loop
  2281. if (s.params.loop) {
  2282. s.destroyLoop();
  2283. }
  2284. // Cleanup styles
  2285. if (cleanupStyles) {
  2286. s.cleanupStyles();
  2287. }
  2288. // Disconnect observer
  2289. s.disconnectObservers();
  2290. // Disable keyboard/mousewheel
  2291. if (s.params.keyboardControl) {
  2292. if (s.disableKeyboardControl) s.disableKeyboardControl();
  2293. }
  2294. if (s.params.mousewheelControl) {
  2295. if (s.disableMousewheelControl) s.disableMousewheelControl();
  2296. }
  2297. // Disable a11y
  2298. if (s.params.a11y && s.a11y) s.a11y.destroy();
  2299. // Destroy callback
  2300. s.emit('onDestroy');
  2301. // Delete instance
  2302. if (deleteInstance !== false) s = null;
  2303. };
  2304. s.init();
  2305. // Return swiper instance
  2306. return s;
  2307. };
  2308. /*==================================================
  2309. Prototype
  2310. ====================================================*/
  2311. Swiper.prototype = {
  2312. defaults: {
  2313. direction: 'horizontal',
  2314. touchEventsTarget: 'container',
  2315. initialSlide: 0,
  2316. speed: 300,
  2317. // autoplay
  2318. autoplay: false,
  2319. autoplayDisableOnInteraction: true,
  2320. // Free mode
  2321. freeMode: false,
  2322. freeModeMomentum: true,
  2323. freeModeMomentumRatio: 1,
  2324. freeModeMomentumBounce: true,
  2325. freeModeMomentumBounceRatio: 1,
  2326. // Set wrapper width
  2327. setWrapperSize: false,
  2328. // Virtual Translate
  2329. virtualTranslate: false,
  2330. // Effects
  2331. effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow'
  2332. coverflow: {
  2333. rotate: 50,
  2334. stretch: 0,
  2335. depth: 100,
  2336. modifier: 1,
  2337. slideShadows : true
  2338. },
  2339. cube: {
  2340. slideShadows: true,
  2341. shadow: true,
  2342. shadowOffset: 20,
  2343. shadowScale: 0.94
  2344. },
  2345. fade: {
  2346. crossFade: false
  2347. },
  2348. // Parallax
  2349. parallax: false,
  2350. // Scrollbar
  2351. scrollbar: null,
  2352. scrollbarHide: true,
  2353. // Keyboard Mousewheel
  2354. keyboardControl: false,
  2355. mousewheelControl: false,
  2356. mousewheelForceToAxis: false,
  2357. // Hash Navigation
  2358. hashnav: false,
  2359. // Slides grid
  2360. spaceBetween: 0,
  2361. slidesPerView: 1,
  2362. slidesPerColumn: 1,
  2363. slidesPerColumnFill: 'column',
  2364. slidesPerGroup: 1,
  2365. centeredSlides: false,
  2366. // Touches
  2367. touchRatio: 1,
  2368. touchAngle: 45,
  2369. simulateTouch: true,
  2370. shortSwipes: true,
  2371. longSwipes: true,
  2372. longSwipesRatio: 0.5,
  2373. longSwipesMs: 300,
  2374. followFinger: true,
  2375. onlyExternal: false,
  2376. threshold: 0,
  2377. touchMoveStopPropagation: true,
  2378. // Pagination
  2379. pagination: null,
  2380. paginationClickable: false,
  2381. paginationHide: false,
  2382. paginationBulletRender: null,
  2383. // Resistance
  2384. resistance: true,
  2385. resistanceRatio: 0.85,
  2386. // Next/prev buttons
  2387. nextButton: null,
  2388. prevButton: null,
  2389. // Progress
  2390. watchSlidesProgress: false,
  2391. watchSlidesVisibility: false,
  2392. // Cursor
  2393. grabCursor: false,
  2394. // Clicks
  2395. preventClicks: true,
  2396. preventClicksPropagation: true,
  2397. slideToClickedSlide: false,
  2398. // Lazy Loading
  2399. lazyLoading: false,
  2400. lazyLoadingInPrevNext: false,
  2401. lazyLoadingOnTransitionStart: false,
  2402. // Images
  2403. preloadImages: true,
  2404. updateOnImagesReady: true,
  2405. // loop
  2406. loop: false,
  2407. loopAdditionalSlides: 0,
  2408. loopedSlides: null,
  2409. // Control
  2410. control: undefined,
  2411. controlInverse: false,
  2412. // Swiping/no swiping
  2413. allowSwipeToPrev: true,
  2414. allowSwipeToNext: true,
  2415. swipeHandler: null, //'.swipe-handler',
  2416. noSwiping: true,
  2417. noSwipingClass: 'swiper-no-swiping',
  2418. // NS
  2419. slideClass: 'swiper-slide',
  2420. slideActiveClass: 'swiper-slide-active',
  2421. slideVisibleClass: 'swiper-slide-visible',
  2422. slideDuplicateClass: 'swiper-slide-duplicate',
  2423. slideNextClass: 'swiper-slide-next',
  2424. slidePrevClass: 'swiper-slide-prev',
  2425. wrapperClass: 'swiper-wrapper',
  2426. bulletClass: 'swiper-pagination-bullet',
  2427. bulletActiveClass: 'swiper-pagination-bullet-active',
  2428. buttonDisabledClass: 'swiper-button-disabled',
  2429. paginationHiddenClass: 'swiper-pagination-hidden',
  2430. // Observer
  2431. observer: false,
  2432. observeParents: false,
  2433. // Accessibility
  2434. a11y: false,
  2435. prevSlideMessage: 'Previous slide',
  2436. nextSlideMessage: 'Next slide',
  2437. firstSlideMessage: 'This is the first slide',
  2438. lastSlideMessage: 'This is the last slide',
  2439. // Callbacks
  2440. runCallbacksOnInit: true,
  2441. /*
  2442. Callbacks:
  2443. onInit: function (swiper)
  2444. onDestroy: function (swiper)
  2445. onClick: function (swiper, e)
  2446. onTap: function (swiper, e)
  2447. onDoubleTap: function (swiper, e)
  2448. onSliderMove: function (swiper, e)
  2449. onSlideChangeStart: function (swiper)
  2450. onSlideChangeEnd: function (swiper)
  2451. onTransitionStart: function (swiper)
  2452. onTransitionEnd: function (swiper)
  2453. onImagesReady: function (swiper)
  2454. onProgress: function (swiper, progress)
  2455. onTouchStart: function (swiper, e)
  2456. onTouchMove: function (swiper, e)
  2457. onTouchMoveOpposite: function (swiper, e)
  2458. onTouchEnd: function (swiper, e)
  2459. onReachBeginning: function (swiper)
  2460. onReachEnd: function (swiper)
  2461. onSetTransition: function (swiper, duration)
  2462. onSetTranslate: function (swiper, translate)
  2463. onAutoplayStart: function (swiper)
  2464. onAutoplayStop: function (swiper),
  2465. onLazyImageLoad: function (swiper, slide, image)
  2466. onLazyImageReady: function (swiper, slide, image)
  2467. */
  2468. },
  2469. isSafari: (function () {
  2470. var ua = navigator.userAgent.toLowerCase();
  2471. return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);
  2472. })(),
  2473. isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),
  2474. isArray: function (arr) {
  2475. return Object.prototype.toString.apply(arr) === '[object Array]';
  2476. },
  2477. /*==================================================
  2478. Browser
  2479. ====================================================*/
  2480. browser: {
  2481. ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
  2482. ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1),
  2483. },
  2484. /*==================================================
  2485. Devices
  2486. ====================================================*/
  2487. device: (function () {
  2488. var ua = navigator.userAgent;
  2489. var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
  2490. var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
  2491. var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
  2492. return {
  2493. ios: ipad || iphone || ipad,
  2494. android: android
  2495. };
  2496. })(),
  2497. /*==================================================
  2498. Feature Detection
  2499. ====================================================*/
  2500. support: {
  2501. touch : (window.Modernizr && Modernizr.touch === true) || (function () {
  2502. return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
  2503. })(),
  2504. transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {
  2505. var div = document.createElement('div').style;
  2506. return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);
  2507. })(),
  2508. flexbox: (function () {
  2509. var div = document.createElement('div').style;
  2510. var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');
  2511. for (var i = 0; i < styles.length; i++) {
  2512. if (styles[i] in div) return true;
  2513. }
  2514. })(),
  2515. observer: (function () {
  2516. return ('MutationObserver' in window || 'WebkitMutationObserver' in window);
  2517. })()
  2518. },
  2519. /*==================================================
  2520. Plugins
  2521. ====================================================*/
  2522. plugins: {}
  2523. };
  2524. $.Swiper = Swiper;
  2525. }(Zepto);
  2526. +function($){
  2527. 'use strict';
  2528. $.Swiper.prototype.defaults.pagination = '.page-current .swiper-pagination';
  2529. $.swiper = function (container, params) {
  2530. return new $.Swiper(container, params);
  2531. };
  2532. $.fn.swiper = function (params) {
  2533. return new $.Swiper(this, params);
  2534. };
  2535. $.initSwiper = function (pageContainer) {
  2536. var page = $(pageContainer || document.body);
  2537. var swipers = page.find('.swiper-container');
  2538. if (swipers.length === 0) return;
  2539. function destroySwiperOnRemove(slider) {
  2540. function destroySwiper() {
  2541. slider.destroy();
  2542. page.off('pageBeforeRemove', destroySwiper);
  2543. }
  2544. page.on('pageBeforeRemove', destroySwiper);
  2545. }
  2546. for (var i = 0; i < swipers.length; i++) {
  2547. var swiper = swipers.eq(i);
  2548. var params;
  2549. if (swiper.data('swiper')) {
  2550. swiper.data("swiper").update(true);
  2551. continue;
  2552. }
  2553. else {
  2554. params = swiper.dataset();
  2555. }
  2556. var _slider = $.swiper(swiper[0], params);
  2557. destroySwiperOnRemove(_slider);
  2558. }
  2559. };
  2560. $.reinitSwiper = function (pageContainer) {
  2561. var page = $(pageContainer || '.page-current');
  2562. var sliders = page.find('.swiper-container');
  2563. if (sliders.length === 0) return;
  2564. for (var i = 0; i < sliders.length; i++) {
  2565. var sliderInstance = sliders[0].swiper;
  2566. if (sliderInstance) {
  2567. sliderInstance.update(true);
  2568. }
  2569. }
  2570. };
  2571. }(Zepto);
  2572. /*======================================================
  2573. ************ Photo Browser ************
  2574. ======================================================*/
  2575. +function($){
  2576. 'use strict';
  2577. var PhotoBrowser = function (params) {
  2578. var pb = this, i;
  2579. var defaults = this.defaults;
  2580. params = params || {};
  2581. for (var def in defaults) {
  2582. if (typeof params[def] === 'undefined') {
  2583. params[def] = defaults[def];
  2584. }
  2585. }
  2586. pb.params = params;
  2587. var navbarTemplate = pb.params.navbarTemplate ||
  2588. '<header class="bar bar-nav">' +
  2589. '<a class="icon icon-left pull-left photo-browser-close-link' + (pb.params.type === 'popup' ? " close-popup" : "") + '"></a>' +
  2590. '<h1 class="title"><div class="center sliding"><span class="photo-browser-current"></span> <span class="photo-browser-of">' + pb.params.ofText + '</span> <span class="photo-browser-total"></span></div></h1>' +
  2591. '</header>';
  2592. var toolbarTemplate = pb.params.toolbarTemplate ||
  2593. '<nav class="bar bar-tab">' +
  2594. '<a class="tab-item photo-browser-prev" href="#">' +
  2595. '<i class="icon icon-prev"></i>' +
  2596. '</a>' +
  2597. '<a class="tab-item photo-browser-next" href="#">' +
  2598. '<i class="icon icon-next"></i>' +
  2599. '</a>' +
  2600. '</nav>';
  2601. var template = pb.params.template ||
  2602. '<div class="photo-browser photo-browser-' + pb.params.theme + '">' +
  2603. '{{navbar}}' +
  2604. '{{toolbar}}' +
  2605. '<div data-page="photo-browser-slides" class="content">' +
  2606. '{{captions}}' +
  2607. '<div class="photo-browser-swiper-container swiper-container">' +
  2608. '<div class="photo-browser-swiper-wrapper swiper-wrapper">' +
  2609. '{{photos}}' +
  2610. '</div>' +
  2611. '</div>' +
  2612. '</div>' +
  2613. '</div>';
  2614. var photoTemplate = !pb.params.lazyLoading ?
  2615. (pb.params.photoTemplate || '<div class="photo-browser-slide swiper-slide"><span class="photo-browser-zoom-container"><img src="{{url}}"></span></div>') :
  2616. (pb.params.photoLazyTemplate || '<div class="photo-browser-slide photo-browser-slide-lazy swiper-slide"><div class="preloader' + (pb.params.theme === 'dark' ? ' preloader-white' : '') + '"></div><span class="photo-browser-zoom-container"><img data-src="{{url}}" class="swiper-lazy"></span></div>');
  2617. var captionsTheme = pb.params.captionsTheme || pb.params.theme;
  2618. var captionsTemplate = pb.params.captionsTemplate || '<div class="photo-browser-captions photo-browser-captions-' + captionsTheme + '">{{captions}}</div>';
  2619. var captionTemplate = pb.params.captionTemplate || '<div class="photo-browser-caption" data-caption-index="{{captionIndex}}">{{caption}}</div>';
  2620. var objectTemplate = pb.params.objectTemplate || '<div class="photo-browser-slide photo-browser-object-slide swiper-slide">{{html}}</div>';
  2621. var photosHtml = '';
  2622. var captionsHtml = '';
  2623. for (i = 0; i < pb.params.photos.length; i ++) {
  2624. var photo = pb.params.photos[i];
  2625. var thisTemplate = '';
  2626. //check if photo is a string or string-like object, for backwards compatibility
  2627. if (typeof(photo) === 'string' || photo instanceof String) {
  2628. //check if "photo" is html object
  2629. if (photo.indexOf('<') >= 0 || photo.indexOf('>') >= 0) {
  2630. thisTemplate = objectTemplate.replace(/{{html}}/g, photo);
  2631. } else {
  2632. thisTemplate = photoTemplate.replace(/{{url}}/g, photo);
  2633. }
  2634. //photo is a string, thus has no caption, so remove the caption template placeholder
  2635. //otherwise check if photo is an object with a url property
  2636. } else if (typeof(photo) === 'object') {
  2637. //check if "photo" is html object
  2638. if (photo.hasOwnProperty('html') && photo.html.length > 0) {
  2639. thisTemplate = objectTemplate.replace(/{{html}}/g, photo.html);
  2640. } else if (photo.hasOwnProperty('url') && photo.url.length > 0) {
  2641. thisTemplate = photoTemplate.replace(/{{url}}/g, photo.url);
  2642. }
  2643. //check if photo has a caption
  2644. if (photo.hasOwnProperty('caption') && photo.caption.length > 0) {
  2645. captionsHtml += captionTemplate.replace(/{{caption}}/g, photo.caption).replace(/{{captionIndex}}/g, i);
  2646. } else {
  2647. thisTemplate = thisTemplate.replace(/{{caption}}/g, '');
  2648. }
  2649. }
  2650. photosHtml += thisTemplate;
  2651. }
  2652. var htmlTemplate = template
  2653. .replace('{{navbar}}', (pb.params.navbar ? navbarTemplate : ''))
  2654. .replace('{{noNavbar}}', (pb.params.navbar ? '' : 'no-navbar'))
  2655. .replace('{{photos}}', photosHtml)
  2656. .replace('{{captions}}', captionsTemplate.replace(/{{captions}}/g, captionsHtml))
  2657. .replace('{{toolbar}}', (pb.params.toolbar ? toolbarTemplate : ''));
  2658. pb.activeIndex = pb.params.initialSlide;
  2659. pb.openIndex = pb.activeIndex;
  2660. pb.opened = false;
  2661. pb.open = function (index) {
  2662. if (typeof index === 'undefined') index = pb.activeIndex;
  2663. index = parseInt(index, 10);
  2664. if (pb.opened && pb.swiper) {
  2665. pb.swiper.slideTo(index);
  2666. return;
  2667. }
  2668. pb.opened = true;
  2669. pb.openIndex = index;
  2670. // pb.initialLazyLoaded = false;
  2671. if (pb.params.type === 'standalone') {
  2672. $(pb.params.container).append(htmlTemplate);
  2673. }
  2674. if (pb.params.type === 'popup') {
  2675. pb.popup = $.popup('<div class="popup photo-browser-popup">' + htmlTemplate + '</div>');
  2676. $(pb.popup).on('closed', pb.onPopupClose);
  2677. }
  2678. if (pb.params.type === 'page') {
  2679. $(document).on('pageBeforeInit', pb.onPageBeforeInit);
  2680. $(document).on('pageBeforeRemove', pb.onPageBeforeRemove);
  2681. if (!pb.params.view) pb.params.view = $.mainView;
  2682. pb.params.view.loadContent(htmlTemplate);
  2683. return;
  2684. }
  2685. pb.layout(pb.openIndex);
  2686. if (pb.params.onOpen) {
  2687. pb.params.onOpen(pb);
  2688. }
  2689. };
  2690. pb.close = function () {
  2691. pb.opened = false;
  2692. if (!pb.swiperContainer || pb.swiperContainer.length === 0) {
  2693. return;
  2694. }
  2695. if (pb.params.onClose) {
  2696. pb.params.onClose(pb);
  2697. }
  2698. // Detach events
  2699. pb.attachEvents(true);
  2700. // Delete from DOM
  2701. if (pb.params.type === 'standalone') {
  2702. pb.container.removeClass('photo-browser-in').addClass('photo-browser-out').animationEnd(function () {
  2703. pb.container.remove();
  2704. });
  2705. }
  2706. // Destroy slider
  2707. pb.swiper.destroy();
  2708. // Delete references
  2709. pb.swiper = pb.swiperContainer = pb.swiperWrapper = pb.slides = gestureSlide = gestureImg = gestureImgWrap = undefined;
  2710. };
  2711. pb.onPopupClose = function () {
  2712. pb.close();
  2713. $(pb.popup).off('pageBeforeInit', pb.onPopupClose);
  2714. };
  2715. pb.onPageBeforeInit = function (e) {
  2716. if (e.detail.page.name === 'photo-browser-slides') {
  2717. pb.layout(pb.openIndex);
  2718. }
  2719. $(document).off('pageBeforeInit', pb.onPageBeforeInit);
  2720. };
  2721. pb.onPageBeforeRemove = function (e) {
  2722. if (e.detail.page.name === 'photo-browser-slides') {
  2723. pb.close();
  2724. }
  2725. $(document).off('pageBeforeRemove', pb.onPageBeforeRemove);
  2726. };
  2727. pb.onSliderTransitionStart = function (swiper) {
  2728. pb.activeIndex = swiper.activeIndex;
  2729. var current = swiper.activeIndex + 1;
  2730. var total = swiper.slides.length;
  2731. if (pb.params.loop) {
  2732. total = total - 2;
  2733. current = current - swiper.loopedSlides;
  2734. if (current < 1) current = total + current;
  2735. if (current > total) current = current - total;
  2736. }
  2737. pb.container.find('.photo-browser-current').text(current);
  2738. pb.container.find('.photo-browser-total').text(total);
  2739. $('.photo-browser-prev, .photo-browser-next').removeClass('photo-browser-link-inactive');
  2740. if (swiper.isBeginning && !pb.params.loop) {
  2741. $('.photo-browser-prev').addClass('photo-browser-link-inactive');
  2742. }
  2743. if (swiper.isEnd && !pb.params.loop) {
  2744. $('.photo-browser-next').addClass('photo-browser-link-inactive');
  2745. }
  2746. // Update captions
  2747. if (pb.captions.length > 0) {
  2748. pb.captionsContainer.find('.photo-browser-caption-active').removeClass('photo-browser-caption-active');
  2749. var captionIndex = pb.params.loop ? swiper.slides.eq(swiper.activeIndex).attr('data-swiper-slide-index') : pb.activeIndex;
  2750. pb.captionsContainer.find('[data-caption-index="' + captionIndex + '"]').addClass('photo-browser-caption-active');
  2751. }
  2752. // Stop Video
  2753. var previousSlideVideo = swiper.slides.eq(swiper.previousIndex).find('video');
  2754. if (previousSlideVideo.length > 0) {
  2755. if ('pause' in previousSlideVideo[0]) previousSlideVideo[0].pause();
  2756. }
  2757. // Callback
  2758. if (pb.params.onSlideChangeStart) pb.params.onSlideChangeStart(swiper);
  2759. };
  2760. pb.onSliderTransitionEnd = function (swiper) {
  2761. // Reset zoom
  2762. if (pb.params.zoom && gestureSlide && swiper.previousIndex !== swiper.activeIndex) {
  2763. gestureImg.transform('translate3d(0,0,0) scale(1)');
  2764. gestureImgWrap.transform('translate3d(0,0,0)');
  2765. gestureSlide = gestureImg = gestureImgWrap = undefined;
  2766. scale = currentScale = 1;
  2767. }
  2768. if (pb.params.onSlideChangeEnd) pb.params.onSlideChangeEnd(swiper);
  2769. };
  2770. pb.layout = function (index) {
  2771. if (pb.params.type === 'page') {
  2772. pb.container = $('.photo-browser-swiper-container').parents('.view');
  2773. }
  2774. else {
  2775. pb.container = $('.photo-browser');
  2776. }
  2777. if (pb.params.type === 'standalone') {
  2778. pb.container.addClass('photo-browser-in');
  2779. // $.sizeNavbars(pb.container);
  2780. }
  2781. pb.swiperContainer = pb.container.find('.photo-browser-swiper-container');
  2782. pb.swiperWrapper = pb.container.find('.photo-browser-swiper-wrapper');
  2783. pb.slides = pb.container.find('.photo-browser-slide');
  2784. pb.captionsContainer = pb.container.find('.photo-browser-captions');
  2785. pb.captions = pb.container.find('.photo-browser-caption');
  2786. var sliderSettings = {
  2787. nextButton: pb.params.nextButton || '.photo-browser-next',
  2788. prevButton: pb.params.prevButton || '.photo-browser-prev',
  2789. indexButton: pb.params.indexButton,
  2790. initialSlide: index,
  2791. spaceBetween: pb.params.spaceBetween,
  2792. speed: pb.params.speed,
  2793. loop: pb.params.loop,
  2794. lazyLoading: pb.params.lazyLoading,
  2795. lazyLoadingInPrevNext: pb.params.lazyLoadingInPrevNext,
  2796. lazyLoadingOnTransitionStart: pb.params.lazyLoadingOnTransitionStart,
  2797. preloadImages: pb.params.lazyLoading ? false : true,
  2798. onTap: function (swiper, e) {
  2799. if (pb.params.onTap) pb.params.onTap(swiper, e);
  2800. },
  2801. onClick: function (swiper, e) {
  2802. if (pb.params.exposition) pb.toggleExposition();
  2803. if (pb.params.onClick) pb.params.onClick(swiper, e);
  2804. },
  2805. onDoubleTap: function (swiper, e) {
  2806. pb.toggleZoom($(e.target).parents('.photo-browser-slide'));
  2807. if (pb.params.onDoubleTap) pb.params.onDoubleTap(swiper, e);
  2808. },
  2809. onTransitionStart: function (swiper) {
  2810. pb.onSliderTransitionStart(swiper);
  2811. },
  2812. onTransitionEnd: function (swiper) {
  2813. pb.onSliderTransitionEnd(swiper);
  2814. },
  2815. onLazyImageLoad: function (swiper, slide, img) {
  2816. if (pb.params.onLazyImageLoad) pb.params.onLazyImageLoad(pb, slide, img);
  2817. },
  2818. onLazyImageReady: function (swiper, slide, img) {
  2819. $(slide).removeClass('photo-browser-slide-lazy');
  2820. if (pb.params.onLazyImageReady) pb.params.onLazyImageReady(pb, slide, img);
  2821. }
  2822. };
  2823. if (pb.params.swipeToClose && pb.params.type !== 'page') {
  2824. sliderSettings.onTouchStart = pb.swipeCloseTouchStart;
  2825. sliderSettings.onTouchMoveOpposite = pb.swipeCloseTouchMove;
  2826. sliderSettings.onTouchEnd = pb.swipeCloseTouchEnd;
  2827. }
  2828. pb.swiper = $.swiper(pb.swiperContainer, sliderSettings);
  2829. if (index === 0) {
  2830. pb.onSliderTransitionStart(pb.swiper);
  2831. }
  2832. pb.attachEvents();
  2833. };
  2834. pb.attachEvents = function (detach) {
  2835. var action = detach ? 'off' : 'on';
  2836. // Slide between photos
  2837. if (pb.params.zoom) {
  2838. var target = pb.params.loop ? pb.swiper.slides : pb.slides;
  2839. // Scale image
  2840. target[action]('gesturestart', pb.onSlideGestureStart);
  2841. target[action]('gesturechange', pb.onSlideGestureChange);
  2842. target[action]('gestureend', pb.onSlideGestureEnd);
  2843. // Move image
  2844. target[action]('touchstart', pb.onSlideTouchStart);
  2845. target[action]('touchmove', pb.onSlideTouchMove);
  2846. target[action]('touchend', pb.onSlideTouchEnd);
  2847. }
  2848. pb.container.find('.photo-browser-close-link')[action]('click', pb.close);
  2849. };
  2850. // Expose
  2851. pb.exposed = false;
  2852. pb.toggleExposition = function () {
  2853. if (pb.container) pb.container.toggleClass('photo-browser-exposed');
  2854. if (pb.params.expositionHideCaptions) pb.captionsContainer.toggleClass('photo-browser-captions-exposed');
  2855. pb.exposed = !pb.exposed;
  2856. };
  2857. pb.enableExposition = function () {
  2858. if (pb.container) pb.container.addClass('photo-browser-exposed');
  2859. if (pb.params.expositionHideCaptions) pb.captionsContainer.addClass('photo-browser-captions-exposed');
  2860. pb.exposed = true;
  2861. };
  2862. pb.disableExposition = function () {
  2863. if (pb.container) pb.container.removeClass('photo-browser-exposed');
  2864. if (pb.params.expositionHideCaptions) pb.captionsContainer.removeClass('photo-browser-captions-exposed');
  2865. pb.exposed = false;
  2866. };
  2867. // Gestures
  2868. var gestureSlide, gestureImg, gestureImgWrap, scale = 1, currentScale = 1, isScaling = false;
  2869. pb.onSlideGestureStart = function () {
  2870. if (!gestureSlide) {
  2871. gestureSlide = $(this);
  2872. gestureImg = gestureSlide.find('img, svg, canvas');
  2873. gestureImgWrap = gestureImg.parent('.photo-browser-zoom-container');
  2874. if (gestureImgWrap.length === 0) {
  2875. gestureImg = undefined;
  2876. return;
  2877. }
  2878. }
  2879. gestureImg.transition(0);
  2880. isScaling = true;
  2881. };
  2882. pb.onSlideGestureChange = function (e) {
  2883. if (!gestureImg || gestureImg.length === 0) return;
  2884. scale = e.scale * currentScale;
  2885. if (scale > pb.params.maxZoom) {
  2886. scale = pb.params.maxZoom - 1 + Math.pow((scale - pb.params.maxZoom + 1), 0.5);
  2887. }
  2888. if (scale < pb.params.minZoom) {
  2889. scale = pb.params.minZoom + 1 - Math.pow((pb.params.minZoom - scale + 1), 0.5);
  2890. }
  2891. gestureImg.transform('translate3d(0,0,0) scale(' + scale + ')');
  2892. };
  2893. pb.onSlideGestureEnd = function () {
  2894. if (!gestureImg || gestureImg.length === 0) return;
  2895. scale = Math.max(Math.min(scale, pb.params.maxZoom), pb.params.minZoom);
  2896. gestureImg.transition(pb.params.speed).transform('translate3d(0,0,0) scale(' + scale + ')');
  2897. currentScale = scale;
  2898. isScaling = false;
  2899. if (scale === 1) gestureSlide = undefined;
  2900. };
  2901. pb.toggleZoom = function () {
  2902. if (!gestureSlide) {
  2903. gestureSlide = pb.swiper.slides.eq(pb.swiper.activeIndex);
  2904. gestureImg = gestureSlide.find('img, svg, canvas');
  2905. gestureImgWrap = gestureImg.parent('.photo-browser-zoom-container');
  2906. }
  2907. if (!gestureImg || gestureImg.length === 0) return;
  2908. gestureImgWrap.transition(300).transform('translate3d(0,0,0)');
  2909. if (scale && scale !== 1) {
  2910. scale = currentScale = 1;
  2911. gestureImg.transition(300).transform('translate3d(0,0,0) scale(1)');
  2912. gestureSlide = undefined;
  2913. }
  2914. else {
  2915. scale = currentScale = pb.params.maxZoom;
  2916. gestureImg.transition(300).transform('translate3d(0,0,0) scale(' + scale + ')');
  2917. }
  2918. };
  2919. var imageIsTouched, imageIsMoved, imageCurrentX, imageCurrentY, imageMinX, imageMinY, imageMaxX, imageMaxY, imageWidth, imageHeight, imageTouchesStart = {}, imageTouchesCurrent = {}, imageStartX, imageStartY, velocityPrevPositionX, velocityPrevTime, velocityX, velocityPrevPositionY, velocityY;
  2920. pb.onSlideTouchStart = function (e) {
  2921. if (!gestureImg || gestureImg.length === 0) return;
  2922. if (imageIsTouched) return;
  2923. if ($.device.os === 'android') e.preventDefault();
  2924. imageIsTouched = true;
  2925. imageTouchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
  2926. imageTouchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
  2927. };
  2928. pb.onSlideTouchMove = function (e) {
  2929. if (!gestureImg || gestureImg.length === 0) return;
  2930. pb.swiper.allowClick = false;
  2931. if (!imageIsTouched || !gestureSlide) return;
  2932. if (!imageIsMoved) {
  2933. imageWidth = gestureImg[0].offsetWidth;
  2934. imageHeight = gestureImg[0].offsetHeight;
  2935. imageStartX = $.getTranslate(gestureImgWrap[0], 'x') || 0;
  2936. imageStartY = $.getTranslate(gestureImgWrap[0], 'y') || 0;
  2937. gestureImgWrap.transition(0);
  2938. }
  2939. // Define if we need image drag
  2940. var scaledWidth = imageWidth * scale;
  2941. var scaledHeight = imageHeight * scale;
  2942. if (scaledWidth < pb.swiper.width && scaledHeight < pb.swiper.height) return;
  2943. imageMinX = Math.min((pb.swiper.width / 2 - scaledWidth / 2), 0);
  2944. imageMaxX = -imageMinX;
  2945. imageMinY = Math.min((pb.swiper.height / 2 - scaledHeight / 2), 0);
  2946. imageMaxY = -imageMinY;
  2947. imageTouchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
  2948. imageTouchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
  2949. if (!imageIsMoved && !isScaling) {
  2950. if (
  2951. (Math.floor(imageMinX) === Math.floor(imageStartX) && imageTouchesCurrent.x < imageTouchesStart.x) ||
  2952. (Math.floor(imageMaxX) === Math.floor(imageStartX) && imageTouchesCurrent.x > imageTouchesStart.x)
  2953. ) {
  2954. imageIsTouched = false;
  2955. return;
  2956. }
  2957. }
  2958. e.preventDefault();
  2959. e.stopPropagation();
  2960. imageIsMoved = true;
  2961. imageCurrentX = imageTouchesCurrent.x - imageTouchesStart.x + imageStartX;
  2962. imageCurrentY = imageTouchesCurrent.y - imageTouchesStart.y + imageStartY;
  2963. if (imageCurrentX < imageMinX) {
  2964. imageCurrentX = imageMinX + 1 - Math.pow((imageMinX - imageCurrentX + 1), 0.8);
  2965. }
  2966. if (imageCurrentX > imageMaxX) {
  2967. imageCurrentX = imageMaxX - 1 + Math.pow((imageCurrentX - imageMaxX + 1), 0.8);
  2968. }
  2969. if (imageCurrentY < imageMinY) {
  2970. imageCurrentY = imageMinY + 1 - Math.pow((imageMinY - imageCurrentY + 1), 0.8);
  2971. }
  2972. if (imageCurrentY > imageMaxY) {
  2973. imageCurrentY = imageMaxY - 1 + Math.pow((imageCurrentY - imageMaxY + 1), 0.8);
  2974. }
  2975. //Velocity
  2976. if (!velocityPrevPositionX) velocityPrevPositionX = imageTouchesCurrent.x;
  2977. if (!velocityPrevPositionY) velocityPrevPositionY = imageTouchesCurrent.y;
  2978. if (!velocityPrevTime) velocityPrevTime = Date.now();
  2979. velocityX = (imageTouchesCurrent.x - velocityPrevPositionX) / (Date.now() - velocityPrevTime) / 2;
  2980. velocityY = (imageTouchesCurrent.y - velocityPrevPositionY) / (Date.now() - velocityPrevTime) / 2;
  2981. if (Math.abs(imageTouchesCurrent.x - velocityPrevPositionX) < 2) velocityX = 0;
  2982. if (Math.abs(imageTouchesCurrent.y - velocityPrevPositionY) < 2) velocityY = 0;
  2983. velocityPrevPositionX = imageTouchesCurrent.x;
  2984. velocityPrevPositionY = imageTouchesCurrent.y;
  2985. velocityPrevTime = Date.now();
  2986. gestureImgWrap.transform('translate3d(' + imageCurrentX + 'px, ' + imageCurrentY + 'px,0)');
  2987. };
  2988. pb.onSlideTouchEnd = function () {
  2989. if (!gestureImg || gestureImg.length === 0) return;
  2990. if (!imageIsTouched || !imageIsMoved) {
  2991. imageIsTouched = false;
  2992. imageIsMoved = false;
  2993. return;
  2994. }
  2995. imageIsTouched = false;
  2996. imageIsMoved = false;
  2997. var momentumDurationX = 300;
  2998. var momentumDurationY = 300;
  2999. var momentumDistanceX = velocityX * momentumDurationX;
  3000. var newPositionX = imageCurrentX + momentumDistanceX;
  3001. var momentumDistanceY = velocityY * momentumDurationY;
  3002. var newPositionY = imageCurrentY + momentumDistanceY;
  3003. //Fix duration
  3004. if (velocityX !== 0) momentumDurationX = Math.abs((newPositionX - imageCurrentX) / velocityX);
  3005. if (velocityY !== 0) momentumDurationY = Math.abs((newPositionY - imageCurrentY) / velocityY);
  3006. var momentumDuration = Math.max(momentumDurationX, momentumDurationY);
  3007. imageCurrentX = newPositionX;
  3008. imageCurrentY = newPositionY;
  3009. // Define if we need image drag
  3010. var scaledWidth = imageWidth * scale;
  3011. var scaledHeight = imageHeight * scale;
  3012. imageMinX = Math.min((pb.swiper.width / 2 - scaledWidth / 2), 0);
  3013. imageMaxX = -imageMinX;
  3014. imageMinY = Math.min((pb.swiper.height / 2 - scaledHeight / 2), 0);
  3015. imageMaxY = -imageMinY;
  3016. imageCurrentX = Math.max(Math.min(imageCurrentX, imageMaxX), imageMinX);
  3017. imageCurrentY = Math.max(Math.min(imageCurrentY, imageMaxY), imageMinY);
  3018. gestureImgWrap.transition(momentumDuration).transform('translate3d(' + imageCurrentX + 'px, ' + imageCurrentY + 'px,0)');
  3019. };
  3020. // Swipe Up To Close
  3021. var swipeToCloseIsTouched = false;
  3022. var allowSwipeToClose = true;
  3023. var swipeToCloseDiff, swipeToCloseStart, swipeToCloseCurrent, swipeToCloseStarted = false, swipeToCloseActiveSlide, swipeToCloseTimeStart;
  3024. pb.swipeCloseTouchStart = function () {
  3025. if (!allowSwipeToClose) return;
  3026. swipeToCloseIsTouched = true;
  3027. };
  3028. pb.swipeCloseTouchMove = function (swiper, e) {
  3029. if (!swipeToCloseIsTouched) return;
  3030. if (!swipeToCloseStarted) {
  3031. swipeToCloseStarted = true;
  3032. swipeToCloseStart = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
  3033. swipeToCloseActiveSlide = pb.swiper.slides.eq(pb.swiper.activeIndex);
  3034. swipeToCloseTimeStart = (new Date()).getTime();
  3035. }
  3036. e.preventDefault();
  3037. swipeToCloseCurrent = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
  3038. swipeToCloseDiff = swipeToCloseStart - swipeToCloseCurrent;
  3039. var opacity = 1 - Math.abs(swipeToCloseDiff) / 300;
  3040. swipeToCloseActiveSlide.transform('translate3d(0,' + (-swipeToCloseDiff) + 'px,0)');
  3041. pb.swiper.container.css('opacity', opacity).transition(0);
  3042. };
  3043. pb.swipeCloseTouchEnd = function () {
  3044. swipeToCloseIsTouched = false;
  3045. if (!swipeToCloseStarted) {
  3046. swipeToCloseStarted = false;
  3047. return;
  3048. }
  3049. swipeToCloseStarted = false;
  3050. allowSwipeToClose = false;
  3051. var diff = Math.abs(swipeToCloseDiff);
  3052. var timeDiff = (new Date()).getTime() - swipeToCloseTimeStart;
  3053. if ((timeDiff < 300 && diff > 20) || (timeDiff >= 300 && diff > 100)) {
  3054. setTimeout(function () {
  3055. if (pb.params.type === 'standalone') {
  3056. pb.close();
  3057. }
  3058. if (pb.params.type === 'popup') {
  3059. $.closeModal(pb.popup);
  3060. }
  3061. if (pb.params.onSwipeToClose) {
  3062. pb.params.onSwipeToClose(pb);
  3063. }
  3064. allowSwipeToClose = true;
  3065. }, 0);
  3066. return;
  3067. }
  3068. if (diff !== 0) {
  3069. swipeToCloseActiveSlide.addClass('transitioning').transitionEnd(function () {
  3070. allowSwipeToClose = true;
  3071. swipeToCloseActiveSlide.removeClass('transitioning');
  3072. });
  3073. }
  3074. else {
  3075. allowSwipeToClose = true;
  3076. }
  3077. pb.swiper.container.css('opacity', '').transition('');
  3078. swipeToCloseActiveSlide.transform('');
  3079. };
  3080. return pb;
  3081. };
  3082. PhotoBrowser.prototype = {
  3083. defaults: {
  3084. photos : [],
  3085. container: 'body',
  3086. initialSlide: 0,
  3087. spaceBetween: 20,
  3088. speed: 300,
  3089. zoom: true,
  3090. maxZoom: 3,
  3091. minZoom: 1,
  3092. exposition: true,
  3093. expositionHideCaptions: false,
  3094. type: 'standalone',
  3095. navbar: true,
  3096. toolbar: true,
  3097. theme: 'light',
  3098. swipeToClose: true,
  3099. backLinkText: 'Close',
  3100. ofText: 'of',
  3101. loop: false,
  3102. lazyLoading: false,
  3103. lazyLoadingInPrevNext: false,
  3104. lazyLoadingOnTransitionStart: false,
  3105. /*
  3106. Callbacks:
  3107. onLazyImageLoad(pb, slide, img)
  3108. onLazyImageReady(pb, slide, img)
  3109. onOpen(pb)
  3110. onClose(pb)
  3111. onSlideChangeStart(swiper)
  3112. onSlideChangeEnd(swiper)
  3113. onTap(swiper, e)
  3114. onClick(swiper, e)
  3115. onDoubleTap(swiper, e)
  3116. onSwipeToClose(pb)
  3117. */
  3118. }
  3119. };
  3120. $.photoBrowser = function (params) {
  3121. $.extend(params, $.photoBrowser.prototype.defaults);
  3122. return new PhotoBrowser(params);
  3123. };
  3124. $.photoBrowser.prototype = {
  3125. defaults: {}
  3126. };
  3127. }(Zepto);