From: Colin Marshall Date: Thu, 4 Feb 2016 04:22:43 +0000 (-0700) Subject: Convert orbit to ES6 class X-Git-Tag: v6.2.0-rc.1~41^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e87b61e511f7a9ed0e68e0325fe433387fc7cfa8;p=thirdparty%2Ffoundation%2Ffoundation-sites.git Convert orbit to ES6 class --- diff --git a/js/foundation.orbit.js b/js/foundation.orbit.js index 1ca6ef604..480533b25 100644 --- a/js/foundation.orbit.js +++ b/js/foundation.orbit.js @@ -1,20 +1,22 @@ +'use strict'; + /** -* Orbit module. -* @module foundation.orbit -* @requires foundation.util.keyboard -* @requires foundation.util.motion -* @requires foundation.util.timerAndImageLoader -* @requires foundation.util.touch -*/ -!function($, Foundation){ - 'use strict'; + * Orbit module. + * @module foundation.orbit + * @requires foundation.util.keyboard + * @requires foundation.util.motion + * @requires foundation.util.timerAndImageLoader + * @requires foundation.util.touch + */ + +export default class Orbit { /** * Creates a new instance of an orbit carousel. * @class * @param {jQuery} element - jQuery object to make into an Orbit Carousel. * @param {Object} options - Overrides to the default plugin settings. */ - function Orbit(element, options){ + constructor(element, options){ this.$element = element; this.options = $.extend({}, Orbit.defaults, this.$element.data(), options); @@ -32,390 +34,410 @@ } }); } - Orbit.defaults = { - /** - * Tells the JS to loadBullets. - * @option - * @example true - */ - bullets: true, - /** - * Tells the JS to apply event listeners to nav buttons - * @option - * @example true - */ - navButtons: true, - /** - * motion-ui animation class to apply - * @option - * @example 'slide-in-right' - */ - animInFromRight: 'slide-in-right', - /** - * motion-ui animation class to apply - * @option - * @example 'slide-out-right' - */ - animOutToRight: 'slide-out-right', - /** - * motion-ui animation class to apply - * @option - * @example 'slide-in-left' - * - */ - animInFromLeft: 'slide-in-left', - /** - * motion-ui animation class to apply - * @option - * @example 'slide-out-left' - */ - animOutToLeft: 'slide-out-left', - /** - * Allows Orbit to automatically animate on page load. - * @option - * @example true - */ - autoPlay: true, - /** - * Amount of time, in ms, between slide transitions - * @option - * @example 5000 - */ - timerDelay: 5000, - /** - * Allows Orbit to infinitely loop through the slides - * @option - * @example true - */ - infiniteWrap: true, - /** - * Allows the Orbit slides to bind to swipe events for mobile, requires an additional util library - * @option - * @example true - */ - swipe: true, - /** - * Allows the timing function to pause animation on hover. - * @option - * @example true - */ - pauseOnHover: true, - /** - * Allows Orbit to bind keyboard events to the slider, to animate frames with arrow keys - * @option - * @example true - */ - accessible: true, - /** - * Class applied to the container of Orbit - * @option - * @example 'orbit-container' - */ - containerClass: 'orbit-container', - /** - * Class applied to individual slides. - * @option - * @example 'orbit-slide' - */ - slideClass: 'orbit-slide', - /** - * Class applied to the bullet container. You're welcome. - * @option - * @example 'orbit-bullets' - */ - boxOfBullets: 'orbit-bullets', - /** - * Class applied to the `next` navigation button. - * @option - * @example 'orbit-next' - */ - nextClass: 'orbit-next', - /** - * Class applied to the `previous` navigation button. - * @option - * @example 'orbit-previous' - */ - prevClass: 'orbit-previous', - /** - * Boolean to flag the js to use motion ui classes or not. Default to true for backwards compatability. - * @option - * @example true - */ - useMUI: true - }; + /** * Initializes the plugin by creating jQuery collections, setting attributes, and starting the animation. * @function * @private */ - Orbit.prototype._init = function(){ + _init() { this.$wrapper = this.$element.find(`.${this.options.containerClass}`); this.$slides = this.$element.find(`.${this.options.slideClass}`); var $images = this.$element.find('img'), initActive = this.$slides.filter('.is-active'); - if(!initActive.length){ + if (!initActive.length) { this.$slides.eq(0).addClass('is-active'); } - if(!this.options.useMUI){ + + if (!this.options.useMUI) { this.$slides.addClass('no-motionui'); } - if($images.length){ + + if ($images.length) { Foundation.onImagesLoaded($images, this._prepareForOrbit.bind(this)); - }else{ + } else { this._prepareForOrbit();//hehe } - if(this.options.bullets){ + if (this.options.bullets) { this._loadBullets(); } this._events(); - if(this.options.autoPlay && this.$slides.length > 1){ + if (this.options.autoPlay && this.$slides.length > 1) { this.geoSync(); } - if(this.options.accessible){ // allow wrapper to be focusable to enable arrow navigation + + if (this.options.accessible) { // allow wrapper to be focusable to enable arrow navigation this.$wrapper.attr('tabindex', 0); } - }; + } + /** * Creates a jQuery collection of bullets, if they are being used. * @function * @private */ - Orbit.prototype._loadBullets = function(){ + _loadBullets() { this.$bullets = this.$element.find(`.${this.options.boxOfBullets}`).find('button'); - }; + } + /** * Sets a `timer` object on the orbit, and starts the counter for the next slide. * @function */ - Orbit.prototype.geoSync = function(){ + geoSync() { var _this = this; this.timer = new Foundation.Timer( this.$element, - {duration: this.options.timerDelay, - infinite: false}, - function(){ + { + duration: this.options.timerDelay, + infinite: false + }, + function() { + _this.changeSlide(true); + }); + this.timer.start(); + } + + /** + * Sets wrapper and slide heights for the orbit. + * @function + * @private + */ + _prepareForOrbit() { + var _this = this; + this._setWrapperHeight(function(max){ + _this._setSlideHeight(max); + }); + } + + /** + * Calulates the height of each slide in the collection, and uses the tallest one for the wrapper height. + * @function + * @private + * @param {Function} cb - a callback function to fire when complete. + */ + _setWrapperHeight(cb) {//rewrite this to `for` loop + var max = 0, temp, counter = 0; + + this.$slides.each(function() { + temp = this.getBoundingClientRect().height; + $(this).attr('data-slide', counter); + + if (counter) {//if not the first slide, set css position and display property + $(this).css({'position': 'relative', 'display': 'none'}); + } + max = temp > max ? temp : max; + counter++; + }); + + if (counter === this.$slides.length) { + this.$wrapper.css({'height': max}); //only change the wrapper height property once. + cb(max); //fire callback with max height dimension. + } + } + + /** + * Sets the max-height of each slide. + * @function + * @private + */ + _setSlideHeight(height) { + this.$slides.each(function() { + $(this).css('max-height', height); + }); + } + + /** + * Adds event listeners to basically everything within the element. + * @function + * @private + */ + _events() { + var _this = this; + + //*************************************** + //**Now using custom event - thanks to:** + //** Yohai Ararat of Toronto ** + //*************************************** + if (this.$slides.length > 1) { + + if (this.options.swipe) { + this.$slides.off('swipeleft.zf.orbit swiperight.zf.orbit') + .on('swipeleft.zf.orbit', function(e){ + e.preventDefault(); _this.changeSlide(true); + }).on('swiperight.zf.orbit', function(e){ + e.preventDefault(); + _this.changeSlide(false); }); - this.timer.start(); - }; - /** - * Sets wrapper and slide heights for the orbit. - * @function - * @private - */ - Orbit.prototype._prepareForOrbit = function(){ - var _this = this; - this._setWrapperHeight(function(max){ - _this._setSlideHeight(max); - }); - }; - /** - * Calulates the height of each slide in the collection, and uses the tallest one for the wrapper height. - * @function - * @private - * @param {Function} cb - a callback function to fire when complete. - */ - Orbit.prototype._setWrapperHeight = function(cb){//rewrite this to `for` loop - var max = 0, temp, counter = 0; - - this.$slides.each(function(){ - temp = this.getBoundingClientRect().height; - $(this).attr('data-slide', counter); - - if(counter){//if not the first slide, set css position and display property - $(this).css({'position': 'relative', 'display': 'none'}); - } - max = temp > max ? temp : max; - counter++; + } + //*************************************** + + if (this.options.autoPlay) { + this.$slides.on('click.zf.orbit', function() { + _this.$element.data('clickedOn', _this.$element.data('clickedOn') ? false : true); + _this.timer[_this.$element.data('clickedOn') ? 'pause' : 'start'](); }); - if(counter === this.$slides.length){ - this.$wrapper.css({'height': max});//only change the wrapper height property once. - cb(max);//fire callback with max height dimension. + if (this.options.pauseOnHover) { + this.$element.on('mouseenter.zf.orbit', function() { + _this.timer.pause(); + }).on('mouseleave.zf.orbit', function() { + if (!_this.$element.data('clickedOn')) { + _this.timer.start(); + } + }); } - }; - /** - * Sets the max-height of each slide. - * @function - * @private - */ - Orbit.prototype._setSlideHeight = function(height){ - this.$slides.each(function(){ - $(this).css('max-height', height); + } + + if (this.options.navButtons) { + var $controls = this.$element.find(`.${this.options.nextClass}, .${this.options.prevClass}`); + $controls.attr('tabindex', 0) + //also need to handle enter/return and spacebar key presses + .on('click.zf.orbit touchend.zf.orbit', function(){ + _this.changeSlide($(this).hasClass(_this.options.nextClass)); }); - }; - /** - * Adds event listeners to basically everything within the element. - * @function - * @private - */ - Orbit.prototype._events = function(){ - var _this = this; - - //*************************************** - //**Now using custom event - thanks to:** - //** Yohai Ararat of Toronto ** - //*************************************** - if(this.$slides.length > 1){ - - if(this.options.swipe){ - this.$slides.off('swipeleft.zf.orbit swiperight.zf.orbit') - .on('swipeleft.zf.orbit', function(e){ - e.preventDefault(); - _this.changeSlide(true); - }).on('swiperight.zf.orbit', function(e){ - e.preventDefault(); - _this.changeSlide(false); - }); - } - //*************************************** - - if(this.options.autoPlay){ - this.$slides.on('click.zf.orbit', function(){ - _this.$element.data('clickedOn', _this.$element.data('clickedOn') ? false : true); - _this.timer[_this.$element.data('clickedOn') ? 'pause' : 'start'](); - }); - if(this.options.pauseOnHover){ - this.$element.on('mouseenter.zf.orbit', function(){ - _this.timer.pause(); - }).on('mouseleave.zf.orbit', function(){ - if(!_this.$element.data('clickedOn')){ - _this.timer.start(); - } - }); + } + + if (this.options.bullets) { + this.$bullets.on('click.zf.orbit touchend.zf.orbit', function() { + if (/is-active/g.test(this.className)) { return false; }//if this is active, kick out of function. + var idx = $(this).data('slide'), + ltr = idx > _this.$slides.filter('.is-active').data('slide'), + $slide = _this.$slides.eq(idx); + + _this.changeSlide(ltr, $slide, idx); + }); + } + + this.$wrapper.add(this.$bullets).on('keydown.zf.orbit', function(e) { + // handle keyboard event with keyboard util + Foundation.Keyboard.handleKey(e, 'Orbit', { + next: function() { + _this.changeSlide(true); + }, + previous: function() { + _this.changeSlide(false); + }, + handled: function() { // if bullet is focused, make sure focus moves + if ($(e.target).is(_this.$bullets)) { + _this.$bullets.filter('.is-active').focus(); } } + }); + }); + } + } - if(this.options.navButtons){ - var $controls = this.$element.find(`.${this.options.nextClass}, .${this.options.prevClass}`); - $controls.attr('tabindex', 0) - //also need to handle enter/return and spacebar key presses - .on('click.zf.orbit touchend.zf.orbit', function(){ - _this.changeSlide($(this).hasClass(_this.options.nextClass)); - }); - } + /** + * Changes the current slide to a new one. + * @function + * @param {Boolean} isLTR - flag if the slide should move left to right. + * @param {jQuery} chosenSlide - the jQuery element of the slide to show next, if one is selected. + * @param {Number} idx - the index of the new slide in its collection, if one chosen. + * @fires Orbit#slidechange + */ + changeSlide(isLTR, chosenSlide, idx) { + var $curSlide = this.$slides.filter('.is-active').eq(0); - if(this.options.bullets){ - this.$bullets.on('click.zf.orbit touchend.zf.orbit', function(){ - if(/is-active/g.test(this.className)){ return false; }//if this is active, kick out of function. - var idx = $(this).data('slide'), - ltr = idx > _this.$slides.filter('.is-active').data('slide'), - $slide = _this.$slides.eq(idx); + if (/mui/g.test($curSlide[0].className)) { return false; } //if the slide is currently animating, kick out of the function - _this.changeSlide(ltr, $slide, idx); - }); - } + var $firstSlide = this.$slides.first(), + $lastSlide = this.$slides.last(), + dirIn = isLTR ? 'Right' : 'Left', + dirOut = isLTR ? 'Left' : 'Right', + _this = this, + $newSlide; - this.$wrapper.add(this.$bullets).on('keydown.zf.orbit', function(e){ - // handle keyboard event with keyboard util - Foundation.Keyboard.handleKey(e, 'Orbit', { - next: function() { - _this.changeSlide(true); - }, - previous: function() { - _this.changeSlide(false); - }, - handled: function() { // if bullet is focused, make sure focus moves - if ($(e.target).is(_this.$bullets)) { - _this.$bullets.filter('.is-active').focus(); - } - } - }); + if (!chosenSlide) { //most of the time, this will be auto played or clicked from the navButtons. + $newSlide = isLTR ? //if wrapping enabled, check to see if there is a `next` or `prev` sibling, if not, select the first or last slide to fill in. if wrapping not enabled, attempt to select `next` or `prev`, if there's nothing there, the function will kick out on next step. CRAZY NESTED TERNARIES!!!!! + (this.options.infiniteWrap ? $curSlide.next(`.${this.options.slideClass}`).length ? $curSlide.next(`.${this.options.slideClass}`) : $firstSlide : $curSlide.next(`.${this.options.slideClass}`))//pick next slide if moving left to right + : + (this.options.infiniteWrap ? $curSlide.prev(`.${this.options.slideClass}`).length ? $curSlide.prev(`.${this.options.slideClass}`) : $lastSlide : $curSlide.prev(`.${this.options.slideClass}`));//pick prev slide if moving right to left + } else { + $newSlide = chosenSlide; + } + + if ($newSlide.length) { + if (this.options.bullets) { + idx = idx || this.$slides.index($newSlide); //grab index to update bullets + this._updateBullets(idx); + } + + if (this.options.useMUI) { + Foundation.Motion.animateIn( + $newSlide.addClass('is-active').css({'position': 'absolute', 'top': 0}), + this.options[`animInFrom${dirIn}`], + function(){ + $newSlide.css({'position': 'relative', 'display': 'block'}) + .attr('aria-live', 'polite'); + }); + + Foundation.Motion.animateOut( + $curSlide.removeClass('is-active'), + this.options[`animOutTo${dirOut}`], + function(){ + $curSlide.removeAttr('aria-live'); + if(_this.options.autoPlay && !_this.timer.isPaused){ + _this.timer.restart(); + } + //do stuff? }); + } else { + $curSlide.removeClass('is-active is-in').removeAttr('aria-live').hide(); + $newSlide.addClass('is-active is-in').attr('aria-live', 'polite').show(); + if (this.options.autoPlay && !this.timer.isPaused) { + this.timer.restart(); } - }; - /** - * Changes the current slide to a new one. - * @function - * @param {Boolean} isLTR - flag if the slide should move left to right. - * @param {jQuery} chosenSlide - the jQuery element of the slide to show next, if one is selected. - * @param {Number} idx - the index of the new slide in its collection, if one chosen. - * @fires Orbit#slidechange - */ - Orbit.prototype.changeSlide = function(isLTR, chosenSlide, idx){ - var $curSlide = this.$slides.filter('.is-active').eq(0); - - if(/mui/g.test($curSlide[0].className)){ return false; }//if the slide is currently animating, kick out of the function - - var $firstSlide = this.$slides.first(), - $lastSlide = this.$slides.last(), - dirIn = isLTR ? 'Right' : 'Left', - dirOut = isLTR ? 'Left' : 'Right', - _this = this, - $newSlide; - - if(!chosenSlide){//most of the time, this will be auto played or clicked from the navButtons. - $newSlide = isLTR ? //if wrapping enabled, check to see if there is a `next` or `prev` sibling, if not, select the first or last slide to fill in. if wrapping not enabled, attempt to select `next` or `prev`, if there's nothing there, the function will kick out on next step. CRAZY NESTED TERNARIES!!!!! - (this.options.infiniteWrap ? $curSlide.next(`.${this.options.slideClass}`).length ? $curSlide.next(`.${this.options.slideClass}`) : $firstSlide : $curSlide.next(`.${this.options.slideClass}`))//pick next slide if moving left to right - : - (this.options.infiniteWrap ? $curSlide.prev(`.${this.options.slideClass}`).length ? $curSlide.prev(`.${this.options.slideClass}`) : $lastSlide : $curSlide.prev(`.${this.options.slideClass}`));//pick prev slide if moving right to left - }else{ - $newSlide = chosenSlide; - } - if($newSlide.length){ - if(this.options.bullets){ - idx = idx || this.$slides.index($newSlide);//grab index to update bullets - this._updateBullets(idx); - } - if(this.options.useMUI){ - - Foundation.Motion.animateIn( - $newSlide.addClass('is-active').css({'position': 'absolute', 'top': 0}), - this.options[`animInFrom${dirIn}`], - function(){ - $newSlide.css({'position': 'relative', 'display': 'block'}) - .attr('aria-live', 'polite'); - }); - - Foundation.Motion.animateOut( - $curSlide.removeClass('is-active'), - this.options[`animOutTo${dirOut}`], - function(){ - $curSlide.removeAttr('aria-live'); - if(_this.options.autoPlay && !_this.timer.isPaused){ - _this.timer.restart(); - } - //do stuff? - }); - }else{ - $curSlide.removeClass('is-active is-in').removeAttr('aria-live').hide(); - $newSlide.addClass('is-active is-in').attr('aria-live', 'polite').show(); - if(this.options.autoPlay && !this.timer.isPaused){ - this.timer.restart(); - } - } - /** - * Triggers when the slide has finished animating in. - * @event Orbit#slidechange - */ - this.$element.trigger('slidechange.zf.orbit', [$newSlide]); - } - }; - /** - * Updates the active state of the bullets, if displayed. - * @function - * @private - * @param {Number} idx - the index of the current slide. - */ - Orbit.prototype._updateBullets = function(idx){ - var $oldBullet = this.$element.find(`.${this.options.boxOfBullets}`) - .find('.is-active').removeClass('is-active').blur(), - span = $oldBullet.find('span:last').detach(), - $newBullet = this.$bullets.eq(idx).addClass('is-active').append(span); - }; - /** - * Destroys the carousel and hides the element. - * @function - */ - Orbit.prototype.destroy = function(){ - this.$element.off('.zf.orbit').find('*').off('.zf.orbit').end().hide(); - Foundation.unregisterPlugin(this); - }; - - Foundation.plugin(Orbit, 'Orbit'); - - }(jQuery, window.Foundation); + } + /** + * Triggers when the slide has finished animating in. + * @event Orbit#slidechange + */ + this.$element.trigger('slidechange.zf.orbit', [$newSlide]); + } + } + + /** + * Updates the active state of the bullets, if displayed. + * @function + * @private + * @param {Number} idx - the index of the current slide. + */ + _updateBullets(idx) { + var $oldBullet = this.$element.find(`.${this.options.boxOfBullets}`) + .find('.is-active').removeClass('is-active').blur(), + span = $oldBullet.find('span:last').detach(), + $newBullet = this.$bullets.eq(idx).addClass('is-active').append(span); + } + + /** + * Destroys the carousel and hides the element. + * @function + */ + destroy() { + this.$element.off('.zf.orbit').find('*').off('.zf.orbit').end().hide(); + Foundation.unregisterPlugin(this); + } +} + +Orbit.defaults = { + /** + * Tells the JS to loadBullets. + * @option + * @example true + */ + bullets: true, + /** + * Tells the JS to apply event listeners to nav buttons + * @option + * @example true + */ + navButtons: true, + /** + * motion-ui animation class to apply + * @option + * @example 'slide-in-right' + */ + animInFromRight: 'slide-in-right', + /** + * motion-ui animation class to apply + * @option + * @example 'slide-out-right' + */ + animOutToRight: 'slide-out-right', + /** + * motion-ui animation class to apply + * @option + * @example 'slide-in-left' + * + */ + animInFromLeft: 'slide-in-left', + /** + * motion-ui animation class to apply + * @option + * @example 'slide-out-left' + */ + animOutToLeft: 'slide-out-left', + /** + * Allows Orbit to automatically animate on page load. + * @option + * @example true + */ + autoPlay: true, + /** + * Amount of time, in ms, between slide transitions + * @option + * @example 5000 + */ + timerDelay: 5000, + /** + * Allows Orbit to infinitely loop through the slides + * @option + * @example true + */ + infiniteWrap: true, + /** + * Allows the Orbit slides to bind to swipe events for mobile, requires an additional util library + * @option + * @example true + */ + swipe: true, + /** + * Allows the timing function to pause animation on hover. + * @option + * @example true + */ + pauseOnHover: true, + /** + * Allows Orbit to bind keyboard events to the slider, to animate frames with arrow keys + * @option + * @example true + */ + accessible: true, + /** + * Class applied to the container of Orbit + * @option + * @example 'orbit-container' + */ + containerClass: 'orbit-container', + /** + * Class applied to individual slides. + * @option + * @example 'orbit-slide' + */ + slideClass: 'orbit-slide', + /** + * Class applied to the bullet container. You're welcome. + * @option + * @example 'orbit-bullets' + */ + boxOfBullets: 'orbit-bullets', + /** + * Class applied to the `next` navigation button. + * @option + * @example 'orbit-next' + */ + nextClass: 'orbit-next', + /** + * Class applied to the `previous` navigation button. + * @option + * @example 'orbit-previous' + */ + prevClass: 'orbit-previous', + /** + * Boolean to flag the js to use motion ui classes or not. Default to true for backwards compatability. + * @option + * @example true + */ + useMUI: true +}; + +// Window exports +if (window.Foundation) { + window.Foundation.plugin(Orbit, 'Orbit'); +}