一文搞懂offset、client、scroll系列及案例

news2024/12/22 20:24:19

目录

一、offset

1-1、offset系列属性

1-2、offset与style区别

1-3、案例

1-3-1、计算鼠标在盒子内的坐标

1-3-2、拖动模态框

二、client

2-1、client系列属性

三、scroll

3-1、scroll系列属性

3-2、案例

3-2-1、滚动页面一定距离后固定侧边栏


一、offset

offset是偏移量,使用offset系列相关属性可以动态得到元素的位置(偏移)、大小等,可获得:

  • 元素距离带有定位父元素的位置
  • 元素自身的宽度、高度

注意:返回的数值不带单位

1-1、offset系列属性

offset系列属性作用
element.offsetParent返回作为该元素带有定位的父级元素(如果父级都没有定位则返回body)
element.offsetTop返回元素相对带有定位父级元素上方的偏移
element.offsetLeft返回元素相对带有定位父元素左边框的偏移
element.offsetWidth返回自身包括padding、边框、内容区的宽度
element.offsetHeight返回自身包括padding、边框、内容区的高度

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .father {
            position: relative;
            width: 200px;
            height: 200px;
            background-color: pink;
            margin: 150px;
        }

        .son {
            width: 100px;
            height: 100px;
            background-color: purple;
            margin-left: 45px;
        }

        .w {
            height: 200px;
            width: 200px;
            background-color: skyblue;
            margin: 0 auto 200px;
            padding: 10px;
            border: 15px solid orange;
        }
    </style>
</head>

<body>
    <div class="father">
        <div class="son"></div>
    </div>
    <div class="w"></div>
    <script>
        // offset 系列
        var father = document.querySelector('.father');
        var son = document.querySelector('.son');
        // 1.可以得到元素的偏移 位置 返回的不带单位的数值  
        console.log(father.offsetTop);// 150
        console.log(father.offsetLeft);// 150
        // 它以带有定位的父亲为准
        // 没有父亲或者父亲没有定位 则以 body 为准,为195
        console.log(son.offsetLeft);// 45
        var w = document.querySelector('.w');
        // 2.可以得到元素的大小 宽度和高度 是包含padding + border + width 
        // 200 + 15*2 + 10*2
        console.log(w.offsetWidth);// 250
        console.log(w.offsetHeight); // 250
        // 3. 返回带有定位的父亲 否则返回的是body
        console.log(son.offsetParent); // 返回带有定位的父亲 否则返回的是body
        console.log(son.parentNode); // 返回父亲 是最近一级的父亲 亲爸爸 不管父亲有没有定位
    </script>
</body>

</html>

1-2、offset与style区别

  1. offset
  • offset系列获得的数值是没有单位的
  • offsetWidth包含padding+border+width
  • offsetWidth等属性是只读属性,只能获取不能赋值
  1. style
  • style.width获得的是带有单位的字符串
  • style.width获得不包含padding和border的值
  • style.width是可读可写属性,可以获取也可以赋值

所以:

  • 想要获取元素大小位置,用offset更合适
  • 想要给元素更改值,用style更合适
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background-color: pink;
            padding: 10px;
        }
    </style>
</head>

<body>
    <div class="box" style="width: 200px;"></div>
    <script>
        // offset与style的区别
        var box = document.querySelector('.box');
        console.log(box.offsetWidth); // 200 + 10*2 = 220
        console.log(box.style.width); // 200px
        box.style.width = '300px'; // 可利用style去设置值
    </script>
</body>

</html>

1-3、案例

1-3-1、计算鼠标在盒子内的坐标

原理: 使用鼠标在页面中的坐标(pageX,pageY) - 盒子在页面中的偏移量(offsetLeft,offsetTop)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            width: 300px;
            height: 300px;
            background-color: pink;
            margin: 200px;
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <script>
        // 我们在盒子内点击, 想要得到鼠标距离盒子左右的距离。
        // 首先得到鼠标在页面中的坐标( e.pageX, e.pageY)
        // 其次得到盒子在页面中的距离(box.offsetLeft, box.offsetTop)
        // 用鼠标距离页面的坐标减去盒子在页面中的距离, 得到 鼠标在盒子内的坐标
        const box = document.querySelector('.box');
        box.addEventListener('mousemove', function (e) {
            // console.log(e.pageX);
            // console.log(e.pageY);
            // console.log(box.offsetLeft);
            const x = e.pageX - this.offsetLeft;
            const y = e.pageY - this.offsetTop;
            this.innerHTML = 'x坐标是' + x + ' y坐标是' + y;
        })
    </script>
</body>

</html>

1-3-2、拖动模态框

原理

  1. 当鼠标按下时(mousedown)拿到鼠标在模态框内的坐标下x,y(原理为1-3-1)

  2. 当鼠标拖动模态框开始移动时(mousemove),分别给模态框的left与top赋值:

    • 模态框的left值为 鼠标距离页面左侧的距离 (pageX)- 鼠标在模态框的横坐标(x)
    • 模态框的top值为 鼠标距离页面顶部的距离(pageY)- 鼠标在模态框的纵坐标(y)
  3. 当鼠标抬起时(mouseup),移除鼠标移动事件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        a {
            text-decoration: none;
            color: #000;
        }

        .show-modal {
            width: 100%;
            text-align: center;
            font-size: 24px;
            cursor: pointer;
        }

        .login {
            /*刚开始隐藏起来*/
            display: none;
            position: fixed;
            width: 520px;
            height: 290px;
            border: 1px solid #ccc;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            background: #fff;
            box-shadow: 0 0 20px #ddd;
            z-index: 9999;
        }

        .login-title {
            position: relative;
            width: 100%;
            height: 40px;
            line-height: 40px;
            text-align: center;
            font-size: 18px;
            cursor: move;
        }

        .login-title span {
            position: absolute;
            width: 40px;
            height: 40px;
            right: -20px;
            top: -30px;
            border-radius: 50%;
            font-size: 12px;
            background: #fff;
            border: 1px solid #ccc;
        }

        .login-content {
            padding: 10px;
            height: 180px;
        }

        .login-content-input {
            display: flex;
        }

        .login-content-input label {
            width: 100px;
            text-align: right;
        }

        .login-content-input input {
            width: 350px;
            height: 35px;
            line-height: 35px;
            border: 1px solid #ccc;
            margin-bottom: 20px;
        }

        .login-btn {
            width: 100%;
            height: 50px;
            line-height: 50px;
            display: block;
            text-align: center;
            font-size: 18px;
            border-top: 1px solid #ccc;
        }

        .login-mask {
            display: none;
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0;
            left: 0;
            background-color: rgba(0, 0, 0, .3);
        }
    </style>
</head>

<body>
    <div class="show-modal">点击展示模态框</div>
    <!--模态框-->
    <div class="login">
        <div class="login-title">
            用户登录
            <span><a class="close-btn" href="#">关闭</a></span>
        </div>
        <div class="login-content">
            <div class="login-content-input">
                <label>用户名:</label>
                <input type="text" placeholder="请输入用户名">
            </div>
            <div class="login-content-input">
                <label>密码:</label>
                <input type="password" placeholder="请输入密码">
            </div>
        </div>
        <div><a href="#" class="login-btn">登录</a></div>
    </div>
    <!--模态框遮罩-->
    <div class="login-mask"></div>
</body>
<script>
    const showLogin = document.querySelector('.show-modal');
    const login = document.querySelector('.login');
    const mask = document.querySelector('.login-mask');
    const closeBtn = document.querySelector('.close-btn');
    const title = document.querySelector('.login-title');

    // 点击展示模态框
    showLogin.addEventListener('click', function () {
        mask.style.display = 'block'; // 展示遮罩
        login.style.display = 'block'; // 展示模态窗
    })

    // 点击关闭按钮关闭模态框
    closeBtn.addEventListener('click', function () {
        mask.style.display = 'none';
        login.style.display = 'none';
    })

    // 拖拽模态框, 按住标题区域开始拖拽
    title.addEventListener('mousedown', function (e) {
        // 1 先获取一下鼠标在模态框内的坐标
        // 鼠标在页面上的坐标 - 模态框距离页面顶部/上部的距离
        const x = e.pageX - login.offsetLeft;
        const y = e.pageY - login.offsetTop;

        // 鼠标移动的监听事件加到document上,方式移动过快甩出模态框
        document.addEventListener('mousemove', move);

        document.addEventListener('mouseup', function () {
            document.removeEventListener('mousemove', move);
        });

        // 模态框现在的位置 = 鼠标在页面上的坐标 - 鼠标在模态框内的坐标
        function move(e) {
            // !!特别注意要加上px
            login.style.left = e.pageX - x + 'px';
            login.style.top = e.pageY - y + 'px';
        }
    });

</script>

</html>

二、client

使用client系列的相关属性可获取元素可视区的相关信息,可动态得到元素的边框大小、元素大小等。

2-1、client系列属性

client系列属性作用
element.clientTop返回元素上边框的大小
element.clientLeft返回元素左边框的大小
element.clientWidth返回自身包括padding、内容区的宽度,不包含边框
element.clientHeight返回自身包括padding、内容区的高度,不包含边框

注意:

  • client系列获取的内容也不包含单位

  • clientWidth、clientHeight与offsetWidth、offsetHeight不同的是:

    • offsetWidthoffsetHeight获取的宽高为:padding + 内容区 + 边框
    • clientWidthclientHeight获取的宽高为:padding + 内容区
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: skyblue;
            border: 10px solid orange;
            padding: 10px;
        }
    </style>
</head>

<body>
    <div></div>
    <script>
        // client 宽度 和我们offsetWidth 最大的区别就是 不包含边框
        var div = document.querySelector('div');
        console.log(div.clientWidth); // 200 + 10* 20 = 220
        console.log(div.clientTop); // 10
    </script>
</body>

</html>

三、scroll

使用scroll系列的线管属性可以动态得到元素的大小、滚动距离等。

3-1、scroll系列属性

scroll系列属性作用
element.scrollTop返回被卷上去的上侧距离
element.scrollLeft返回被卷去的左侧距离
element.scrollWidth返回自身的实际宽度,不包含边框
element.scrollHeight返回自身的实际高度,不包含边框

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: skyblue;
            border: 10px solid orange;
            padding: 10px;
            overflow: auto;
        }
    </style>
</head>

<body>
    <div>
        我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容
        我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容
    </div>
    <script>
        // scroll 系列
        var div = document.querySelector('div');
        console.log(div.scrollHeight); // 314 内容的实际高度
        console.log(div.clientHeight); // 200 + 10* 2 = 220
        // scroll滚动事件当我们滚动条发生变化会触发的事件
        div.addEventListener('scroll', function () {
            console.log(div.scrollTop);
        })
    </script>
</body>

</html>

 

3-2、案例

3-2-1、滚动页面一定距离后固定侧边栏

实现效果:侧边栏刚开始为相对定位,当页面滚动到一定距离后改为绝对定位并显示返回顶部按钮

原理:

  1. 首先确定页面需滚动的距离(滚动多少后侧边栏固定),以及侧边栏需要固定的位置
  2. 给页面添加监听页面滚动的事件,在事件中获取页面被卷去的距离(页面被卷去的距离通过:window.pageYOffset、window.pageXOffset获取)
  3. 如果卷去的距离大于等于设定的距离那么就固定侧边栏,将侧边栏固定到所需要固定的位置
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</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. 获取元素
        const sliderbar = document.querySelector('.slider-bar');
        const banner = document.querySelector('.banner');
        // banner.offestTop 就是被卷去头部的大小 一定要写到滚动的外面
        const bannerTop = banner.offsetTop
        // 当我们侧边栏固定定位之后应该变化的数值
        const sliderbarTop = sliderbar.offsetTop - bannerTop;
        // 获取main 主体元素
        const main = document.querySelector('.main');
        const goBack = document.querySelector('.goBack');
        const mainTop = main.offsetTop;
        // 2. 页面滚动事件 scroll
        document.addEventListener('scroll', function () {
            // console.log(11);
            // 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';
            }
        })
    </script>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2157744.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pg入门3—详解tablespaces—下

pg默认的tablespace的location为空&#xff0c;那么如果表设置了默认的tablespace&#xff0c;数据实际上是存哪个目录的呢? 在 PostgreSQL 中&#xff0c;如果你创建了一个表并且没有显式指定表空间&#xff08;tablespace&#xff09;&#xff0c;或者表空间的 location 为…

数据库数据恢复—SQL Server附加数据库出现“错误823”怎么恢复数据?

SQL Server数据库故障&#xff1a; SQL Server附加数据库出现错误823&#xff0c;附加数据库失败。数据库没有备份&#xff0c;无法通过备份恢复数据库。 SQL Server数据库出现823错误的可能原因有&#xff1a;数据库物理页面损坏、数据库物理页面校验值损坏导致无法识别该页面…

【靶点Talk】免疫检查点争夺战:TIGIT能否超越PD-1?

曾经的TIGIT靶点顶着“下一个PD-1”的名号横空出世&#xff0c;三年的“征程”中TIGIT走过一次又一次的失败&#xff0c;然而面对质疑和压力仍有一批公司选择前行。今天给大家分享TIGIT靶点的相关内容&#xff0c;更多靶点科普视频请关注义翘神州B站和知乎官方账号。 TIGIT的“…

C#和数据库高级:虚方法

文章目录 一、抽象方法和抽象类中的思考1.1、回顾抽象方法的特点1.2、针对抽象方法问题的引出 二、虚方法的使用步骤2.1、虚方法重写方法的调用2.2、系统自带的虚方法2.3、重写Equals方法2.4、虚方法和抽象方法的比较 三、虚方法和抽象方法的联系3.1、ToString()方法的应用 一、…

2024/9/23 leetcode 25题 k个一组翻转链表

目录 25.k个一组翻转链表 题目描述 题目链接 解题思路与代码 25.k个一组翻转链表 题目描述 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的…

Gartner:中国企业利用GenAI提高生产力的三大策略

作者&#xff1a;Gartner高级首席分析师 雷丝、Gartner 研究总监 闫斌、Gartner高级研究总监 张桐 随着生成式人工智能&#xff08;GenAI&#xff09;风靡全球&#xff0c;大多数企业都希望利用人工智能&#xff08;AI&#xff09;技术进行创新&#xff0c;以收获更多的业务成果…

JS 历史简介

目录 1. JS 历史简介 2. JS 技术特征 1. JS 历史简介 举例&#xff1a;在提交用户的注册信息的时候&#xff0c;为避免注册出现错误后重新填写信息&#xff0c;可以在写完一栏信息后进行校验&#xff0c;并提示是否出现错误&#xff0c;这样会大大提高用户提交的成功率&…

PCL 随机下采样

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff08;长期更新&#xff09; 一、概述 随机下采样 是一种常用的点…

大模型LLM对话模拟器Dialogue Simulator Visualization可视化工具

伴随着生成式人工智能技术发展&#xff0c;进2年涌现出大语言模型LLM/Agent系统/AI推理等众多方向的技术项目和论文。其中对话系统&#xff0c;智能体交互是用户通过UX界面和AI系统进行交互&#xff0c;这种交互有时候也是多模态&#xff08;用户输入文字/语音/图像&#xff09…

众数信科 AI智能体智慧办公解决方案——众数办公AI

智慧办公解决方案 众数办公AI 智能问答 拥有广域知识库 结合AI交互能力 通过智能人机、多轮对话即可完成 信息检索、知识提炼、内容衍生等问答操作 为用户提供多样化的问答服务 PPT创作 支持用户明确计划创作内容后进行需求提交 即刻智能生成符合需求的文章 支持上百种…

【软件工程】验证软件需求

一、验证需求正确性的四个方面 二、验证软件需求的方法 三、用于需求分析的软件工具 小结 例题 判断题

Java/Spring项目的包开头为什么是com?

Java/Spring项目的包开头为什么是com&#xff1f; 下面是一个使用Maven构建的项目初始结构 src/main/java/ --> Java 源代码com.example/ --->为什么这里是com开头resources/ --> 资源文件 (配置、静态文件等)test/java/ --> 测试代码resourc…

【机器学习】揭秘GBDT:梯度提升决策树

目录 &#x1f354; 提升树 &#x1f354; 梯度提升树 &#x1f354; 举例介绍 3.1 初始化弱学习器&#xff08;CART树&#xff09; 3.2 构建第一个弱学习器&#xff08;CART树&#xff09; 3.3 构建第二个弱学习器&#xff08;CART树&#xff09; 3.4 构建第三个弱学习…

Java ----常用类

包装类 包装类的分类 1) 针对八种基本数据类型相应的引用类型—包装类2) 有了类的特点&#xff0c;就可以调用类中的方法。3) 如图 包装类和基本数据的转换 jdk5 前的手动装箱和拆箱方式&#xff0c;装箱&#xff1a;基本类型转包装类型&#xff0c;拆箱&#xff1a;包装类型…

基于物联网的火灾报警器设计与实现(论文+源码)

1 总体方案设计 本次基于物联网的火灾报警器&#xff0c;其系统总体架构如图2.1所示&#xff0c;采用STM32f103单片机作为控制器&#xff0c;通过DS18B20传感器实现温度检测&#xff1b;通过MQ-2烟雾传感器实现烟雾检测&#xff1b;.通过火焰传感器实现火焰检测&#xff0c;当…

ps证件照蓝底换白底

ps证件照蓝底换白底 1、打开 Photoshop&#xff0c;导入需要处理的照片。 2、左侧工具栏中选择“魔棒工具”&#xff0c;点击证件照的背景区域进行选择。 3、使用快捷键 Shift F5 或者从顶部菜单选择“编辑” -> “填充”&#xff0c;在弹出的对话框中选择“填充内容”中…

算法【Java】—— 位运算

位运算总结 位运算的运算符&#xff1a;按位与&#xff08;&&#xff09;&#xff0c;按位或&#xff08;|&#xff09;&#xff0c;按位异或&#xff08;^&#xff09;&#xff0c;按位取反&#xff08;~&#xff09;&#xff0c;还有移位操作符 <<&#xff0c;>…

xinference linux系统下部署

1.创建虚拟环境 conda create -n xinfer pyrhon3.10 2.使用虚拟环境 conda activate xinfer (xinfer) roothome:~$ python -V Python 3.10.14 3.pip安装环境 pip install "xinference[all]" 4.启动服务 nohup xinference-local --host 0.0.0.0 --port 9997 &…

【数据结构】Java的HashMap 和 HashSet 大全笔记,写算法用到的时候翻一下,百度都省了!(实践篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

97、prometheus之yaml文件

命令回顾 [rootmaster01 ~]# kubectl explain ingressKIND: Ingress VERSION: networking.k8s.io/v1DESCRIPTION:Ingress is a collection of rules that allow inbound connections to reachthe endpoints defined by a backend. An Ingress can be configured to givese…