vue-infinite-scroll 搭配使用ant-design-vue 弹窗dialog无法触发loadMore方法

1.弹窗启动时,未经过mounted生命周期,所以未绑定成功滚动事件

 

2.获得监听滚动函数的element时(getScrollEventTarget),也就是滚动的容器时,未能拿到overflowY的值,是根据这个值去返回当前滚动容器的元素。否则拿不到返回window的值

 

 

const ctx = '@@InfiniteScroll';
 
let throttle = function (fn, delay) {
  let now, lastExec, timer, context, args; //eslint-disable-line
 
  let execute = function () {
    fn.apply(context, args);
    lastExec = now;
  };
 
  return function () {
    context = this;
    args = arguments;
    now = Date.now();
 
    if (timer) {
      clearTimeout(timer);
      timer = null;
    }
 
    if (lastExec) {
      let diff = delay - (now - lastExec);
      if (diff < 0) {
        execute();
      } else {
        timer = setTimeout(() => {
          execute();
        }, diff);
      }
    } else {
      execute();
    }
  };
};
 
let getScrollTop = function (element) {
  if (element === window) {
    return Math.max(window.pageYOffset || 0, document.documentElement.scrollTop);
  }
 
  return element.scrollTop;
};
 
let getComputedStyle = document.defaultView.getComputedStyle;
 
let getScrollEventTarget = function (element) {
  let currentNode = element;
  // bugfix, see http://w3help.org/zh-cn/causes/SD9013 and http://stackoverflow.com/questions/17016740/onscroll-function-is-not-working-for-chrome
  while (currentNode && currentNode.tagName !== 'HTML' && currentNode.tagName !== 'BODY' && currentNode.nodeType === 1) {
    let overflowY = getComputedStyle(currentNode).overflowY;
    let overflowYStyle = currentNode.style.overflowY
    if (overflowY === 'scroll' || overflowY === 'auto' || overflowYStyle === 'auto') {
      return currentNode;
    }
    currentNode = currentNode.parentNode;
  }
  return currentNode;
};
 
let getVisibleHeight = function (element) {
  if (element === window) {
    return document.documentElement.clientHeight;
  }
 
  return element.clientHeight;
};
 
let getElementTop = function (element) {
  if (element === window) {
    return getScrollTop(window);
  }
  return element.getBoundingClientRect().top + getScrollTop(window);
};
 
let isAttached = function (element) {
  let currentNode = element.parentNode;
  while (currentNode) {
    if (currentNode.tagName === 'HTML') {
      return true;
    }
    if (currentNode.nodeType === 11) {
      return false;
    }
    currentNode = currentNode.parentNode;
  }
  return false;
};
 
let doBind = function () {
  if (this.binded) return; // eslint-disable-line
  this.binded = true;
 
  let directive = this;
  let element = directive.el;
 
  let throttleDelayExpr = element.getAttribute('infinite-scroll-throttle-delay');
  let throttleDelay = 200;
  if (throttleDelayExpr) {
    throttleDelay = Number(directive.vm[throttleDelayExpr] || throttleDelayExpr);
    if (isNaN(throttleDelay) || throttleDelay < 0) {
      throttleDelay = 200;
    }
  }
  directive.throttleDelay = throttleDelay;
 
  directive.scrollEventTarget = getScrollEventTarget(element);
  directive.scrollListener = throttle(doCheck.bind(directive), directive.throttleDelay);
  directive.scrollEventTarget.addEventListener('scroll', directive.scrollListener);
 
  this.vm.$on('hook:beforeDestroy', function () {
    directive.scrollEventTarget.removeEventListener('scroll', directive.scrollListener);
  });
 
  let disabledExpr = element.getAttribute('infinite-scroll-disabled');
  let disabled = false;
  console.log('disabledExpr', disabledExpr)
  if (disabledExpr) {
    this.vm.$watch(disabledExpr, function (value) {
      directive.disabled = value;
      if (!value && directive.immediateCheck) {
        doCheck.call(directive);
      }
    });
    disabled = Boolean(directive.vm[disabledExpr]);
  }
  directive.disabled = disabled;
 
  let distanceExpr = element.getAttribute('infinite-scroll-distance');
  let distance = 0;
  if (distanceExpr) {
    distance = Number(directive.vm[distanceExpr] || distanceExpr);
    if (isNaN(distance)) {
      distance = 0;
    }
  }
  directive.distance = distance;
 
  let immediateCheckExpr = element.getAttribute('infinite-scroll-immediate-check');
  let immediateCheck = true;
  if (immediateCheckExpr) {
    immediateCheck = Boolean(directive.vm[immediateCheckExpr]);
  }
  directive.immediateCheck = immediateCheck;
 
  if (immediateCheck) {
    doCheck.call(directive);
  }
 
  let eventName = element.getAttribute('infinite-scroll-listen-for-event');
  if (eventName) {
    directive.vm.$on(eventName, function () {
      doCheck.call(directive);
    });
  }
};
 
const doCheck = function (force) {
  let scrollEventTarget = this.scrollEventTarget;
  let element = this.el;
  let distance = this.distance;
 
  if (force !== true && this.disabled) return; //eslint-disable-line
  let viewportScrollTop = getScrollTop(scrollEventTarget);
  let viewportBottom = viewportScrollTop + getVisibleHeight(scrollEventTarget);
 
  let shouldTrigger = false;
 
  if (scrollEventTarget === element) {
    shouldTrigger = scrollEventTarget.scrollHeight - viewportBottom <= distance;
  } else {
    let elementBottom = getElementTop(element) - getElementTop(scrollEventTarget) + element.offsetHeight + viewportScrollTop;
 
    shouldTrigger = viewportBottom + distance >= elementBottom;
  }
 
  if (shouldTrigger && this.expression) {
    this.expression();
  }
};
 
export default {
  bind (el, binding, vnode) {
    el[ctx] = {
      el,
      vm: vnode.context,
      expression: binding.value
    };
    const args = arguments;
 
    doBind.call(el[ctx]);
    el[ctx].vm.$nextTick().then(function () {
      if (isAttached(el)) {
        doBind.call(el[ctx], args);
      }
 
      el[ctx].bindTryCount = 0;
 
      const tryBind = function () {
        if (el[ctx].bindTryCount > 10) return; //eslint-disable-line
        el[ctx].bindTryCount++;
        if (isAttached(el)) {
          doBind.call(el[ctx], args);
        } else {
          setTimeout(tryBind, 50);
        }
      };
      tryBind();
    });
  },
 
  unbind (el) {
    if (el && el[ctx] && el[ctx].scrollEventTarget) {
      el[ctx].scrollEventTarget.removeEventListener('scroll', el[ctx].scrollListener);
    }
  }
};
import infiniteScroll from './directive';
export default {
  directives: { infiniteScroll },
  components: {
    DetailsTitle
  },
}//将上述代码的js放在文件夹下,直接引用,其实就是把vue-infinate-scroll包里的js抽出来,自己改了,按照原来的用法用就行了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue-infinite-scroll 是一个 Vue.js 的插件,它可以帮助我们在滚动页面时加载更多的数据,实现无限滚动的效果。下面是在 Vue3 中使用 vue-infinite-scroll 的步骤: 1. 安装 vue-infinite-scroll: ``` npm install vue-infinite-scroll --save ``` 2. 在 main.js 中引入 vue-infinite-scroll: ```javascript import { createApp } from 'vue' import App from './App.vue' import infiniteScroll from 'vue-infinite-scroll' const app = createApp(App) app.use(infiniteScroll) app.mount('#app') ``` 3. 在需要使用无限滚动的组件中添加 v-infinite-scroll 指令: ```html <template> <div v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10"> <ul> <li v-for="item in items" :key="item.id">{{ item.title }}</li> </ul> </div> </template> <script> export default { data() { return { items: [], page: 1, busy: false } }, methods: { loadMore() { if (this.busy) return this.busy = true fetch('/api/getData?page=' + this.page) .then(res => res.json()) .then(data => { this.items = this.items.concat(data) this.page++ this.busy = false }) } } } </script> ``` 在上面的代码中,我们使用 v-infinite-scroll 指令来监听滚动事件,并调用 loadMore 方法来加载更多的数据。infinite-scroll-disabled 属性用来控制是否禁用无限滚动,infinite-scroll-distance 属性用来设置滚动到距离底部多少像素时触发加载更多数据的事件。 以上就是使用 vue-infinite-scroll 实现无限滚动的基本步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值