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抽出来,自己改了,按照原来的用法用就行了

猜你喜欢

转载自blog.csdn.net/LoveHaixin/article/details/129058325