PluginProbe
Smart Grid-Layout Design for Contact Form 7 / 4.5
Smart Grid-Layout Design for Contact Form 7 v4.5
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.5, at assets/glider-js/glider.js

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