携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情
💻文档地址:ahooks.js.org/zh-CN/
👨💻github地址:github.com/alibaba/hoo…
document.scrollingElement:Document 的只读属性,返回滚动文档的 Element 对象的引用。 在标准模式下,这是文档的根元素。
Element.scrollLeft:属性可以读取或设置元素滚动条到元素左边的距离。
Element.scrollTop:属性可以获取或设置一个元素的内容垂直滚动的像素数。
window.pageYOffset:pageYOffset 属性是 scrollY 属性的别名。
监听当前元素的滚动事件,判断当前元素不是 document 的时候,获取该元素的 scrollLeft 和 scrollTop。
function useScroll(
target?: Target,
): Position | undefined {
const [position, setPosition] = useRafState<Position>();
useEffect(() => {
const el = getTargetElement(target, document);
if (!el) {
return;
}
const updatePosition = () => {
let newPosition: Position;
if (el === document) {
// ...
} else {
newPosition = {
left: (el as Element).scrollLeft,
top: (el as Element).scrollTop,
};
}
};
updatePosition();
el.addEventListener('scroll', updatePosition);
return () => {
el.removeEventListener('scroll', updatePosition);
};
}, [])
return position;
}
export default useScroll;
scrollingElement 返回滚动文档的 Element 对象的引用。
在标准模式下,这是文档的根元素, document.documentElement。当在怪异模式下, scrollingElement 属性返回 HTML body 元素(若不存在返回 null )。
怪异模式和标准模式
目前浏览器的排版引擎使用三种模式:怪异模式(Quirks mode)、接近标准模式(Almost standards mode)、以及标准模式(Standards mode)。
浏览器如何决定使用哪个模式
浏览器使用文件开头的 DOCTYPE 来决定用怪异模式处理或标准模式处理。<!DOCTYPE html>,是所有可用的 DOCTYPE 之中最简单的,也是 HTML5 所推荐的。当今的浏览器都会对这个 DOCTYPE 使用标准模式,就算是早已过时的 Internet Explorer 6 也一样。
分成了两种情况进行赋值。
if (document.scrollingElement) {
newPosition = {
left: document.scrollingElement.scrollLeft,
top: document.scrollingElement.scrollTop,
};
} else {
newPosition = {
left: Math.max(
window.pageYOffset,
document.documentElement.scrollTop,
document.body.scrollTop,
),
top: Math.max(
window.pageXOffset,
document.documentElement.scrollLeft,
document.body.scrollLeft,
),
};
}
动态控制,监听滚动的状态。shouldUpdate 是一个函数,返回一个 bool 值。shouldUpdateRef.current 是函数,当前的 position 如果满足条件,则继续更新坐标。
const shouldUpdateRef = useLatest(shouldUpdate);
const updatePosition = () => {
let newPosition: Position;
// ...
if (shouldUpdateRef.current(newPosition)) {
setPosition(newPosition);
}
};