跟随Element学习Vue小技巧(56)——InfiniteScroll

988 阅读4分钟

人生要是无憾

那该多无趣

前言

1 InfiniteScroll

变动观察器 MutationObserver

代码片段

if (immediate) {
  const observer = el[scope].observer = new MutationObserver(onScroll);
  observer.observe(container, { childList: true, subtree: true });
  onScroll();
}

技巧解析

可监听的事件有哪些呢?
鼠标,键盘,手势,合成...
DOM变化也可以监听吗?
有了MutationObserver,就可以啦
1.构造观察器,传入触发事件
2.执行观察,配置观察要素
childList,同时监听子元素变化
subtree,同事监听所有后代节点
注意,subtree不能单独出现,必须带上其中一个,即childList(DOM元素),attributes(元素属性),characterData(文本内容)

Mutation Observer 传送门

三大家族

代码片段

const getClientHeight = el => {
  return getPositionSize(el, 'clientHeight');
};
const scrollBottom = container.scrollTop + getClientHeight(container);
shouldTrigger = container.scrollHeight - scrollBottom <= distance;

技巧解析

offsetHeight、scrollHeight、clientHeight,什么东东???
clientHeight = height + padding
offsetHeight = clientHeight + border
scrollHeight = offsetHeight + scrollTop + 下边隐藏的高度 offsetTop:盒子顶部与父级盒子顶部距离
scrollTop:向上卷曲的距离 (想象窗帘)
scrollHeight === scrollTop + clientHeight,即往上卷,卷啊卷,终于接触到底部了,无法再卷了 ╮(╯▽╰)╭

彻底弄清元素的offsetHeight、scrollHeight、clientHeight

小工具

handleScroll

代码片段

/*
* @ {desc} 上拉刷新,即触底时触发刷新
* @ {params} cb,刷新回调
* @ {example}
*/
const handleScroll = function(cb) {
  const { el, vm, container, observer } = this[scope];
  const { distance, disabled } = getScrollOptions(el, vm);

  if (disabled) return;

  const containerInfo = container.getBoundingClientRect();
  if (!containerInfo.width && !containerInfo.height) return;

  let shouldTrigger = false;

  if (container === el) {
    // be aware of difference between clientHeight & offsetHeight & window.getComputedStyle().height
    const scrollBottom = container.scrollTop + getClientHeight(container);
    shouldTrigger = container.scrollHeight - scrollBottom <= distance;
  } else {
    const heightBelowTop = getOffsetHeight(el) + getElementTop(el) - getElementTop(container);
    const offsetHeight = getOffsetHeight(container);
    const borderBottom = Number.parseFloat(getStyleComputedProperty(container, 'borderBottomWidth'));
    shouldTrigger = heightBelowTop - offsetHeight + borderBottom <= distance;
  }

  if (shouldTrigger && isFunction(cb)) {
    cb.call(vm);
  } else if (observer) {
    observer.disconnect();
    this[scope].observer = null;
  }
};



原来两个人肩并肩坐在一起 也会走散

参考链接

往期回顾