autoplay.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /* eslint no-underscore-dangle: "off" */
  2. /* eslint no-use-before-define: "off" */
  3. import { getDocument } from 'ssr-window';
  4. import { nextTick } from '../../shared/utils.js';
  5. export default function Autoplay({
  6. swiper,
  7. extendParams,
  8. on,
  9. emit
  10. }) {
  11. let timeout;
  12. swiper.autoplay = {
  13. running: false,
  14. paused: false
  15. };
  16. extendParams({
  17. autoplay: {
  18. enabled: false,
  19. delay: 3000,
  20. waitForTransition: true,
  21. disableOnInteraction: true,
  22. stopOnLastSlide: false,
  23. reverseDirection: false,
  24. pauseOnMouseEnter: false
  25. }
  26. });
  27. function run() {
  28. const $activeSlideEl = swiper.slides.eq(swiper.activeIndex);
  29. let delay = swiper.params.autoplay.delay;
  30. if ($activeSlideEl.attr('data-swiper-autoplay')) {
  31. delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay;
  32. }
  33. clearTimeout(timeout);
  34. timeout = nextTick(() => {
  35. let autoplayResult;
  36. if (swiper.params.autoplay.reverseDirection) {
  37. if (swiper.params.loop) {
  38. swiper.loopFix();
  39. autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
  40. emit('autoplay');
  41. } else if (!swiper.isBeginning) {
  42. autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
  43. emit('autoplay');
  44. } else if (!swiper.params.autoplay.stopOnLastSlide) {
  45. autoplayResult = swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true);
  46. emit('autoplay');
  47. } else {
  48. stop();
  49. }
  50. } else if (swiper.params.loop) {
  51. swiper.loopFix();
  52. autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
  53. emit('autoplay');
  54. } else if (!swiper.isEnd) {
  55. autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
  56. emit('autoplay');
  57. } else if (!swiper.params.autoplay.stopOnLastSlide) {
  58. autoplayResult = swiper.slideTo(0, swiper.params.speed, true, true);
  59. emit('autoplay');
  60. } else {
  61. stop();
  62. }
  63. if (swiper.params.cssMode && swiper.autoplay.running) run();else if (autoplayResult === false) {
  64. run();
  65. }
  66. }, delay);
  67. }
  68. function start() {
  69. if (typeof timeout !== 'undefined') return false;
  70. if (swiper.autoplay.running) return false;
  71. swiper.autoplay.running = true;
  72. emit('autoplayStart');
  73. run();
  74. return true;
  75. }
  76. function stop() {
  77. if (!swiper.autoplay.running) return false;
  78. if (typeof timeout === 'undefined') return false;
  79. if (timeout) {
  80. clearTimeout(timeout);
  81. timeout = undefined;
  82. }
  83. swiper.autoplay.running = false;
  84. emit('autoplayStop');
  85. return true;
  86. }
  87. function pause(speed) {
  88. if (!swiper.autoplay.running) return;
  89. if (swiper.autoplay.paused) return;
  90. if (timeout) clearTimeout(timeout);
  91. swiper.autoplay.paused = true;
  92. if (speed === 0 || !swiper.params.autoplay.waitForTransition) {
  93. swiper.autoplay.paused = false;
  94. run();
  95. } else {
  96. ['transitionend', 'webkitTransitionEnd'].forEach(event => {
  97. swiper.$wrapperEl[0].addEventListener(event, onTransitionEnd);
  98. });
  99. }
  100. }
  101. function onVisibilityChange() {
  102. const document = getDocument();
  103. if (document.visibilityState === 'hidden' && swiper.autoplay.running) {
  104. pause();
  105. }
  106. if (document.visibilityState === 'visible' && swiper.autoplay.paused) {
  107. run();
  108. swiper.autoplay.paused = false;
  109. }
  110. }
  111. function onTransitionEnd(e) {
  112. if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;
  113. if (e.target !== swiper.$wrapperEl[0]) return;
  114. ['transitionend', 'webkitTransitionEnd'].forEach(event => {
  115. swiper.$wrapperEl[0].removeEventListener(event, onTransitionEnd);
  116. });
  117. swiper.autoplay.paused = false;
  118. if (!swiper.autoplay.running) {
  119. stop();
  120. } else {
  121. run();
  122. }
  123. }
  124. function onMouseEnter() {
  125. if (swiper.params.autoplay.disableOnInteraction) {
  126. stop();
  127. } else {
  128. pause();
  129. }
  130. ['transitionend', 'webkitTransitionEnd'].forEach(event => {
  131. swiper.$wrapperEl[0].removeEventListener(event, onTransitionEnd);
  132. });
  133. }
  134. function onMouseLeave() {
  135. if (swiper.params.autoplay.disableOnInteraction) {
  136. return;
  137. }
  138. swiper.autoplay.paused = false;
  139. run();
  140. }
  141. function attachMouseEvents() {
  142. if (swiper.params.autoplay.pauseOnMouseEnter) {
  143. swiper.$el.on('mouseenter', onMouseEnter);
  144. swiper.$el.on('mouseleave', onMouseLeave);
  145. }
  146. }
  147. function detachMouseEvents() {
  148. swiper.$el.off('mouseenter', onMouseEnter);
  149. swiper.$el.off('mouseleave', onMouseLeave);
  150. }
  151. on('init', () => {
  152. if (swiper.params.autoplay.enabled) {
  153. start();
  154. const document = getDocument();
  155. document.addEventListener('visibilitychange', onVisibilityChange);
  156. attachMouseEvents();
  157. }
  158. });
  159. on('beforeTransitionStart', (_s, speed, internal) => {
  160. if (swiper.autoplay.running) {
  161. if (internal || !swiper.params.autoplay.disableOnInteraction) {
  162. swiper.autoplay.pause(speed);
  163. } else {
  164. stop();
  165. }
  166. }
  167. });
  168. on('sliderFirstMove', () => {
  169. if (swiper.autoplay.running) {
  170. if (swiper.params.autoplay.disableOnInteraction) {
  171. stop();
  172. } else {
  173. pause();
  174. }
  175. }
  176. });
  177. on('touchEnd', () => {
  178. if (swiper.params.cssMode && swiper.autoplay.paused && !swiper.params.autoplay.disableOnInteraction) {
  179. run();
  180. }
  181. });
  182. on('destroy', () => {
  183. detachMouseEvents();
  184. if (swiper.autoplay.running) {
  185. stop();
  186. }
  187. const document = getDocument();
  188. document.removeEventListener('visibilitychange', onVisibilityChange);
  189. });
  190. Object.assign(swiper.autoplay, {
  191. pause,
  192. run,
  193. start,
  194. stop
  195. });
  196. }