-
Notifications
You must be signed in to change notification settings - Fork 20
Open
Description
概述
position: sticky是新增的css属性,粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。
polyfill
其实这样的效果可以使用JS来实现,下面的链接就是我写的polyfill
/**
* position: sticky的polyfill
* 推荐在文档加载完成之后(‘DOMContentLoaded’事件)调用
* @param {String} selectors 选择器
* @param {String} top 距离顶部的偏移量
*/
function sticky(selectors, top = 0) {
let elements = document.querySelectorAll(selectors);
for (let i = 0; i < elements.length; ++i) {
elements[i].dataset['originOffsetTop'] = elements[i].getBoundingClientRect().top + ((window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop)
}
window.addEventListener('scroll', onScroll(elements, top));
function onScroll(elements, top) {
let shouldRun = true
return () => {
let scrollY = window.pageYOffset;
if (shouldRun) {
// 节流代码
shouldRun = false
for (let i = 0; i < elements.length; ++i) {
let element = elements[i];
console.log(element)
// 判断是relative条件还是fixed条件
if (element.dataset['originOffsetTop'] - scrollY <= top && !element.$isSticky) {
// fixed条件
fixed(element, top)
}
if (element.dataset['originOffsetTop'] - scrollY > top && element.$isSticky) {
// relative条件
element.$unFixed && element.$unFixed()
}
}
setTimeout(() => {
shouldRun = true
}, 100)
}
}
}
function fixed(element, top) {
let originCss = element.style.cssText;
element.style.cssText += ";position: fixed; top: " + top + "px;";
element.$isSticky = true
element.$unFixed = () => {
element.$isSticky = false
element.style.cssText = originCss;
}
}
}
思路
- 获取元素初始化时候的offsetTop,并存储在元素的dataset中
- 监听滚动条事件,并使用节流方式处理滚动事件处理器
- 在事件处理器里,获取浏览器的纵轴的滚动偏移量——
window.pageYOffset,然后跟元素的纵轴偏移量作比较,判断是否需要对元素做position: fixed处理,或者还原positon
因为需要把元素设置为 position: fixed;所以元素的width和height需要制定确切的值
API
该库仅对外提供一个接口:
/**
* position: sticky的polyfill
* 推荐在文档加载完成之后(‘DOMContentLoaded’事件)调用
* @param {String} selectors 选择器
* @param {String} top 距离顶部的偏移量
*/
function sticky(selectors, top = 0)
案例
可以在CodePen上看到效果。
参考
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels