滚动(scroll)tips

3.25

介绍

滚动是常见的交互方式。包含页面、容器、元素,滚动距离、滚动条等概念。

滚动距离关系

Element.scrollTop是有滚动条元素的垂直滚动距离。用来表示元素顶部到已滚动内容顶部的距离。当元素在顶部或没有滚动条时,值为0

可交互的例子

图片示例

scorll img

场景

元素滚动到顶部

scrollIntoView

element.scrollIntoView({behavior: 'smooth', block: 'start'});

offsetTop

offsetTop 是当前元素到父元素(offsetParent)的相对距离。使用offsetTop属性和 scrollTo方法。

// 需要滚动到顶部的元素
const dom = document.querySelector('.class');

container.scrollTo({
  top: dom.offsetTop,
  behavior: 'smooth',
});

直接控制容器的滚动条

const container = document.querySelector('.container')
container.scrollTop = top;

offsetParent order

  • the nearest positioned ancestor element
  • td, th, table
  • body

<body>如果设置了overflow-x: hidden,会导致滚动失效。需要去掉该样式。

让容器滚动到底部

参考

const dom = document.querySelector('.class')
dom.scrollTop = dom.scrollHeight - dom.clientHeight;

判断元素接近底部

const div = document.getElementById(id);
if (div.scrollHeight - div.scrollTop - div.clientHeight < 1) {
  console.log('near bottom!');
}

// 针对 window 和 document.body
const innerHeight = window.innerHeight // 或者 document.body.clientHeight
if (document.body.scrollHeight - window.scrollY - innerHeight < 100) {
  console.log('near bottom!');
}

判断元素的位置

在滚动过程中,可能需要确定某个元素所处的位置,例如接近顶部。可以使用getBoundingClientRect()方法,获取到 viewport 的绝对距离。

scrollElement.addEventListener('scroll', event => {
  const target = document.getElementById(id);
  const rect = target.getBoundingClientRect();
  if (rect.top < 100) {
    // near top
  }

  if (rect.bottom > 800) {
    // near bottom
  }
}, { passive: true });

跨平台滚动(手机和桌面等)

移动端(webview):window.scrollTo(x, y)

浏览器:window.scrollTo(options)

if (platform === 'app') {
  window.scrollTo(0, top);
} else {
  window.scrollTo({
    top,
    behavior: 'smooth',
  });
}

touch events

touchmove, touchstart, touchend 等事件,在移动平台也可以用来检测页面滚动(pageY)或滑动(pageX)

element.addEventListener('touchstart', event => {
  // event.changedTouches[0].pageY
});

element.addEventListener('touchend', event => {
  // event.changedTouches[0].pageY
});

element.addEventListener('touchmove', event => {
  // event.touches[0].pageY
});

提升滚动性能

Passive event listeners: 当确定不会调用 preventDefault 时,设置被动式监听事件,可以显著提升浏览器的滚动性能。

Throttle/Debounce: 可以设置响应函数的调用间隔。

target.addEventListener(type, listener, { passive: true });

Improving scrolling performance with passive listeners

ios Modal 滚动卡顿解决方案

overflow: scroll;
-webkit-overflow-scrolling: touch;

滚动距离关系

Element.scrollTop是有滚动条元素的垂直滚动距离。用来表示元素顶部到已滚动内容顶部的距离。当元素在顶部或没有滚动条时,值为0

可交互的例子

图片示例

scorll img

📖