本来前段时间在整理关于vue组件封装、bind实现、promise实现的文章。但是由于篇幅有点大,并且笔记有些久远好多东西还要再更新下,所以就推迟了。就简单整理下最近自己写过的代码中比较有代表性的例子。
如何用js实现jq中的offset方法。
JQuery中的offset方法是获取当前元素上边框到document顶部距离的。
需要实现offset可以借助js中的offsetTop、offsetLeft。
js 的 offsetTop、offsetLeft 是用来访问一个 DOM 节点上边框相对其本身最近、且position值为非static的祖先元素的垂直和水平偏移量。
最后再借用递归就可以轻松实现了,代码如下
const offset = ele => {
let position
let result = {
top: 0,
left: 0
}
const getOffset = (node, init) => {
// 如果不是元素节点,则直接返回。nodeType=1为元素节点,
if (node.nodeType !== 1) {
return
}
// window.getComputedStyle获取元素的所有样式
position = window.getComputedStyle(node)['position']
// 如不是首次计算,并且position为static,继续计算父级
if (typeof (init) === 'undefined' && position === 'static') {
getOffset(node.parentNode)
return
}
// 减去node.scrollTop是因为,如果元素在一个带有滚动条的父元素内,则offsetTop会获取整个高度
// 如果滚动条不为0则需要减去已滚动的部分。
result.top += node.offsetTop - node.scrollTop
result.left += node.offsetLeft - node.scrollLeft
if (position === 'fixed') {
return
}
// 递归调用
getOffset(node.parentNode)
}
// 当前 DOM 节点的 display === 'none' 时, 直接返回 {top: 0, left: 0}
if (window.getComputedStyle(ele)['display'] === 'none') {
return result
}
getOffset(ele, true)
return result
}
代码非常简单易懂,但是在平时开发中很少会遇到这样的问题。不过在面试中这又是一个高频的考点,非常考验js基本功。实现方法有很多,在这就列举一种容易理解的,有兴趣的小伙伴可以自己尝试其他方式实现。
网友评论