Web APIs 学习笔记(七)--- offset、client和scroll系列属性

一、元素偏移量 offset 系列属性

1、offset 概述

​ offset系列属性可以动态的获得页面中某元素的偏移量,也就是元素位置,以及元素的宽度高度等属性。但是要注意,获得的元素的偏移量是元素相对于带有定位的父元素的位置,如果没有带定位的父元素,则是相对于页面的位置。而且获得的元素的宽度和高度是包括元素的border、padding的。最后所有属性的返回值都是数值型,不带单位,而且如果元素的offset系列属性是小数,如:22.5,则通过offset系列获取的值会向上取整。

2、offset系列属性

在这里插入图片描述
在这里插入图片描述

​ 总结:
offsetWidth=width+padding+border

offsetHeight=height+padding+border

// 案例代码

// 获得鼠标指针在盒子内的坐标以及盒子的宽高
<div class="box"></div>
<script>
    var box = document.querySelector('.box');
    box.addEventListener('mousemove', function(e) {
    var x = e.pageX - this.offsetLeft;
    var y = e.pageY - this.offsetTop;
    var h = this.offsetHeight;
    var w = this.offsetWidth;
    this.innerHTML = 'x坐标是' + x + ' y坐标是' + y + '盒子高度是' + h + '盒子宽度是' + w;
    })
</script>
3、offset和style的区别

​ ① offset 可以获得任意样式表中元素的宽高等样式的值,而style只能获得行内样式表中的所有样式值。

​ ② offsetWidth等属性获得样式值都是没有单位的数值型,而style.width等属性获得的样式值是带有单位的字符串型

​ ③ offsetWidth 包含padding+border+width ,而style.width 不包含padding和border 的值,只是width的值。

​ ④ offsetWidth 等属性是只读属性,只能获取不能赋值,而style.width 是可读写属性,既可以获取也可以赋值。所以如果我们只是想获取元素大小位置,用offset;如果我们想更改元素的大小位置,用style。

二、元素可视区 client 系列

1、client概述

​ client 系列相关属性可以动态的获得元素可视区的相关信息,比如: 元素边框的大小、元素本身的大小等。获得的元素的宽度和高度是包括元素的padding不包括元素的border的。而且所有属性的返回值都是数值型,不带单位。

2、client系列属性

在这里插入图片描述
在这里插入图片描述

​ 总结:
clientWidth=width+padding

clientHeight=height+padding

// 案例代码

// 获得盒子的宽高以及上边框、左边框
<div class="box"></div>
<script>
	var box = document.querySelector('.box');
    var t = box.clientTop;
    var l = box.clientLeft;
    var h = box.clientHeight;
    var w = box.clientWidth;
    console.log('上边框的宽度'+ t + '左边框的宽度' + l + '高度(不包含border)' + h + '宽度(不包含border)' + w);
</script>

三、元素滚动scroll系列属性

1、scroll 概述

​ scroll 系列的相关属性可以动态的获得元素的大小、滚动距离等。获得的元素的宽度和高度是包括滚动条隐藏的部分以及显示出来的部分的实际的宽度和高度,而且包括元素的padding不包含元素的border的。所有属性的返回值都是数值型,不带单位。

2、scroll 系列属性

在这里插入图片描述
在这里插入图片描述

​ 总结:
scrollWidth=width+padding

scrollHeight=height+padding

// 案例代码

// 获得盒子的实际宽高以及元素被卷去的头部和左侧
<div class="box"></div>
<script>
	var box = document.querySelector('.box');
    var t = box.scrollTop;
    var l = box.scrollLeft;
    var h = box.scrolHeight;
    var w = box.scrollWidth;
    console.log('元素被卷去的头部'+ t + '元素被卷去的左侧' + l + '实际高度(不包含border)' + h + '实际宽度(不包含border)' + w);
</script>
3、页面滚动

​ 如果浏览器的高度或者宽度小于页面的高度或宽度,窗口就会自动出现滚动条。当页面开始滚动时,页面被隐藏掉的高度,我们就称为页面被卷去的头部。而且页面滚动时会触发 scroll 事件,因为是页面滚动,所以事件源是document

​ 注意:页面被卷去的头部和元素被卷去的头部是不一样的。元素被卷去的头部通过 element.scrollTop 获得,页面被卷去的头部通过 window.pageYOffset 获得。同理,元素被卷去的左侧是 element.scrollLeft ,页面被卷去的左侧是 window.pageXOffset 。而且可以通过 window.scroll(x,y) 方法直接滚动到页面的某个位置。

后续补充:
Window.scrollTo(x,y) : 滚动到页面的某个坐标中去,与window.scroll(x,y) 作用相同,两个参数都为数字型,分别是文档中的横轴坐标和文档中的纵轴坐标。但是该方法有第二种形式的参数,window.scrollTo(options),options包含三个属性:top - 相对于页面顶部的距离,相当于前面的 y、left - 相对于页面左侧的距离,相当于前面的 x、behavior - 类型String,表示滚动行为动画,支持参数 smooth(平滑滚动),instant(瞬间滚动),默认值auto,auto的效果与instant相同。比window.scroll() 的优秀之处就在于平滑的滚动动画,可以应用于页面的导航跳转等场景。
但是该方法的window.scrollTo(options)形式在IE11及以下版本不兼容,只支持Window.scrollTo(x,y)形式,所以要相兼容IE则需要做好兼容性处理:

 // 解决scrollTo behavior 缓动动画不兼容问题
 // 判断document中是否存在scrollBehavior属性 存在则支持缓动动画 否则不支持
const supportsNativeSmoothScroll = 'scrollBehavior' in document.documentElement.style
if (supportsNativeSmoothScroll) {
	console.log('这里支持缓动动画')
	window.scrollTo({
		top: 100,
		behavior: 'smooth'
	})
} else {
	console.log('这里不支持缓动动画')
	window.scrollTo(0, 100)
}

而且该方法的滚动动画在ios中不兼容,滚动行为兼容,会议瞬间滚动的形式呈现。如果想要在ios中兼容滚动动画可以通过下面的方法:

// 前提:Vue项目 或 Nuxt项目 

// 1、安装转插件
yarn add smoothscroll-polyfill 或者 npm i smoothscroll-polyfill
// 2、在需要滚动效果的页面引入
import smoothscroll from 'smoothscroll-polyfill';
// 3、在点击滚动到页面某位置的事件中 执行下面方法
smoothscroll.polyfill();

四、总结

在这里插入图片描述

主要应用场景:
  1. offset系列 通常应用于获得元素的位置, offsetLeft offsetTop。

  2. client系列 通常应用于获得元素的大小 ,clientWidth clientHeight。

  3. scroll系列 通常应用于获取元素的滚动距离, scrollTop scrollLeft 。

  4. 页面的滚动距离通过 window.pageYOffsetwindow.pageXOffset 获得。

  5. 都有一个共同点,返回值都是数字且不带单位。

  6. 获取页面在Y轴上的滚动距离,可以通过window.pageYOffsetdocument.documentElement.scrollTopdocument.body.scrollTop 三种方式。

后续补充:

1、不同浏览器兼容获取页面在Y轴上的滚动距离的方法:
① IE8及以下:支持 document.documentElement.scrollTop
② IE9及以上:支持 document.documentElement.scrollTopwindow.pageYOffset
③ Safari:支持document.body.scrollTopwindow.pageYOffset
④ Chrome: 支持document.body.scrollTop(低版本,已验证的有:Chrome/55.0)document.documentElement.scrollTop(高版本,已验证的有:Chrome/63.0)window.pageYOffset
⑤ Firefox: 支持 document.documentElement.scrollTopwindow.pageYOffset

2、兼容写法:

// 无论移动端还是pc都可以兼容
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

因为这两个方法有个特殊点,就是同时只会有一个值生效。比如document.body.scrollTop能取到值的时候,document.documentElement.scrollTop就会始终为0;反之亦然。所以可通过该特性来兼容的获取 scrollTop 的值。
3、踩坑经历:
最近写了一个移动端的h5页面,是嵌入到app里面的,安卓端使用的document.documentElement.scrollTop没有任何问题,但是ios端document.documentElement.scrollTo 的值一直是0,于是改用document.body.scrollTop,在我测试的6p机型上兼容了,于是我信心满满的提测了,但是过了一会儿测试提刀上门了…
发现6s机型和XR机型,document.body.scrollTop 不起作用,应该是不兼容。最后还是使用了上面的兼容写法,才得以从测试的刀下逃生。所以建议大家都是用兼容写法。

五、仿淘宝侧边栏综合案例

案例要求:
  1. 原先侧边栏是绝对定位
  2. 当页面滚动到一定位置,侧边栏改为固定定位
  3. 页面继续滚动,会让 返回顶部显示出来
案例代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .slider-bar {
            position: absolute;
            left: 50%;
            top: 300px;
            margin-left: 600px;
            width: 45px;
            height: 130px;
            background-color: pink;
        }

        .w {
            width: 1200px;
            margin: 10px auto;
        }

        .header {
            height: 150px;
            background-color: purple;
        }

        .banner {
            height: 250px;
            background-color: skyblue;
        }

        .main {
            height: 1000px;
            background-color: yellowgreen;
        }

        span {
            display: none;
            position: absolute;
            bottom: 0;
        }
    </style>
</head>
<body>
<div class="slider-bar">
    <span class="goBack">返回顶部</span>
</div>
<div class="header w">头部区域</div>
<div class="banner w">banner区域</div>
<div class="main w">主体部分</div>

<script>
      //1. 获取元素
        var sliderbar = document.querySelector('.slider-bar');
        var banner = document.querySelector('.banner');
        // banner.offestTop 就是被卷去头部的大小 一定要写到滚动的外面
        var bannerTop = banner.offsetTop
            // 当我们侧边栏固定定位之后应该变化的数值
        var sliderbarTop = sliderbar.offsetTop - bannerTop;
        // 获取main 主体元素
        var main = document.querySelector('.main');
        var goBack = document.querySelector('.goBack');
        var mainTop = main.offsetTop;
        // 2. 页面滚动事件 scroll
        document.addEventListener('scroll', function() {
            // console.log(11);
            // window.pageYOffset 页面被卷去的头部
            // console.log(window.pageYOffset);
            // 3 .当我们页面被卷去的头部大于等于了 172 此时 侧边栏就要改为固定定位
            if (window.pageYOffset >= bannerTop) {
                sliderbar.style.position = 'fixed';
                sliderbar.style.top = sliderbarTop + 'px';
            } else {
                sliderbar.style.position = 'absolute';
                sliderbar.style.top = '300px';
            }
            // 4. 当我们页面滚动到main盒子,就显示 goback模块
            if (window.pageYOffset >= mainTop) {
                goBack.style.display = 'block';
            } else {
                goBack.style.display = 'none';
            }
        })
		goBack.addEventListener('click',function () {
        // window.scroll(x,y);  x y 代表页面的坐标
        // 直接跳到页面顶部
         window.scroll(0,0);
    });
</script>
</body>
</html>
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的小朱同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值