123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929 |
- // Flickity main
- ( function( window, factory ) {
- // universal module definition
- /* jshint strict: false */
- if ( typeof define == 'function' && define.amd ) {
- // AMD
- define( [
- 'ev-emitter/ev-emitter',
- 'get-size/get-size',
- 'fizzy-ui-utils/utils',
- './cell',
- './slide',
- './animate'
- ], function( EvEmitter, getSize, utils, Cell, Slide, animatePrototype ) {
- return factory( window, EvEmitter, getSize, utils, Cell, Slide, animatePrototype );
- });
- } else if ( typeof module == 'object' && module.exports ) {
- // CommonJS
- module.exports = factory(
- window,
- require('ev-emitter'),
- require('get-size'),
- require('fizzy-ui-utils'),
- require('./cell'),
- require('./slide'),
- require('./animate')
- );
- } else {
- // browser global
- var _Flickity = window.Flickity;
- window.Flickity = factory(
- window,
- window.EvEmitter,
- window.getSize,
- window.fizzyUIUtils,
- _Flickity.Cell,
- _Flickity.Slide,
- _Flickity.animatePrototype
- );
- }
- }( window, function factory( window, EvEmitter, getSize,
- utils, Cell, Slide, animatePrototype ) {
- 'use strict';
- // vars
- var jQuery = window.jQuery;
- var getComputedStyle = window.getComputedStyle;
- var console = window.console;
- function moveElements( elems, toElem ) {
- elems = utils.makeArray( elems );
- while ( elems.length ) {
- toElem.appendChild( elems.shift() );
- }
- }
- // -------------------------- Flickity -------------------------- //
- // globally unique identifiers
- var GUID = 0;
- // internal store of all Flickity intances
- var instances = {};
- function Flickity( element, options ) {
- var queryElement = utils.getQueryElement( element );
- if ( !queryElement ) {
- if ( console ) {
- console.error( 'Bad element for Flickity: ' + ( queryElement || element ) );
- }
- return;
- }
- this.element = queryElement;
- // do not initialize twice on same element
- if ( this.element.flickityGUID ) {
- var instance = instances[ this.element.flickityGUID ];
- instance.option( options );
- return instance;
- }
- // add jQuery
- if ( jQuery ) {
- this.$element = jQuery( this.element );
- }
- // options
- this.options = utils.extend( {}, this.constructor.defaults );
- this.option( options );
- // kick things off
- this._create();
- }
- Flickity.defaults = {
- accessibility: true,
- // adaptiveHeight: false,
- cellAlign: 'center',
- // cellSelector: undefined,
- // contain: false,
- freeScrollFriction: 0.075, // friction when free-scrolling
- friction: 0.28, // friction when selecting
- namespaceJQueryEvents: true,
- // initialIndex: 0,
- percentPosition: true,
- resize: true,
- selectedAttraction: 0.025,
- setGallerySize: true
- // watchCSS: false,
- // wrapAround: false
- };
- // hash of methods triggered on _create()
- Flickity.createMethods = [];
- var proto = Flickity.prototype;
- // inherit EventEmitter
- utils.extend( proto, EvEmitter.prototype );
- proto._create = function() {
- // add id for Flickity.data
- var id = this.guid = ++GUID;
- this.element.flickityGUID = id; // expando
- instances[ id ] = this; // associate via id
- // initial properties
- this.selectedIndex = 0;
- // how many frames slider has been in same position
- this.restingFrames = 0;
- // initial physics properties
- this.x = 0;
- this.velocity = 0;
- this.originSide = this.options.rightToLeft ? 'right' : 'left';
- // create viewport & slider
- this.viewport = document.createElement('div');
- this.viewport.className = 'flickity-viewport';
- this._createSlider();
- if ( this.options.resize || this.options.watchCSS ) {
- window.addEventListener( 'resize', this );
- }
- // add listeners from on option
- for ( var eventName in this.options.on ) {
- var listener = this.options.on[ eventName ];
- this.on( eventName, listener );
- }
- Flickity.createMethods.forEach( function( method ) {
- this[ method ]();
- }, this );
- if ( this.options.watchCSS ) {
- this.watchCSS();
- } else {
- this.activate();
- }
- };
- /**
- * set options
- * @param {Object} opts
- */
- proto.option = function( opts ) {
- utils.extend( this.options, opts );
- };
- proto.activate = function() {
- if ( this.isActive ) {
- return;
- }
- this.isActive = true;
- this.element.classList.add('flickity-enabled');
- if ( this.options.rightToLeft ) {
- this.element.classList.add('flickity-rtl');
- }
- this.getSize();
- // move initial cell elements so they can be loaded as cells
- var cellElems = this._filterFindCellElements( this.element.children );
- moveElements( cellElems, this.slider );
- this.viewport.appendChild( this.slider );
- this.element.appendChild( this.viewport );
- // get cells from children
- this.reloadCells();
- if ( this.options.accessibility ) {
- // allow element to focusable
- this.element.tabIndex = 0;
- // listen for key presses
- this.element.addEventListener( 'keydown', this );
- }
- this.emitEvent('activate');
- this.selectInitialIndex();
- // flag for initial activation, for using initialIndex
- this.isInitActivated = true;
- // ready event. #493
- this.dispatchEvent('ready');
- };
- // slider positions the cells
- proto._createSlider = function() {
- // slider element does all the positioning
- var slider = document.createElement('div');
- slider.className = 'flickity-slider';
- slider.style[ this.originSide ] = 0;
- this.slider = slider;
- };
- proto._filterFindCellElements = function( elems ) {
- return utils.filterFindElements( elems, this.options.cellSelector );
- };
- // goes through all children
- proto.reloadCells = function() {
- // collection of item elements
- this.cells = this._makeCells( this.slider.children );
- this.positionCells();
- this._getWrapShiftCells();
- this.setGallerySize();
- };
- /**
- * turn elements into Flickity.Cells
- * @param {Array or NodeList or HTMLElement} elems
- * @returns {Array} items - collection of new Flickity Cells
- */
- proto._makeCells = function( elems ) {
- var cellElems = this._filterFindCellElements( elems );
- // create new Flickity for collection
- var cells = cellElems.map( function( cellElem ) {
- return new Cell( cellElem, this );
- }, this );
- return cells;
- };
- proto.getLastCell = function() {
- return this.cells[ this.cells.length - 1 ];
- };
- proto.getLastSlide = function() {
- return this.slides[ this.slides.length - 1 ];
- };
- // positions all cells
- proto.positionCells = function() {
- // size all cells
- this._sizeCells( this.cells );
- // position all cells
- this._positionCells( 0 );
- };
- /**
- * position certain cells
- * @param {Integer} index - which cell to start with
- */
- proto._positionCells = function( index ) {
- index = index || 0;
- // also measure maxCellHeight
- // start 0 if positioning all cells
- this.maxCellHeight = index ? this.maxCellHeight || 0 : 0;
- var cellX = 0;
- // get cellX
- if ( index > 0 ) {
- var startCell = this.cells[ index - 1 ];
- cellX = startCell.x + startCell.size.outerWidth;
- }
- var len = this.cells.length;
- for ( var i=index; i < len; i++ ) {
- var cell = this.cells[i];
- cell.setPosition( cellX );
- cellX += cell.size.outerWidth;
- this.maxCellHeight = Math.max( cell.size.outerHeight, this.maxCellHeight );
- }
- // keep track of cellX for wrap-around
- this.slideableWidth = cellX;
- // slides
- this.updateSlides();
- // contain slides target
- this._containSlides();
- // update slidesWidth
- this.slidesWidth = len ? this.getLastSlide().target - this.slides[0].target : 0;
- };
- /**
- * cell.getSize() on multiple cells
- * @param {Array} cells
- */
- proto._sizeCells = function( cells ) {
- cells.forEach( function( cell ) {
- cell.getSize();
- });
- };
- // -------------------------- -------------------------- //
- proto.updateSlides = function() {
- this.slides = [];
- if ( !this.cells.length ) {
- return;
- }
- var slide = new Slide( this );
- this.slides.push( slide );
- var isOriginLeft = this.originSide == 'left';
- var nextMargin = isOriginLeft ? 'marginRight' : 'marginLeft';
- var canCellFit = this._getCanCellFit();
- this.cells.forEach( function( cell, i ) {
- // just add cell if first cell in slide
- if ( !slide.cells.length ) {
- slide.addCell( cell );
- return;
- }
- var slideWidth = ( slide.outerWidth - slide.firstMargin ) +
- ( cell.size.outerWidth - cell.size[ nextMargin ] );
- if ( canCellFit.call( this, i, slideWidth ) ) {
- slide.addCell( cell );
- } else {
- // doesn't fit, new slide
- slide.updateTarget();
- slide = new Slide( this );
- this.slides.push( slide );
- slide.addCell( cell );
- }
- }, this );
- // last slide
- slide.updateTarget();
- // update .selectedSlide
- this.updateSelectedSlide();
- };
- proto._getCanCellFit = function() {
- var groupCells = this.options.groupCells;
- if ( !groupCells ) {
- return function() {
- return false;
- };
- } else if ( typeof groupCells == 'number' ) {
- // group by number. 3 -> [0,1,2], [3,4,5], ...
- var number = parseInt( groupCells, 10 );
- return function( i ) {
- return ( i % number ) !== 0;
- };
- }
- // default, group by width of slide
- // parse '75%
- var percentMatch = typeof groupCells == 'string' &&
- groupCells.match(/^(\d+)%$/);
- var percent = percentMatch ? parseInt( percentMatch[1], 10 ) / 100 : 1;
- return function( i, slideWidth ) {
- return slideWidth <= ( this.size.innerWidth + 1 ) * percent;
- };
- };
- // alias _init for jQuery plugin .flickity()
- proto._init =
- proto.reposition = function() {
- this.positionCells();
- this.positionSliderAtSelected();
- };
- proto.getSize = function() {
- this.size = getSize( this.element );
- this.setCellAlign();
- this.cursorPosition = this.size.innerWidth * this.cellAlign;
- };
- var cellAlignShorthands = {
- // cell align, then based on origin side
- center: {
- left: 0.5,
- right: 0.5
- },
- left: {
- left: 0,
- right: 1
- },
- right: {
- right: 0,
- left: 1
- }
- };
- proto.setCellAlign = function() {
- var shorthand = cellAlignShorthands[ this.options.cellAlign ];
- this.cellAlign = shorthand ? shorthand[ this.originSide ] : this.options.cellAlign;
- };
- proto.setGallerySize = function() {
- if ( this.options.setGallerySize ) {
- var height = this.options.adaptiveHeight && this.selectedSlide ?
- this.selectedSlide.height : this.maxCellHeight;
- this.viewport.style.height = height + 'px';
- }
- };
- proto._getWrapShiftCells = function() {
- // only for wrap-around
- if ( !this.options.wrapAround ) {
- return;
- }
- // unshift previous cells
- this._unshiftCells( this.beforeShiftCells );
- this._unshiftCells( this.afterShiftCells );
- // get before cells
- // initial gap
- var gapX = this.cursorPosition;
- var cellIndex = this.cells.length - 1;
- this.beforeShiftCells = this._getGapCells( gapX, cellIndex, -1 );
- // get after cells
- // ending gap between last cell and end of gallery viewport
- gapX = this.size.innerWidth - this.cursorPosition;
- // start cloning at first cell, working forwards
- this.afterShiftCells = this._getGapCells( gapX, 0, 1 );
- };
- proto._getGapCells = function( gapX, cellIndex, increment ) {
- // keep adding cells until the cover the initial gap
- var cells = [];
- while ( gapX > 0 ) {
- var cell = this.cells[ cellIndex ];
- if ( !cell ) {
- break;
- }
- cells.push( cell );
- cellIndex += increment;
- gapX -= cell.size.outerWidth;
- }
- return cells;
- };
- // ----- contain ----- //
- // contain cell targets so no excess sliding
- proto._containSlides = function() {
- if ( !this.options.contain || this.options.wrapAround || !this.cells.length ) {
- return;
- }
- var isRightToLeft = this.options.rightToLeft;
- var beginMargin = isRightToLeft ? 'marginRight' : 'marginLeft';
- var endMargin = isRightToLeft ? 'marginLeft' : 'marginRight';
- var contentWidth = this.slideableWidth - this.getLastCell().size[ endMargin ];
- // content is less than gallery size
- var isContentSmaller = contentWidth < this.size.innerWidth;
- // bounds
- var beginBound = this.cursorPosition + this.cells[0].size[ beginMargin ];
- var endBound = contentWidth - this.size.innerWidth * ( 1 - this.cellAlign );
- // contain each cell target
- this.slides.forEach( function( slide ) {
- if ( isContentSmaller ) {
- // all cells fit inside gallery
- slide.target = contentWidth * this.cellAlign;
- } else {
- // contain to bounds
- slide.target = Math.max( slide.target, beginBound );
- slide.target = Math.min( slide.target, endBound );
- }
- }, this );
- };
- // ----- ----- //
- /**
- * emits events via eventEmitter and jQuery events
- * @param {String} type - name of event
- * @param {Event} event - original event
- * @param {Array} args - extra arguments
- */
- proto.dispatchEvent = function( type, event, args ) {
- var emitArgs = event ? [ event ].concat( args ) : args;
- this.emitEvent( type, emitArgs );
- if ( jQuery && this.$element ) {
- // default trigger with type if no event
- type += this.options.namespaceJQueryEvents ? '.flickity' : '';
- var $event = type;
- if ( event ) {
- // create jQuery event
- var jQEvent = jQuery.Event( event );
- jQEvent.type = type;
- $event = jQEvent;
- }
- this.$element.trigger( $event, args );
- }
- };
- // -------------------------- select -------------------------- //
- /**
- * @param {Integer} index - index of the slide
- * @param {Boolean} isWrap - will wrap-around to last/first if at the end
- * @param {Boolean} isInstant - will immediately set position at selected cell
- */
- proto.select = function( index, isWrap, isInstant ) {
- if ( !this.isActive ) {
- return;
- }
- index = parseInt( index, 10 );
- this._wrapSelect( index );
- if ( this.options.wrapAround || isWrap ) {
- index = utils.modulo( index, this.slides.length );
- }
- // bail if invalid index
- if ( !this.slides[ index ] ) {
- return;
- }
- var prevIndex = this.selectedIndex;
- this.selectedIndex = index;
- this.updateSelectedSlide();
- if ( isInstant ) {
- this.positionSliderAtSelected();
- } else {
- this.startAnimation();
- }
- if ( this.options.adaptiveHeight ) {
- this.setGallerySize();
- }
- // events
- this.dispatchEvent( 'select', null, [ index ] );
- // change event if new index
- if ( index != prevIndex ) {
- this.dispatchEvent( 'change', null, [ index ] );
- }
- // old v1 event name, remove in v3
- this.dispatchEvent('cellSelect');
- };
- // wraps position for wrapAround, to move to closest slide. #113
- proto._wrapSelect = function( index ) {
- var len = this.slides.length;
- var isWrapping = this.options.wrapAround && len > 1;
- if ( !isWrapping ) {
- return index;
- }
- var wrapIndex = utils.modulo( index, len );
- // go to shortest
- var delta = Math.abs( wrapIndex - this.selectedIndex );
- var backWrapDelta = Math.abs( ( wrapIndex + len ) - this.selectedIndex );
- var forewardWrapDelta = Math.abs( ( wrapIndex - len ) - this.selectedIndex );
- if ( !this.isDragSelect && backWrapDelta < delta ) {
- index += len;
- } else if ( !this.isDragSelect && forewardWrapDelta < delta ) {
- index -= len;
- }
- // wrap position so slider is within normal area
- if ( index < 0 ) {
- this.x -= this.slideableWidth;
- } else if ( index >= len ) {
- this.x += this.slideableWidth;
- }
- };
- proto.previous = function( isWrap, isInstant ) {
- this.select( this.selectedIndex - 1, isWrap, isInstant );
- };
- proto.next = function( isWrap, isInstant ) {
- this.select( this.selectedIndex + 1, isWrap, isInstant );
- };
- proto.updateSelectedSlide = function() {
- var slide = this.slides[ this.selectedIndex ];
- // selectedIndex could be outside of slides, if triggered before resize()
- if ( !slide ) {
- return;
- }
- // unselect previous selected slide
- this.unselectSelectedSlide();
- // update new selected slide
- this.selectedSlide = slide;
- slide.select();
- this.selectedCells = slide.cells;
- this.selectedElements = slide.getCellElements();
- // HACK: selectedCell & selectedElement is first cell in slide, backwards compatibility
- // Remove in v3?
- this.selectedCell = slide.cells[0];
- this.selectedElement = this.selectedElements[0];
- };
- proto.unselectSelectedSlide = function() {
- if ( this.selectedSlide ) {
- this.selectedSlide.unselect();
- }
- };
- proto.selectInitialIndex = function() {
- var initialIndex = this.options.initialIndex;
- // already activated, select previous selectedIndex
- if ( this.isInitActivated ) {
- this.select( this.selectedIndex, false, true );
- return;
- }
- // select with selector string
- if ( initialIndex && typeof initialIndex == 'string' ) {
- var cell = this.queryCell( initialIndex );
- if ( cell ) {
- this.selectCell( initialIndex, false, true );
- return;
- }
- }
- var index = 0;
- // select with number
- if ( initialIndex && this.slides[ initialIndex ] ) {
- index = initialIndex;
- }
- // select instantly
- this.select( index, false, true );
- };
- /**
- * select slide from number or cell element
- * @param {Element or Number} elem
- */
- proto.selectCell = function( value, isWrap, isInstant ) {
- // get cell
- var cell = this.queryCell( value );
- if ( !cell ) {
- return;
- }
- var index = this.getCellSlideIndex( cell );
- this.select( index, isWrap, isInstant );
- };
- proto.getCellSlideIndex = function( cell ) {
- // get index of slides that has cell
- for ( var i=0; i < this.slides.length; i++ ) {
- var slide = this.slides[i];
- var index = slide.cells.indexOf( cell );
- if ( index != -1 ) {
- return i;
- }
- }
- };
- // -------------------------- get cells -------------------------- //
- /**
- * get Flickity.Cell, given an Element
- * @param {Element} elem
- * @returns {Flickity.Cell} item
- */
- proto.getCell = function( elem ) {
- // loop through cells to get the one that matches
- for ( var i=0; i < this.cells.length; i++ ) {
- var cell = this.cells[i];
- if ( cell.element == elem ) {
- return cell;
- }
- }
- };
- /**
- * get collection of Flickity.Cells, given Elements
- * @param {Element, Array, NodeList} elems
- * @returns {Array} cells - Flickity.Cells
- */
- proto.getCells = function( elems ) {
- elems = utils.makeArray( elems );
- var cells = [];
- elems.forEach( function( elem ) {
- var cell = this.getCell( elem );
- if ( cell ) {
- cells.push( cell );
- }
- }, this );
- return cells;
- };
- /**
- * get cell elements
- * @returns {Array} cellElems
- */
- proto.getCellElements = function() {
- return this.cells.map( function( cell ) {
- return cell.element;
- });
- };
- /**
- * get parent cell from an element
- * @param {Element} elem
- * @returns {Flickit.Cell} cell
- */
- proto.getParentCell = function( elem ) {
- // first check if elem is cell
- var cell = this.getCell( elem );
- if ( cell ) {
- return cell;
- }
- // try to get parent cell elem
- elem = utils.getParent( elem, '.flickity-slider > *' );
- return this.getCell( elem );
- };
- /**
- * get cells adjacent to a slide
- * @param {Integer} adjCount - number of adjacent slides
- * @param {Integer} index - index of slide to start
- * @returns {Array} cells - array of Flickity.Cells
- */
- proto.getAdjacentCellElements = function( adjCount, index ) {
- if ( !adjCount ) {
- return this.selectedSlide.getCellElements();
- }
- index = index === undefined ? this.selectedIndex : index;
- var len = this.slides.length;
- if ( 1 + ( adjCount * 2 ) >= len ) {
- return this.getCellElements();
- }
- var cellElems = [];
- for ( var i = index - adjCount; i <= index + adjCount ; i++ ) {
- var slideIndex = this.options.wrapAround ? utils.modulo( i, len ) : i;
- var slide = this.slides[ slideIndex ];
- if ( slide ) {
- cellElems = cellElems.concat( slide.getCellElements() );
- }
- }
- return cellElems;
- };
- /**
- * select slide from number or cell element
- * @param {Element, Selector String, or Number} selector
- */
- proto.queryCell = function( selector ) {
- if ( typeof selector == 'number' ) {
- // use number as index
- return this.cells[ selector ];
- }
- if ( typeof selector == 'string' ) {
- // do not select invalid selectors from hash: #123, #/. #791
- if ( selector.match(/^[#\.]?[\d\/]/) ) {
- return;
- }
- // use string as selector, get element
- selector = this.element.querySelector( selector );
- }
- // get cell from element
- return this.getCell( selector );
- };
- // -------------------------- events -------------------------- //
- proto.uiChange = function() {
- this.emitEvent('uiChange');
- };
- // keep focus on element when child UI elements are clicked
- proto.childUIPointerDown = function( event ) {
- // HACK iOS does not allow touch events to bubble up?!
- if ( event.type != 'touchstart' ) {
- event.preventDefault();
- }
- this.focus();
- };
- // ----- resize ----- //
- proto.onresize = function() {
- this.watchCSS();
- this.resize();
- };
- utils.debounceMethod( Flickity, 'onresize', 150 );
- proto.resize = function() {
- if ( !this.isActive ) {
- return;
- }
- this.getSize();
- // wrap values
- if ( this.options.wrapAround ) {
- this.x = utils.modulo( this.x, this.slideableWidth );
- }
- this.positionCells();
- this._getWrapShiftCells();
- this.setGallerySize();
- this.emitEvent('resize');
- // update selected index for group slides, instant
- // TODO: position can be lost between groups of various numbers
- var selectedElement = this.selectedElements && this.selectedElements[0];
- this.selectCell( selectedElement, false, true );
- };
- // watches the :after property, activates/deactivates
- proto.watchCSS = function() {
- var watchOption = this.options.watchCSS;
- if ( !watchOption ) {
- return;
- }
- var afterContent = getComputedStyle( this.element, ':after' ).content;
- // activate if :after { content: 'flickity' }
- if ( afterContent.indexOf('flickity') != -1 ) {
- this.activate();
- } else {
- this.deactivate();
- }
- };
- // ----- keydown ----- //
- // go previous/next if left/right keys pressed
- proto.onkeydown = function( event ) {
- // only work if element is in focus
- var isNotFocused = document.activeElement && document.activeElement != this.element;
- if ( !this.options.accessibility ||isNotFocused ) {
- return;
- }
- var handler = Flickity.keyboardHandlers[ event.keyCode ];
- if ( handler ) {
- handler.call( this );
- }
- };
- Flickity.keyboardHandlers = {
- // left arrow
- 37: function() {
- var leftMethod = this.options.rightToLeft ? 'next' : 'previous';
- this.uiChange();
- this[ leftMethod ]();
- },
- // right arrow
- 39: function() {
- var rightMethod = this.options.rightToLeft ? 'previous' : 'next';
- this.uiChange();
- this[ rightMethod ]();
- },
- };
- // ----- focus ----- //
- proto.focus = function() {
- // TODO remove scrollTo once focus options gets more support
- // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#Browser_compatibility
- var prevScrollY = window.pageYOffset;
- this.element.focus({ preventScroll: true });
- // hack to fix scroll jump after focus, #76
- if ( window.pageYOffset != prevScrollY ) {
- window.scrollTo( window.pageXOffset, prevScrollY );
- }
- };
- // -------------------------- destroy -------------------------- //
- // deactivate all Flickity functionality, but keep stuff available
- proto.deactivate = function() {
- if ( !this.isActive ) {
- return;
- }
- this.element.classList.remove('flickity-enabled');
- this.element.classList.remove('flickity-rtl');
- this.unselectSelectedSlide();
- // destroy cells
- this.cells.forEach( function( cell ) {
- cell.destroy();
- });
- this.element.removeChild( this.viewport );
- // move child elements back into element
- moveElements( this.slider.children, this.element );
- if ( this.options.accessibility ) {
- this.element.removeAttribute('tabIndex');
- this.element.removeEventListener( 'keydown', this );
- }
- // set flags
- this.isActive = false;
- this.emitEvent('deactivate');
- };
- proto.destroy = function() {
- this.deactivate();
- window.removeEventListener( 'resize', this );
- this.allOff();
- this.emitEvent('destroy');
- if ( jQuery && this.$element ) {
- jQuery.removeData( this.element, 'flickity' );
- }
- delete this.element.flickityGUID;
- delete instances[ this.guid ];
- };
- // -------------------------- prototype -------------------------- //
- utils.extend( proto, animatePrototype );
- // -------------------------- extras -------------------------- //
- /**
- * get Flickity instance from element
- * @param {Element} elem
- * @returns {Flickity}
- */
- Flickity.data = function( elem ) {
- elem = utils.getQueryElement( elem );
- var id = elem && elem.flickityGUID;
- return id && instances[ id ];
- };
- utils.htmlInit( Flickity, 'flickity' );
- if ( jQuery && jQuery.bridget ) {
- jQuery.bridget( 'flickity', Flickity );
- }
- // set internal jQuery, for Webpack + jQuery v3, #478
- Flickity.setJQuery = function( jq ) {
- jQuery = jq;
- };
- Flickity.Cell = Cell;
- Flickity.Slide = Slide;
- return Flickity;
- }));
|