资讯专栏INFORMATION COLUMN

Javascript零碎之各种宽高属性及应用

DevYK / 3497人阅读

摘要:一挂在上的上最常用的只有其中,永远都是窗口的大小,跟随窗口变化而变化。这个是距该元素最近的不为的祖先元素,如果没有则指向元素。

在Javascript的开发过程中,我们总会看到类似如下的边界条件判断(懒加载):

const scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;    
const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
const innerHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight 
   
if( scrollTop +innerHeight >= scrollHeight + 50) {
  console.log("滚动到底了!")
}

这些获取滚动状态的属性,可能我们咋一看能够理解,不过时间久了立马又忘记了。这是因为这些获取各种宽高的属性api及其的多,而且几乎都存在兼容性写法。一方面很难记,更重要的是不好理解。下面通过选取常用的几个来讲述下具体api的区别。

## 一 挂在window上的

window上最常用的只有window.innerWidth/window.innerHeight、window.pageXOffset/window.pageYOffset.

其中,window.innerWidth/windw.innerHeight永远都是窗口的大小,跟随窗口变化而变化。window.pageXOffset/window.pageYOffset是IE9+浏览器获取滚动距离的,实质跟document.documentElement/document.body上的scrollTop/scrollLeft功能一致,所以日常都使用兼容写法:

const scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
pageYOffset 属性实质是 window.scrollY 属性的别名,pageXOffset同理,为了跨浏览器兼容,一般用后者(pageYOffset、pageXOffset)。
二 挂在document上的 1 clientWidth/clientHeight:元素内部的宽高.

记住公式:

clientWidth/clientHeight = padding + content宽高 - scrollbar宽高(如有滚动条)
2 offsetWidth/offsetHeight

个人觉得这个名字有点误导人,压根没有偏移的意思,记住公式即可:

offsetWidth/offsetHeight = clientWidth/clientHeight(padding + content) + border + scrollbar

由上述公式,可以得到第一个示例,即"获取滚动条的宽度(scrollbar)":

const el = document.querySelect(".box")
const style = getComputedStyle(el, flase)//获取样式
const clientWidth = el.clientWidth, offsetWidth = el.offsetWidth
//parseFloat("10px", 10) => 10
const borderWidth = parseFloat(style.borderLeftWidth, 10) + parseFloat(style.borderRightWidth, 10)
const scrollbarW = offsetWidth - clientWidth - borderWidth
3 offsetTop/offsetLeft

这两个才是真的意如其名,指的是元素上侧或者左侧偏移它的offsetParent的距离。这个offsetParent是距该元素最近的position不为static的祖先元素,如果没有则指向body元素。说白了就是:"元素div往外找到最近的position不为static的元素,然后该div的边界到它的距离"。
由此,可以得到第二个示例,即"获得任一元素在页面中的位置":

const getPosition = (el) => {
    let left = 0, top = 0;

    while(el.offsetParent) {
        //获取偏移父元素的样式,在计算偏移的时候需要加上它的border
        const pStyle = getComputedStyle(el.offsetParent, false);
        left += el.offsetLeft + parseFloat(pStyle.borderLeftWidth, 10);
        top += el.offsetTop + parseFloat(pStyle.borderTopWidth, 10);
        el = el.offsetParent;
    }

    return { left, top }
}

那么,offsetLeft和style.left有什么区别呢?

offsetLeft 只读,可以返回没有定位盒子的距离左侧的位置,值为number,例100。

style.left 可读可写,但是读取时前提是设置过left,值为字符串,例:"100px"

所以,一般通用用法是:“用offsetLeft 和 offsetTop 获取值,用style.left 和 style.top 赋值”

综上,结合getBoundingClientRect()得到综合示例"元素是否在可视区域":

function isElemInViewport(el) {
    const rt = el.getBoundingClientRect();

    return (
        rt.top >=0 &&
        rt.left >= 0 &&
        rt.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rt.right <= (window.innerWidth || document.documentElement.clientWidth)
    )
}

其中,getBoundingClientRect用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置:

三 挂在event上的

event上面的相对距离一般是鼠标点击或者移动端触控事件获取的。

1 clientX clientY

鼠标或者触控点相对于可视窗口左上角为原点x轴和y轴的距离:

2 offsetX offsetY

鼠标或者触控点相对于元素本身宽高左上角为原点x轴和y轴的距离:

3 screenX screenY

鼠标或者触控点相对于屏幕显示器左上角为原点x轴和y轴的距离:

4 pageX pageY

鼠标或者触控点相对于页面内容左上角为原点x轴和y轴的距离:

需要注意的是,这两个属性存在兼容性问题:

pageX = event.pageX || event.x; //IE
pageY = event.pageY || event.y; //IE
本文收录在个人的Github上https://github.com/kekobin/bl... ,觉得有帮助的,欢迎start哈。支持原创,未经本人同意,请勿转载!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105101.html

相关文章

  • CSS零碎em、rem

    摘要:移动端的开发基本很少直接使用作为单位了,目前最常用的是。一般移动端页面的开发流程是设计人员以某个机型作为标准,设计好。前端开发针对这个机型的做开发,然后其它机型相对的去等比例缩放。 移动端的开发基本很少直接使用px作为单位了,目前最常用的是rem。不过在这之前其实还有个em单位,和rem长得非常的像,那么它们有什么区别呢?又有什么不一样的适用场景呢? 注意:无论使用em,还是rem,客...

    Faremax 评论0 收藏0
  • CSS零碎em、rem

    摘要:移动端的开发基本很少直接使用作为单位了,目前最常用的是。一般移动端页面的开发流程是设计人员以某个机型作为标准,设计好。前端开发针对这个机型的做开发,然后其它机型相对的去等比例缩放。 移动端的开发基本很少直接使用px作为单位了,目前最常用的是rem。不过在这之前其实还有个em单位,和rem长得非常的像,那么它们有什么区别呢?又有什么不一样的适用场景呢? 注意:无论使用em,还是rem,客...

    Integ 评论0 收藏0
  • Javascript零碎IntersectionObserver

    摘要:主要用于元素可见性的监听,比传统通过全局监听事件去判断可见性无论是性能还是便利性都要好得多。问题是这种通过监听的方式很容易导致性能问题,或者多多少少会有些性能损失。 IntersectionObserver主要用于元素可见性的监听,比传统通过全局监听scroll事件去判断可见性无论是性能还是便利性都要好得多。因为api比较新,存在兼容性问题,好在已经有了兼容的polyfill.其基本介...

    张迁 评论0 收藏0
  • JavaScript中的各种宽高位置总结

    摘要:和这一对属性是用来读取元素的的宽度和高度的。第二部分对象在中,对于元素的运动的操作通常都会涉及到对象,而对象也存在很多位置属性,且由于浏览器兼容性问题会导致这些属性间相互混淆,这里一一讲解。文章转自中的各种宽高以及位置总结 在javascript中操作dom节点让其运动的时候,常常会涉及到各种宽高以及位置坐标等概念,如果不能很好地理解这些属性所代表的意义,就不能理解js的运动原理,同时...

    microelec 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<