autoplay.js 5.8 KB

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