observe-image.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*!
  2. * better-scroll / observe-image
  3. * (c) 2016-2021 ustbhuangyi
  4. * Released under the MIT License.
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  8. typeof define === 'function' && define.amd ? define(factory) :
  9. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ObserveImage = factory());
  10. }(this, (function () { 'use strict';
  11. // ssr support
  12. var inBrowser = typeof window !== 'undefined';
  13. var ua = inBrowser && navigator.userAgent.toLowerCase();
  14. !!(ua && /wechatdevtools/.test(ua));
  15. ua && ua.indexOf('android') > 0;
  16. /* istanbul ignore next */
  17. ((function () {
  18. if (typeof ua === 'string') {
  19. var regex = /os (\d\d?_\d(_\d)?)/;
  20. var matches = regex.exec(ua);
  21. if (!matches)
  22. return false;
  23. var parts = matches[1].split('_').map(function (item) {
  24. return parseInt(item, 10);
  25. });
  26. // ios version >= 13.4 issue 982
  27. return !!(parts[0] === 13 && parts[1] >= 4);
  28. }
  29. return false;
  30. }))();
  31. /* istanbul ignore next */
  32. var supportsPassive = false;
  33. /* istanbul ignore next */
  34. if (inBrowser) {
  35. var EventName = 'test-passive';
  36. try {
  37. var opts = {};
  38. Object.defineProperty(opts, 'passive', {
  39. get: function () {
  40. supportsPassive = true;
  41. },
  42. }); // https://github.com/facebook/flow/issues/285
  43. window.addEventListener(EventName, function () { }, opts);
  44. }
  45. catch (e) { }
  46. }
  47. var extend = function (target, source) {
  48. for (var key in source) {
  49. target[key] = source[key];
  50. }
  51. return target;
  52. };
  53. var elementStyle = (inBrowser &&
  54. document.createElement('div').style);
  55. var vendor = (function () {
  56. /* istanbul ignore if */
  57. if (!inBrowser) {
  58. return false;
  59. }
  60. var transformNames = [
  61. {
  62. key: 'standard',
  63. value: 'transform',
  64. },
  65. {
  66. key: 'webkit',
  67. value: 'webkitTransform',
  68. },
  69. {
  70. key: 'Moz',
  71. value: 'MozTransform',
  72. },
  73. {
  74. key: 'O',
  75. value: 'OTransform',
  76. },
  77. {
  78. key: 'ms',
  79. value: 'msTransform',
  80. },
  81. ];
  82. for (var _i = 0, transformNames_1 = transformNames; _i < transformNames_1.length; _i++) {
  83. var obj = transformNames_1[_i];
  84. if (elementStyle[obj.value] !== undefined) {
  85. return obj.key;
  86. }
  87. }
  88. /* istanbul ignore next */
  89. return false;
  90. })();
  91. /* istanbul ignore next */
  92. function prefixStyle(style) {
  93. if (vendor === false) {
  94. return style;
  95. }
  96. if (vendor === 'standard') {
  97. if (style === 'transitionEnd') {
  98. return 'transitionend';
  99. }
  100. return style;
  101. }
  102. return vendor + style.charAt(0).toUpperCase() + style.substr(1);
  103. }
  104. function addEvent(el, type, fn, capture) {
  105. var useCapture = supportsPassive
  106. ? {
  107. passive: false,
  108. capture: !!capture,
  109. }
  110. : !!capture;
  111. el.addEventListener(type, fn, useCapture);
  112. }
  113. function removeEvent(el, type, fn, capture) {
  114. el.removeEventListener(type, fn, {
  115. capture: !!capture,
  116. });
  117. }
  118. vendor && vendor !== 'standard' ? '-' + vendor.toLowerCase() + '-' : '';
  119. var transform = prefixStyle('transform');
  120. var transition = prefixStyle('transition');
  121. inBrowser && prefixStyle('perspective') in elementStyle;
  122. ({
  123. transform: transform,
  124. transition: transition,
  125. transitionTimingFunction: prefixStyle('transitionTimingFunction'),
  126. transitionDuration: prefixStyle('transitionDuration'),
  127. transitionDelay: prefixStyle('transitionDelay'),
  128. transformOrigin: prefixStyle('transformOrigin'),
  129. transitionEnd: prefixStyle('transitionEnd'),
  130. transitionProperty: prefixStyle('transitionProperty'),
  131. });
  132. var EventRegister = /** @class */ (function () {
  133. function EventRegister(wrapper, events) {
  134. this.wrapper = wrapper;
  135. this.events = events;
  136. this.addDOMEvents();
  137. }
  138. EventRegister.prototype.destroy = function () {
  139. this.removeDOMEvents();
  140. this.events = [];
  141. };
  142. EventRegister.prototype.addDOMEvents = function () {
  143. this.handleDOMEvents(addEvent);
  144. };
  145. EventRegister.prototype.removeDOMEvents = function () {
  146. this.handleDOMEvents(removeEvent);
  147. };
  148. EventRegister.prototype.handleDOMEvents = function (eventOperation) {
  149. var _this = this;
  150. var wrapper = this.wrapper;
  151. this.events.forEach(function (event) {
  152. eventOperation(wrapper, event.name, _this, !!event.capture);
  153. });
  154. };
  155. EventRegister.prototype.handleEvent = function (e) {
  156. var eventType = e.type;
  157. this.events.some(function (event) {
  158. if (event.name === eventType) {
  159. event.handler(e);
  160. return true;
  161. }
  162. return false;
  163. });
  164. };
  165. return EventRegister;
  166. }());
  167. var isImageTag = function (el) {
  168. return el.tagName.toLowerCase() === 'img';
  169. };
  170. var ObserveImage = /** @class */ (function () {
  171. function ObserveImage(scroll) {
  172. this.scroll = scroll;
  173. this.refreshTimer = 0;
  174. this.init();
  175. }
  176. ObserveImage.prototype.init = function () {
  177. this.handleOptions(this.scroll.options.observeImage);
  178. this.bindEventsToWrapper();
  179. };
  180. ObserveImage.prototype.handleOptions = function (userOptions) {
  181. if (userOptions === void 0) { userOptions = {}; }
  182. userOptions = (userOptions === true ? {} : userOptions);
  183. var defaultOptions = {
  184. debounceTime: 100,
  185. };
  186. this.options = extend(defaultOptions, userOptions);
  187. };
  188. ObserveImage.prototype.bindEventsToWrapper = function () {
  189. var wrapper = this.scroll.scroller.wrapper;
  190. this.imageLoadEventRegister = new EventRegister(wrapper, [
  191. {
  192. name: 'load',
  193. handler: this.load.bind(this),
  194. capture: true,
  195. },
  196. ]);
  197. this.imageErrorEventRegister = new EventRegister(wrapper, [
  198. {
  199. name: 'error',
  200. handler: this.load.bind(this),
  201. capture: true,
  202. },
  203. ]);
  204. };
  205. ObserveImage.prototype.load = function (e) {
  206. var _this = this;
  207. var target = e.target;
  208. var debounceTime = this.options.debounceTime;
  209. if (target && isImageTag(target)) {
  210. if (debounceTime === 0) {
  211. this.scroll.refresh();
  212. }
  213. else {
  214. clearTimeout(this.refreshTimer);
  215. this.refreshTimer = window.setTimeout(function () {
  216. _this.scroll.refresh();
  217. }, this.options.debounceTime);
  218. }
  219. }
  220. };
  221. ObserveImage.pluginName = 'observeImage';
  222. return ObserveImage;
  223. }());
  224. return ObserveImage;
  225. })));