page-dots.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // page dots
  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. 'unipointer/unipointer',
  10. 'fizzy-ui-utils/utils'
  11. ], function( Flickity, Unipointer, utils ) {
  12. return factory( window, Flickity, Unipointer, utils );
  13. });
  14. } else if ( typeof module == 'object' && module.exports ) {
  15. // CommonJS
  16. module.exports = factory(
  17. window,
  18. require('./flickity'),
  19. require('unipointer'),
  20. require('fizzy-ui-utils')
  21. );
  22. } else {
  23. // browser global
  24. factory(
  25. window,
  26. window.Flickity,
  27. window.Unipointer,
  28. window.fizzyUIUtils
  29. );
  30. }
  31. }( window, function factory( window, Flickity, Unipointer, utils ) {
  32. // -------------------------- PageDots -------------------------- //
  33. 'use strict';
  34. function PageDots( parent ) {
  35. this.parent = parent;
  36. this._create();
  37. }
  38. PageDots.prototype = Object.create( Unipointer.prototype );
  39. PageDots.prototype._create = function() {
  40. // create holder element
  41. this.holder = document.createElement('ol');
  42. this.holder.className = 'flickity-page-dots';
  43. // create dots, array of elements
  44. this.dots = [];
  45. // events
  46. this.handleClick = this.onClick.bind( this );
  47. this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) );
  48. };
  49. PageDots.prototype.activate = function() {
  50. this.setDots();
  51. this.holder.addEventListener( 'click', this.handleClick );
  52. this.bindStartEvent( this.holder );
  53. // add to DOM
  54. this.parent.element.appendChild( this.holder );
  55. };
  56. PageDots.prototype.deactivate = function() {
  57. this.holder.removeEventListener( 'click', this.handleClick );
  58. this.unbindStartEvent( this.holder );
  59. // remove from DOM
  60. this.parent.element.removeChild( this.holder );
  61. };
  62. PageDots.prototype.setDots = function() {
  63. // get difference between number of slides and number of dots
  64. var delta = this.parent.slides.length - this.dots.length;
  65. if ( delta > 0 ) {
  66. this.addDots( delta );
  67. } else if ( delta < 0 ) {
  68. this.removeDots( -delta );
  69. }
  70. };
  71. PageDots.prototype.addDots = function( count ) {
  72. var fragment = document.createDocumentFragment();
  73. var newDots = [];
  74. var length = this.dots.length;
  75. var max = length + count;
  76. for ( var i = length; i < max; i++ ) {
  77. var dot = document.createElement('li');
  78. dot.className = 'dot';
  79. dot.setAttribute( 'aria-label', 'Page dot ' + ( i + 1 ) );
  80. fragment.appendChild( dot );
  81. newDots.push( dot );
  82. }
  83. this.holder.appendChild( fragment );
  84. this.dots = this.dots.concat( newDots );
  85. };
  86. PageDots.prototype.removeDots = function( count ) {
  87. // remove from this.dots collection
  88. var removeDots = this.dots.splice( this.dots.length - count, count );
  89. // remove from DOM
  90. removeDots.forEach( function( dot ) {
  91. this.holder.removeChild( dot );
  92. }, this );
  93. };
  94. PageDots.prototype.updateSelected = function() {
  95. // remove selected class on previous
  96. if ( this.selectedDot ) {
  97. this.selectedDot.className = 'dot';
  98. this.selectedDot.removeAttribute('aria-current');
  99. }
  100. // don't proceed if no dots
  101. if ( !this.dots.length ) {
  102. return;
  103. }
  104. this.selectedDot = this.dots[ this.parent.selectedIndex ];
  105. this.selectedDot.className = 'dot is-selected';
  106. this.selectedDot.setAttribute( 'aria-current', 'step' );
  107. };
  108. PageDots.prototype.onTap = // old method name, backwards-compatible
  109. PageDots.prototype.onClick = function( event ) {
  110. var target = event.target;
  111. // only care about dot clicks
  112. if ( target.nodeName != 'LI' ) {
  113. return;
  114. }
  115. this.parent.uiChange();
  116. var index = this.dots.indexOf( target );
  117. this.parent.select( index );
  118. };
  119. PageDots.prototype.destroy = function() {
  120. this.deactivate();
  121. this.allOff();
  122. };
  123. Flickity.PageDots = PageDots;
  124. // -------------------------- Flickity -------------------------- //
  125. utils.extend( Flickity.defaults, {
  126. pageDots: true
  127. });
  128. Flickity.createMethods.push('_createPageDots');
  129. var proto = Flickity.prototype;
  130. proto._createPageDots = function() {
  131. if ( !this.options.pageDots ) {
  132. return;
  133. }
  134. this.pageDots = new PageDots( this );
  135. // events
  136. this.on( 'activate', this.activatePageDots );
  137. this.on( 'select', this.updateSelectedPageDots );
  138. this.on( 'cellChange', this.updatePageDots );
  139. this.on( 'resize', this.updatePageDots );
  140. this.on( 'deactivate', this.deactivatePageDots );
  141. };
  142. proto.activatePageDots = function() {
  143. this.pageDots.activate();
  144. };
  145. proto.updateSelectedPageDots = function() {
  146. this.pageDots.updateSelected();
  147. };
  148. proto.updatePageDots = function() {
  149. this.pageDots.setDots();
  150. };
  151. proto.deactivatePageDots = function() {
  152. this.pageDots.deactivate();
  153. };
  154. // ----- ----- //
  155. Flickity.PageDots = PageDots;
  156. return Flickity;
  157. }));