PluginProbe
Smart Grid-Layout Design for Contact Form 7 / 4.12
Smart Grid-Layout Design for Contact Form 7 v4.12
4.18.0 4.17.0 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 4.0.0 4.0.1 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10 4.11 4.12 4.13 4.14 All 119 releases
cf7-grid-layout / assets / glider-js / glider.js

glider.js in Smart Grid-Layout Design for Contact Form 7 4.12, at assets/glider-js/glider.js

577 lines 15.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* @preserve
2 _____ __ _ __ _
3 / ___// /(_)___/ /___ ____ (_)___
4 / (_ // // // _ // -_)/ __/_ / /(_-<
5 \___//_//_/ \_,_/ \__//_/ (_)__/ //___/
6 |___/
7
8 Version: forked
9 Author: Nick Piscitelli (pickykneee)
10 Website: https://nickpiscitelli.com
11 Documentation: http://nickpiscitelli.github.io/Glider.js
12 License: MIT License
13 Release Date: October 25th, 2018
14
15 */
16
17 /* global define */
18
19 (function (factory) {
20 typeof define === 'function' && define.amd
21 ? define(factory)
22 : typeof exports === 'object'
23 ? (module.exports = factory())
24 : factory()
25 })(function () {
26 ('use strict') // eslint-disable-line no-unused-expressions
27
28 /* globals window:true */
29 var _window = typeof window !== 'undefined' ? window : this
30
31 var Glider = (_window.Glider = function (element, settings) {
32 var _ = this
33
34 if (element._glider) return element._glider
35
36 _.ele = element
37 _.ele.classList.add('glider')
38
39 // expose glider object to its DOM element
40 _.ele._glider = _
41
42 // merge user setting with defaults
43 _.opt = Object.assign(
44 {},
45 {
46 slidesToScroll: 1,
47 slidesToShow: 1,
48 resizeLock: true,
49 labelDots: false,
50 duration: 0.5,
51 dir: (_window.getComputedStyle(_.ele).direction === 'rtl') ? -1:1,
52 // easeInQuad
53 easing: function (x, t, b, c, d) {
54 return c * (t /= d) * t + b
55 }
56 },
57 settings
58 )
59 if(Math.abs(_.opt.dir) != 1) _.opt.dir = 1;
60
61 // set defaults
62 _.animate_id = _.page = _.slide = _.scrollLeft = 0
63 _.arrows = {}
64
65 // preserve original options to
66 // extend breakpoint settings
67 _._opt = _.opt
68
69 if (_.opt.skipTrack) {
70 // first and only child is the track
71 _.track = _.ele.children[0]
72 } else {
73 // create track and wrap slides
74 _.track = document.createElement('div')
75 _.ele.appendChild(_.track)
76 while (_.ele.children.length !== 1) {
77 _.track.appendChild(_.ele.children[0])
78 }
79 }
80
81 _.track.classList.add('glider-track')
82
83 // start glider
84 _.init()
85
86 // set events
87 _.resize = _.init.bind(_, true)
88 _.event(_.ele, 'add', {
89 scroll: _.updateControls.bind(_)
90 })
91 _.event(_window, 'add', {
92 resize: _.resize
93 })
94 })
95
96 var gliderPrototype = Glider.prototype
97 gliderPrototype.init = function (refresh, paging) {
98 var _ = this
99
100 var width = 0
101
102 var height = 0
103
104 _.slides = _.track.children;
105
106
107 [].forEach.call(_.slides, function (_, i) {
108 _.classList.add('glider-slide')
109 _.setAttribute('data-gslide', i)
110 })
111
112 _.containerWidth = _.ele.clientWidth
113
114 var breakpointChanged = _.settingsBreakpoint()
115 if (!paging) paging = breakpointChanged
116
117 if (
118 _.opt.slidesToShow === 'auto' ||
119 typeof _.opt._autoSlide !== 'undefined'
120 ) {
121 var slideCount = _.containerWidth / _.opt.itemWidth
122
123 _.opt._autoSlide = _.opt.slidesToShow = _.opt.exactWidth
124 ? slideCount
125 : Math.floor(slideCount)
126 }
127 if (_.opt.slidesToScroll === 'auto') {
128 _.opt.slidesToScroll = Math.floor(_.opt.slidesToShow)
129 }
130
131 _.itemWidth = _.opt.exactWidth
132 ? _.opt.itemWidth
133 : _.containerWidth / _.opt.slidesToShow;
134
135 // set slide dimensions
136 [].forEach.call(_.slides, function (__) {
137 __.style.height = 'auto'
138 __.style.width = _.itemWidth + 'px'
139 width += _.itemWidth
140 height = Math.max(__.offsetHeight, height)
141 })
142
143 _.track.style.width = width + 'px'
144 _.trackWidth = width
145 _.isDrag = false
146 _.preventClick = false
147
148 _.opt.resizeLock && _.scrollTo(_.slide * _.itemWidth, 0)
149
150 if (breakpointChanged || paging) {
151 _.bindArrows()
152 _.buildDots()
153 _.bindDrag()
154 }
155
156 _.updateControls()
157
158 _.emit(refresh ? 'refresh' : 'loaded')
159 }
160
161 gliderPrototype.bindDrag = function () {
162 var _ = this
163 _.mouse = _.mouse || _.handleMouse.bind(_)
164
165 var mouseup = function () {
166 _.mouseDown = undefined
167 _.ele.classList.remove('drag')
168 if (_.isDrag) {
169 _.preventClick = true
170 }
171 _.isDrag = false
172 }
173
174 var events = {
175 mouseup: mouseup,
176 mouseleave: mouseup,
177 mousedown: function (e) {
178 e.preventDefault()
179 e.stopPropagation()
180 _.mouseDown = e.clientX
181 _.ele.classList.add('drag')
182 },
183 mousemove: _.mouse,
184 click: function (e) {
185 if (_.preventClick) {
186 e.preventDefault()
187 e.stopPropagation()
188 }
189 _.preventClick = false
190 }
191 }
192
193 _.ele.classList.toggle('draggable', _.opt.draggable === true)
194 _.event(_.ele, 'remove', events)
195 if (_.opt.draggable) _.event(_.ele, 'add', events)
196 }
197
198 gliderPrototype.buildDots = function () {
199 var _ = this
200
201 if (!_.opt.dots) {
202 if (_.dots) _.dots.innerHTML = ''
203 return
204 }
205
206 if (typeof _.opt.dots === 'string') {
207 _.dots = document.querySelector(_.opt.dots)
208 } else _.dots = _.opt.dots
209 if (!_.dots) return
210
211 _.dots.innerHTML = ''
212 _.dots.classList.add('glider-dots')
213 if(false !== _.opt.labelDots) _.dots.classList.add('label-dots')
214
215 for (var i = 0; i < Math.ceil(_.slides.length / _.opt.slidesToShow); ++i) {
216 var dot = document.createElement('button')
217 dot.dataset.index = i
218 dot.setAttribute('aria-label', 'Page ' + (i + 1))
219 dot.className = 'glider-dot ' + (i ? '' : 'active')
220 if(false !== _.opt.labelDots){
221 if(_.opt.labelDots[i]) dot.innerText = _.opt.labelDots[i]
222 else dot.innerText = (i+1)
223 }
224 _.event(dot, 'add', {
225 click: _.scrollItem.bind(_, i, true)
226 })
227 _.dots.appendChild(dot)
228 }
229 }
230
231 gliderPrototype.bindArrows = function () {
232 var _ = this
233 if (!_.opt.arrows) {
234 Object.keys(_.arrows).forEach(function (direction) {
235 var element = _.arrows[direction]
236 _.event(element, 'remove', { click: element._func })
237 })
238 return
239 }
240 ['prev', 'next'].forEach(function (direction) {
241 var arrow = _.opt.arrows[direction]
242 if (arrow) {
243 if (typeof arrow === 'string') arrow = document.querySelector(arrow)
244 if (arrow) {
245 arrow._func = arrow._func || _.scrollItem.bind(_, direction)
246 _.event(arrow, 'remove', {
247 click: arrow._func
248 })
249 _.event(arrow, 'add', {
250 click: arrow._func
251 })
252 _.arrows[direction] = arrow
253 }
254 }
255 })
256 }
257
258 gliderPrototype.updateControls = function (event) {
259 var _ = this
260
261 if (event && !_.opt.scrollPropagate) {
262 event.stopPropagation()
263 }
264
265 var disableArrows = _.containerWidth >= _.trackWidth
266
267 if (!_.opt.rewind) {
268 if (_.arrows.prev) {
269 _.arrows.prev.classList.toggle(
270 'disabled',
271 (_.opt.dir * _.ele.scrollLeft) <= 0 || disableArrows
272 )
273 }
274 if (_.arrows.next) {
275 _.arrows.next.classList.toggle(
276 'disabled',
277 Math.ceil(_.opt.dir * _.ele.scrollLeft + _.containerWidth) >=
278 Math.floor(_.trackWidth) || disableArrows
279 )
280 }
281 }
282
283 _.slide = Math.round(_.opt.dir * _.ele.scrollLeft / _.itemWidth)
284 _.page = Math.round(_.opt.dir * _.ele.scrollLeft / _.containerWidth)
285
286 var middle = _.slide + Math.floor(Math.floor(_.opt.slidesToShow) / 2)
287
288 var extraMiddle = Math.floor(_.opt.slidesToShow) % 2 ? 0 : middle + 1
289 if (Math.floor(_.opt.slidesToShow) === 1) {
290 extraMiddle = 0
291 }
292
293 // the last page may be less than one half of a normal page width so
294 // the page is rounded down. when at the end, force the page to turn
295 if ( (_.opt.dir * _.ele.scrollLeft + _.containerWidth) >= Math.floor(_.trackWidth)) {
296 _.page = _.dots ? _.dots.children.length - 1 : 0
297 }
298
299 [].forEach.call(_.slides, function (slide, index) {
300 var slideClasses = slide.classList
301
302 var wasVisible = slideClasses.contains('visible')
303
304 var start = _.opt.dir * _.ele.scrollLeft
305
306 var end = _.opt.dir * _.ele.scrollLeft + _.containerWidth
307
308 var itemStart = _.itemWidth * index
309
310 var itemEnd = itemStart + _.itemWidth;
311
312 [].forEach.call(slideClasses, function (className) {
313 /^left|right/.test(className) && slideClasses.remove(className)
314 })
315 slideClasses.toggle('active', _.slide === index)
316 if (middle === index || (extraMiddle && extraMiddle === index)) {
317 slideClasses.add('center')
318 } else {
319 slideClasses.remove('center')
320 slideClasses.add(
321 [
322 index < middle ? 'left' : 'right',
323 Math.abs(index - (index < middle ? middle : extraMiddle || middle))
324 ].join('-')
325 )
326 }
327
328 var isVisible =
329 Math.ceil(itemStart) >= start && Math.floor(itemEnd) <= end
330 slideClasses.toggle('visible', isVisible)
331 if (isVisible !== wasVisible) {
332 _.emit('slide-' + (isVisible ? 'visible' : 'hidden'), {
333 slide: index
334 })
335 }
336 })
337 if (_.dots) {
338 [].forEach.call(_.dots.children, function (dot, index) {
339 dot.classList.toggle('active', _.page === index)
340 })
341 }
342
343 if (event && _.opt.scrollLock) {
344 clearTimeout(_.scrollLock)
345 _.scrollLock = setTimeout(function () {
346 clearTimeout(_.scrollLock)
347 // dont attempt to scroll less than a pixel fraction - causes looping
348 if (Math.abs(_.ele.scrollLeft / _.itemWidth - _.slide) > 0.02) {
349 if (!_.mouseDown) {
350 // Only scroll if not at the end (#94)
351 if (_.trackWidth > _.containerWidth + _.opt.dir *_.ele.scrollLeft) {
352 _.scrollItem(_.getCurrentSlide())
353 }
354 }
355 }
356 }, _.opt.scrollLockDelay || 250)
357 }
358 }
359
360 gliderPrototype.getCurrentSlide = function () {
361 var _ = this
362 return _.round(_.ele.scrollLeft / _.itemWidth)
363 }
364
365 gliderPrototype.scrollItem = function (slide, dot, e) {
366 if (e) e.preventDefault()
367
368 var _ = this
369
370 var originalSlide = slide
371 ++_.animate_id
372
373 if (dot === true) {
374 slide = slide * _.containerWidth
375 slide = Math.round(slide / _.itemWidth) * _.itemWidth
376 } else {
377 if (typeof slide === 'string') {
378 var backwards = slide === 'prev'
379
380 // use precise location if fractional slides are on
381 if (_.opt.slidesToScroll % 1 || _.opt.slidesToShow % 1) {
382 slide = _.getCurrentSlide()
383 } else {
384 slide = _.slide
385 }
386
387 if (backwards) slide -= _.opt.slidesToScroll
388 else slide += _.opt.slidesToScroll
389
390 if (_.opt.rewind) {
391 var scrollLeft = _.opt.dir * _.ele.scrollLeft
392 slide =
393 backwards && !scrollLeft
394 ? _.slides.length
395 : !backwards &&
396 scrollLeft + _.containerWidth >= Math.floor(_.trackWidth)
397 ? 0
398 : slide
399 }
400 }
401
402 slide = Math.max(Math.min(slide, _.slides.length), 0)
403
404 _.slide = slide
405 slide = _.itemWidth * slide
406 }
407
408 _.scrollTo(
409 slide,
410 _.opt.duration * Math.abs( _.opt.dir * _.ele.scrollLeft - slide),
411 function () {
412 _.updateControls()
413 _.emit('animated', {
414 value: originalSlide,
415 type:
416 typeof originalSlide === 'string' ? 'arrow' : dot ? 'dot' : 'slide'
417 })
418 }
419 )
420
421 return false
422 }
423
424 gliderPrototype.settingsBreakpoint = function () {
425 var _ = this
426
427 var resp = _._opt.responsive
428
429 if (resp) {
430 // Sort the breakpoints in mobile first order
431 resp.sort(function (a, b) {
432 return b.breakpoint - a.breakpoint
433 })
434
435 for (var i = 0; i < resp.length; ++i) {
436 var size = resp[i]
437 if (_window.innerWidth >= size.breakpoint) {
438 if (_.breakpoint !== size.breakpoint) {
439 _.opt = Object.assign({}, _._opt, size.settings)
440 _.breakpoint = size.breakpoint
441 return true
442 }
443 return false
444 }
445 }
446 }
447 // set back to defaults in case they were overriden
448 var breakpointChanged = _.breakpoint !== 0
449 _.opt = Object.assign({}, _._opt)
450 _.breakpoint = 0
451 return breakpointChanged
452 }
453
454 gliderPrototype.scrollTo = function (scrollTarget, scrollDuration, callback) {
455 var _ = this
456
457 var start = new Date().getTime()
458
459 var animateIndex = _.animate_id
460
461 var animate = function () {
462 var now = new Date().getTime() - start
463 _.scrollLeft = _.scrollLeft + (scrollTarget - _.scrollLeft) * _.opt.easing(0, now, 0, 1, scrollDuration)
464 _.ele.scrollLeft = _.opt.dir * _.scrollLeft
465
466 if (now < scrollDuration && animateIndex === _.animate_id) {
467 _window.requestAnimationFrame(animate)
468 } else {
469 _.scrollLeft = scrollTarget
470 _.ele.scrollLeft = _.opt.dir * _.scrollLeft
471 callback && callback.call(_)
472 }
473 }
474
475 _window.requestAnimationFrame(animate)
476 }
477
478 gliderPrototype.removeItem = function (index) {
479 var _ = this
480
481 if (_.slides.length) {
482 _.track.removeChild(_.slides[index])
483 _.refresh(true)
484 _.emit('remove')
485 }
486 }
487
488 gliderPrototype.addItem = function (ele) {
489 var _ = this
490
491 _.track.appendChild(ele)
492 _.refresh(true)
493 _.emit('add')
494 }
495
496 gliderPrototype.handleMouse = function (e) {
497 var _ = this
498 if (_.mouseDown) {
499 _.isDrag = true
500 _.ele.scrollLeft += _.opt.dir *
501 (_.mouseDown - e.clientX) * (_.opt.dragVelocity || 3.3)
502 _.mouseDown = e.clientX
503 }
504 }
505
506 // used to round to the nearest 0.XX fraction
507 gliderPrototype.round = function (double) {
508 var _ = this
509 var step = _.opt.slidesToScroll % 1 || 1
510 var inv = 1.0 / step
511 return Math.round(double * inv) / inv
512 }
513
514 gliderPrototype.refresh = function (paging) {
515 var _ = this
516 _.init(true, paging)
517 }
518
519 gliderPrototype.setOption = function (opt, global) {
520 var _ = this
521
522 if (_.breakpoint && !global) {
523 _._opt.responsive.forEach(function (v) {
524 if (v.breakpoint === _.breakpoint) {
525 v.settings = Object.assign({}, v.settings, opt)
526 }
527 })
528 } else {
529 _._opt = Object.assign({}, _._opt, opt)
530 }
531
532 _.breakpoint = 0
533 _.settingsBreakpoint()
534 }
535
536 gliderPrototype.destroy = function () {
537 var _ = this
538
539 var replace = _.ele.cloneNode(true)
540
541 var clear = function (ele) {
542 ele.removeAttribute('style');
543 [].forEach.call(ele.classList, function (className) {
544 /^glider/.test(className) && ele.classList.remove(className)
545 })
546 }
547 // remove track
548 replace.children[0].outerHTML = replace.children[0].innerHTML
549 clear(replace);
550 [].forEach.call(replace.getElementsByTagName('*'), clear)
551 _.ele.parentNode.replaceChild(replace, _.ele)
552 _.event(_window, 'remove', {
553 resize: _.resize
554 })
555 _.emit('destroy')
556 }
557
558 gliderPrototype.emit = function (name, arg) {
559 var _ = this
560
561 var e = new _window.CustomEvent('glider-' + name, {
562 bubbles: !_.opt.eventPropagate,
563 detail: arg
564 })
565 _.ele.dispatchEvent(e)
566 }
567
568 gliderPrototype.event = function (ele, type, args) {
569 var eventHandler = ele[type + 'EventListener'].bind(ele)
570 Object.keys(args).forEach(function (k) {
571 eventHandler(k, args[k])
572 })
573 }
574
575 return Glider
576 })
577