JavaScript——BOM之元素的位置系列

116 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情

元素的位置系列

1.元素偏移量 offset 系列

offset 指偏移,我们使用 offset 系列相关属性,可以动态的得到元素的位置(偏移)、大小等。 该元素在文档中占用的所有显示宽度,包括borderpadding内容滚动条,不包括overflow隐藏的部分。

1.offset系列属性

offset系列属性说明
element.offsetParent返回该元素的祖先元素中、离自己最近的、有定位的元素(position为absolute/relative)。即返回该元素的最近的有定位的父级元素。如果父级元素都没有定位则返回body。
element.offsetTop返回该元素相对它的的最近的有定位的父级元素的上边框的偏移。即该元素上边框与父元素上边框的距离。返回的数值不带单位。
element.offsetLeft返回该元素相对它的的最近的有定位的父级元素的左边框的偏移。即该元素左边框与父元素左边框的距离。返回的数值不带单位。
element.offsetWidth返回该元素自身的宽度。返回的数值不带单位。 该元素自身的宽度 = 左右边框宽度 + 左右padding值 + 内容区宽度 offsetWidth = [border-width*2] + [padding-left] + [width] + [padding-right]
element.offsetHeight返回该元素自身的高度。返回的数值不带单位。 该元素自身的高度 = 上下边框宽度 + 上下padding值 + 内容区高度 offsetHeight = [border-width*2]+[padding-top]+[height]+[padding-bottom]

image-20210911203314.png

<style>
    * {
        margin: 0;
        padding: 0;
    }
​
    .father {
        /* position: relative; *//* 注意此行注释与否的的区别 */
        width: 200px;
        height: 200px;
        background-color: red;
        margin: 150px;
    }
​
    .son {
        width: 100px;
        height: 100px;
        background-color: blue;
        margin-left: 45px;
    }
​
    .d {
        width: 300px;
        height: 200px;
        background-color: green;
        margin: 0 auto 200px;
        padding: 10px;
        border: 15px solid orange;
    }
</style><div class="father">
    <div class="son"></div>
</div>
<div class="d"></div><script>
    /* 该元素的最近的有定位的父级元素——此处为body元素 */
    var father = document.querySelector('.father');
    console.log(father.offsetTop); //相对于body元素上边框的偏移
    console.log(father.offsetLeft); //相对于body元素左边框的偏移/* 该元素的最近的有定位的父级元素——此处为<div class="father">元素 */
    var son = document.querySelector('.son');
    console.log(son.offsetParent); //返回带有定位的父元素,否则返回的是body。
    console.log(son.parentNode); //返回父元素,不管父元素有没有定位。
    console.log(son.offsetTop); //相对于<div class="father">元素上边框的偏移
    console.log(son.offsetLeft); //相对于<div class="father">元素左边框的偏移/* 该元素自身的高度 */
    var d = document.querySelector('.d');
    console.log(d.offsetWidth); //350 = 15*2 + 10*2 + 300  (border*2 + padding*2 + width) 
    console.log(d.offsetHeight); //250 = 15*2 + 10*2 + 200 (border*2 + padding*2 +height)
</script>

2.offset和style的区别

1.offset能获取任意样式表中的值;style只能获取内联样式中的值。

2.offset获取的值是没有单位的;style获取的值是含有单位的字符串。

3.offsetWidth获取的值包含padding+border+width;style获取的值不包含padding+border。

4.offsetWidth是只读属性,只能获取值不能赋值;style既能获取值也能赋值。

因此获取元素大小位置,用offset更合适;改变属性值,需要用style属性。

3.案例_获取鼠标在盒子内的坐标

<style>
    .box {
        width: 300px;
        height: 300px;
        background-color: green;
        margin: 100px;
    }
</style><div class="box"></div><script>
    var box = document.querySelector('.box');
    box.onmousemove = function(e) {
        //鼠标在页面的x坐标-盒子在页面中的左偏移量(相对于body)
        var x = e.clientX - this.offsetLeft; 
        //鼠标在页面的y坐标-盒子在页面中的上偏移量(相对于body)
        var y = e.clientY - this.offsetTop; 
        this.innerHTML = 'x坐标是' + x + ' y坐标是' + y;
    }
</script>

2.元素可视区 client 系列

client 指元素本身的可视内容。我们使用 client 系列的相关属性,可以动态的得到元素的边框大小、元素大小等。 元素本身的可视内容,包括padding内容,不包括border、滚动条、overflow被折叠起来的部分。

1.client系列属性

client系列属性说明
element.clientTop返回元素上边框大小。即上边框的厚度,一般它的值就是0,因为滚动条不会出现在顶部。
element.clientLeft返回元素左边框大小。即左边框的厚度,一般它的值就是0,因为滚动条不会出现在左侧。
element.clientWidth返回元素自身可见的宽度。返回的数值不带单位。 该元素自身可见的宽度 = 左右padding值 + 内容区宽度 clientWidth = [padding-left] + [width] + [padding-right]
element.clientHeight返回该元素自身可见的高度。返回的数值不带单位。 该元素自身可见的高度 = 上下padding值 + 内容区高度 offsetHeight = [padding-top] + [height] + [padding-bottom]

image-20210911203315.png

<style type="text/css">
    p {
        width: 200px;
        height: 150px;
        border: 1px solid red;
        padding: 5px;
        overflow: scroll;
    }
</style><p>
    前端(Frontend):指涉及浏览器中直接运行或与浏览器直接相关的HTML标签、CSS样式、JavaScript脚本等各方面内容。Web设计系列课程中涉及的内容,都属于前端开发内容。如果是前端设计,就还包括图片设计,用户体验设计等(这部分不在我们课程内容中)。
</p><script>
    var p = document.querySelector('p');
    console.log(p.clientTop); //1
    console.log(p.clientLeft); //1
    console.log(p.clientWidth); //189 = 5*2 + (200 - 滚动条宽度) (padding*2 + width)
    console.log(p.clientHeight); //139 = 5*2 + (150 - 滚动条高度) (padding*2 + height)
    console.log(p.offsetWidth); //212 = 1*2 + 5*2 + 200  (border*2 + padding*2 + width) 
    console.log(p.offsetHeight); //162 = 1*2 + 5*2 + 150 (border*2 + padding*2 + height)
</script>

3.元素滚动 scroll 系列

scroll指滚动,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。 元素本身的实际宽度,包括padding内容overflow被折叠起来的部分,不包括border、滚动条。

1.scroll系列属性

scroll系列属性说明
element.scrollTop返回被卷去的上侧距离。返回值不带单位。 用于获取或设置位于对象最顶端和窗口中可见内容的最顶端之间的距离。
element.scrollLeft返回被卷去的左侧距离。返回值不带单位。 用于获取或设置位于对象左边界和窗口中目前可见内容的最左端之间的距离。
element.scrollWidth返回元素的滚动宽度,即元素的实际宽度。返回值不带单位 该元素的滚动宽度 = 左右padding值 + 内容区宽度 + overflow的宽度 scrollWidth = [padding-left] + [width] + [overflow] + [padding-right]
element.scrollHeight返回元素的滚动高度,即元素的实际高度。返回值不带单位 该元素的滚动高度 = 上下padding值 + 内容区高度 + overflow的高度 scrollHeight = [padding-top] + [width] + [overflow] + [padding-bottom]

image-20210911203316.png

(承接上面)
<script>
    p.scrollTop = p.scrollHeight; //设置滚动条自动滚动到最底部。
    console.log(p.scrollTop);
    console.log(p.scrollLeft);
    console.log(p.scrollWidth); //189 = 5*2 + (200 - 滚动条宽度) + 0 (padding*2 + width + overflow)
    console.log(p.scrollHeight); //262 = 5*2 + (150 - 滚动条高度) + 123 (padding*2 + height + overflow)
</script>

滚动条在滚动时会触发 onscroll事件。

(承接上面)
<script>
    p.onscroll = function() {
        console.log(p.scrollTop);
    }
</script>

2.页面被卷去的头部

如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。 当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。 页面被卷去的头部,有兼容性问题,根据情况不同,被卷去的头部通常有如下几种写法: ①声明了 DTD(我们用的是标准型:),使用 document.documentElement.scrollTop。 ②未声明 DTD,使用  document.body.scrollTop。 ③新方法 window.pageXOffset 和 window.pageYOffset,IE9 开始支持。

兼容性解决方案:

function getScroll() {
    return {
        left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft||0,
        top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
    };
} 
使用的时候:getScroll().left

scroll系列属性2:

scroll系列属性2说明
window.pageXOffset返回文档在窗口左上角水平方向滚动的像素。等价于 scrollX。 用于获取或设置当前页面相对于窗口显示区左上角的 X 位置。
window.pageYOffset返回文档在窗口左上角垂直方向滚动的像素。等价于 scrollXY。 用于获取或设置当前页面相对于窗口显示区左上角的 Y 位置。
(承接上面,多复制几次<p>元素让页面出现滚动条)
<script>
    window.onscroll = function() {
        console.log(document.documentElement.scrollTop); //有<!DOCTYPE html>方有效果
        console.log(document.body.scrollTop); //注释掉<!DOCTYPE html>方有效果
        console.log(window.pageXOffset); //0
        console.log(window.scrollX); //0
        console.log(window.pageYOffset);
        console.log(window.scrollY);
    }
<script>