当前位置:   article > 正文

v-infinite-scroll 自定义属性

v-infinite-scroll
  1. 前言:在使用v-infinite-scroll 属性时 发现项目中并没有 此属性
  2. 解决:把v-infinite-scroll 源码放在.js文件中导出 使用
  3. 源码:
  4. const ctx = "@@InfiniteScroll";
  5. const throttle = function (fn, delay) {
  6. let now, lastExec, timer, context, args; //eslint-disable-line
  7. const execute = function () {
  8. fn.apply(context, args);
  9. lastExec = now;
  10. };
  11. return function () {
  12. context = this;
  13. args = arguments;
  14. now = Date.now();
  15. if (timer) {
  16. clearTimeout(timer);
  17. timer = null;
  18. }
  19. if (lastExec) {
  20. const diff = delay - (now - lastExec);
  21. if (diff < 0) {
  22. execute();
  23. } else {
  24. timer = setTimeout(() => {
  25. execute();
  26. }, diff);
  27. }
  28. } else {
  29. execute();
  30. }
  31. };
  32. };
  33. const getScrollTop = function (element) {
  34. if (element === window) {
  35. return Math.max(window.pageYOffset || 0, document.documentElement.scrollTop);
  36. }
  37. return element.scrollTop;
  38. };
  39. const getComputedStyle = document.defaultView.getComputedStyle;
  40. const getScrollEventTarget = function (element) {
  41. let currentNode = element;
  42. console.log("drawer:", element);
  43. // bugfix, see http://w3help.org/zh-cn/causes/SD9013 and http://stackoverflow.com/questions/17016740/onscroll-function-is-not-working-for-chrome
  44. while (currentNode && currentNode.tagName !== "HTML" && currentNode.tagName !== "BODY" && currentNode.nodeType === 1) {
  45. const overflowY = getComputedStyle(currentNode).overflowY;
  46. console.log("drawer:", overflowY);
  47. const overflowYStyle = currentNode.style.overflowY;
  48. console.log("drawer:", overflowYStyle);
  49. if (overflowY === "scroll" || overflowY === "auto" || overflowYStyle === "auto") {
  50. return currentNode;
  51. }
  52. console.log("drawer:", currentNode.parentNode);
  53. currentNode = currentNode.parentNode;
  54. }
  55. return currentNode;
  56. };
  57. const getVisibleHeight = function (element) {
  58. if (element === window) {
  59. return document.documentElement.clientHeight;
  60. }
  61. return element.clientHeight;
  62. };
  63. const getElementTop = function (element) {
  64. if (element === window) {
  65. return getScrollTop(window);
  66. }
  67. return element.getBoundingClientRect().top + getScrollTop(window);
  68. };
  69. const isAttached = function (element) {
  70. let currentNode = element.parentNode;
  71. while (currentNode) {
  72. if (currentNode.tagName === "HTML") {
  73. return true;
  74. }
  75. if (currentNode.nodeType === 11) {
  76. return false;
  77. }
  78. currentNode = currentNode.parentNode;
  79. }
  80. return false;
  81. };
  82. const doBind = function () {
  83. if (this.binded) return; // eslint-disable-line
  84. this.binded = true;
  85. const directive = this;
  86. const element = directive.el;
  87. console.log("directive:", directive, element.parentNode);
  88. const throttleDelayExpr = element.getAttribute("infinite-scroll-throttle-delay");
  89. let throttleDelay = 200;
  90. if (throttleDelayExpr) {
  91. throttleDelay = Number(directive.vm[throttleDelayExpr] || throttleDelayExpr);
  92. if (isNaN(throttleDelay) || throttleDelay < 0) {
  93. throttleDelay = 200;
  94. }
  95. }
  96. directive.throttleDelay = throttleDelay;
  97. directive.scrollEventTarget = getScrollEventTarget(element);
  98. directive.scrollListener = throttle(doCheck.bind(directive), directive.throttleDelay);
  99. directive.scrollEventTarget.addEventListener("scroll", directive.scrollListener);
  100. this.vm.$on("hook:beforeDestroy", function () {
  101. directive.scrollEventTarget.removeEventListener("scroll", directive.scrollListener);
  102. });
  103. const disabledExpr = element.getAttribute("infinite-scroll-disabled");
  104. let disabled = false;
  105. console.log("disabledExpr", disabledExpr);
  106. if (disabledExpr) {
  107. this.vm.$watch(disabledExpr, function (value) {
  108. directive.disabled = value;
  109. if (!value && directive.immediateCheck) {
  110. doCheck.call(directive);
  111. }
  112. });
  113. disabled = Boolean(directive.vm[disabledExpr]);
  114. }
  115. directive.disabled = disabled;
  116. const distanceExpr = element.getAttribute("infinite-scroll-distance");
  117. let distance = 0;
  118. if (distanceExpr) {
  119. distance = Number(directive.vm[distanceExpr] || distanceExpr);
  120. if (isNaN(distance)) {
  121. distance = 0;
  122. }
  123. }
  124. directive.distance = distance;
  125. const immediateCheckExpr = element.getAttribute("infinite-scroll-immediate-check");
  126. let immediateCheck = true;
  127. if (immediateCheckExpr) {
  128. immediateCheck = Boolean(directive.vm[immediateCheckExpr]);
  129. }
  130. directive.immediateCheck = immediateCheck;
  131. if (immediateCheck) {
  132. doCheck.call(directive);
  133. }
  134. const eventName = element.getAttribute("infinite-scroll-listen-for-event");
  135. if (eventName) {
  136. directive.vm.$on(eventName, function () {
  137. doCheck.call(directive);
  138. });
  139. }
  140. };
  141. const doCheck = function (force) {
  142. const scrollEventTarget = this.scrollEventTarget;
  143. const element = this.el;
  144. const distance = this.distance;
  145. if (force !== true && this.disabled) return; //eslint-disable-line
  146. const viewportScrollTop = getScrollTop(scrollEventTarget);
  147. const viewportBottom = viewportScrollTop + getVisibleHeight(scrollEventTarget);
  148. let shouldTrigger = false;
  149. if (scrollEventTarget === element) {
  150. shouldTrigger = scrollEventTarget.scrollHeight - viewportBottom <= distance;
  151. } else {
  152. const elementBottom = getElementTop(element) - getElementTop(scrollEventTarget) + element.offsetHeight + viewportScrollTop;
  153. shouldTrigger = viewportBottom + distance >= elementBottom;
  154. }
  155. if (shouldTrigger && this.expression) {
  156. this.expression();
  157. }
  158. };
  159. export default {
  160. // bind
  161. // bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  162. // inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  163. inserted(el, binding, vnode) {
  164. el[ctx] = {
  165. el,
  166. vm: vnode.context,
  167. expression: binding.value,
  168. };
  169. const args = arguments;
  170. doBind.call(el[ctx]);
  171. el[ctx].vm.$nextTick().then(function () {
  172. if (isAttached(el)) {
  173. doBind.call(el[ctx], args);
  174. }
  175. el[ctx].bindTryCount = 0;
  176. const tryBind = function () {
  177. if (el[ctx].bindTryCount > 10) return; //eslint-disable-line
  178. el[ctx].bindTryCount++;
  179. if (isAttached(el)) {
  180. doBind.call(el[ctx], args);
  181. } else {
  182. setTimeout(tryBind, 50);
  183. }
  184. };
  185. tryBind();
  186. });
  187. },
  188. unbind(el) {
  189. if (el && el[ctx] && el[ctx].scrollEventTarget) {
  190. el[ctx].scrollEventTarget.removeEventListener("scroll", el[ctx].scrollListener);
  191. }
  192. },
  193. };
  194. -------------------------------------------------------------------------------------
  195. v-infinite-scroll="onLazyLoad" 使用方法添加事件函数
  196. onLazyLoad(){
  197. ....................
  198. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/982896
推荐阅读
  

闽ICP备14008679号