add-remove-cell.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // add, remove cell
  2. ( function( window, factory ) {
  3. // universal module definition
  4. /* jshint strict: false */
  5. if ( typeof define == 'function' && define.amd ) {
  6. // AMD
  7. define( [
  8. './flickity',
  9. 'fizzy-ui-utils/utils'
  10. ], function( Flickity, utils ) {
  11. return factory( window, Flickity, utils );
  12. });
  13. } else if ( typeof module == 'object' && module.exports ) {
  14. // CommonJS
  15. module.exports = factory(
  16. window,
  17. require('./flickity'),
  18. require('fizzy-ui-utils')
  19. );
  20. } else {
  21. // browser global
  22. factory(
  23. window,
  24. window.Flickity,
  25. window.fizzyUIUtils
  26. );
  27. }
  28. }( window, function factory( window, Flickity, utils ) {
  29. 'use strict';
  30. // append cells to a document fragment
  31. function getCellsFragment( cells ) {
  32. var fragment = document.createDocumentFragment();
  33. cells.forEach( function( cell ) {
  34. fragment.appendChild( cell.element );
  35. });
  36. return fragment;
  37. }
  38. // -------------------------- add/remove cell prototype -------------------------- //
  39. var proto = Flickity.prototype;
  40. /**
  41. * Insert, prepend, or append cells
  42. * @param {Element, Array, NodeList} elems
  43. * @param {Integer} index
  44. */
  45. proto.insert = function( elems, index ) {
  46. var cells = this._makeCells( elems );
  47. if ( !cells || !cells.length ) {
  48. return;
  49. }
  50. var len = this.cells.length;
  51. // default to append
  52. index = index === undefined ? len : index;
  53. // add cells with document fragment
  54. var fragment = getCellsFragment( cells );
  55. // append to slider
  56. var isAppend = index == len;
  57. if ( isAppend ) {
  58. this.slider.appendChild( fragment );
  59. } else {
  60. var insertCellElement = this.cells[ index ].element;
  61. this.slider.insertBefore( fragment, insertCellElement );
  62. }
  63. // add to this.cells
  64. if ( index === 0 ) {
  65. // prepend, add to start
  66. this.cells = cells.concat( this.cells );
  67. } else if ( isAppend ) {
  68. // append, add to end
  69. this.cells = this.cells.concat( cells );
  70. } else {
  71. // insert in this.cells
  72. var endCells = this.cells.splice( index, len - index );
  73. this.cells = this.cells.concat( cells ).concat( endCells );
  74. }
  75. this._sizeCells( cells );
  76. this.cellChange( index, true );
  77. };
  78. proto.append = function( elems ) {
  79. this.insert( elems, this.cells.length );
  80. };
  81. proto.prepend = function( elems ) {
  82. this.insert( elems, 0 );
  83. };
  84. /**
  85. * Remove cells
  86. * @param {Element, Array, NodeList} elems
  87. */
  88. proto.remove = function( elems ) {
  89. var cells = this.getCells( elems );
  90. if ( !cells || !cells.length ) {
  91. return;
  92. }
  93. var minCellIndex = this.cells.length - 1;
  94. // remove cells from collection & DOM
  95. cells.forEach( function( cell ) {
  96. cell.remove();
  97. var index = this.cells.indexOf( cell );
  98. minCellIndex = Math.min( index, minCellIndex );
  99. utils.removeFrom( this.cells, cell );
  100. }, this );
  101. this.cellChange( minCellIndex, true );
  102. };
  103. /**
  104. * logic to be run after a cell's size changes
  105. * @param {Element} elem - cell's element
  106. */
  107. proto.cellSizeChange = function( elem ) {
  108. var cell = this.getCell( elem );
  109. if ( !cell ) {
  110. return;
  111. }
  112. cell.getSize();
  113. var index = this.cells.indexOf( cell );
  114. this.cellChange( index );
  115. };
  116. /**
  117. * logic any time a cell is changed: added, removed, or size changed
  118. * @param {Integer} changedCellIndex - index of the changed cell, optional
  119. */
  120. proto.cellChange = function( changedCellIndex, isPositioningSlider ) {
  121. var prevSelectedElem = this.selectedElement;
  122. this._positionCells( changedCellIndex );
  123. this._getWrapShiftCells();
  124. this.setGallerySize();
  125. // update selectedIndex
  126. // try to maintain position & select previous selected element
  127. var cell = this.getCell( prevSelectedElem );
  128. if ( cell ) {
  129. this.selectedIndex = this.getCellSlideIndex( cell );
  130. }
  131. this.selectedIndex = Math.min( this.slides.length - 1, this.selectedIndex );
  132. this.emitEvent( 'cellChange', [ changedCellIndex ] );
  133. // position slider
  134. this.select( this.selectedIndex );
  135. // do not position slider after lazy load
  136. if ( isPositioningSlider ) {
  137. this.positionSliderAtSelected();
  138. }
  139. };
  140. // ----- ----- //
  141. return Flickity;
  142. }));