元素偏移量 offset 系列

1.offset 概述

offset 翻译过来就是偏移量, 我们使用 offset 系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
(1)  获得元素距离带有定位父元素的位置
(2)  获得元素自身的大小(宽度高度)
(3)  注意: 返回的数值都不带单位

offset 系列常用属性有:

 1.1 代码体验

<style>
    * {
        margin: 0;
        padding: 0;
    }
    .father {
        margin: 100px;
        width: 200px;
        height: 200px;
        background-color: pink;
    }
    .son {
        margin-left: 30px;
        width: 100px;
        height: 100px;
        background-color: purple;
    }
    .box {
        margin: 0 100px;
        width: 200px;
        height: 200px;
        padding: 20px;
        background-color: skyblue;
        border: 10px solid red;
    }
</style>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
    <div class="box"></div>
    <script>
        // offset 系列
        let father = document.querySelector('.father');
        let son = document.querySelector('.son');
        // 1. 返回带有定位的父亲,否则返回的是body
        console.log(son.offsetParent);
        // 2. 可以得到元素的偏移量(位置),返回的是不带单位的数值
        console.log(father.offsetTop); // 100 ,因为css为其设置的margin为100
        console.log(father.offsetLeft); // 100 ,因为css为其设置的margin为100
        console.log(son.offsetLeft); // 130 ,因为虽然其有父亲,但是其父亲没有定位,所以以body为准,即100+30=130
        // 3. 可以得到元素的大小(宽度和高度),是包含padding + border + width/height的,不包括margin
        let box = document.querySelector('.box')
        console.log(box.offsetWidth); // 260  
        console.log(box.offsetHeight); // 260
    </script>
</body>

 

 特别注意:offset系列返回的位置是距离最近一级带有定位父元素的位置,如果父元素没有定位,则以body为参照。

2 offset 与 style 区别 

(1)offset 

① offset 可以得到任意样式表中的样式值
② offset 系列获得的数值是没有单位的
③ offsetWidth、offsetHeight包含padding+border+width
offsetWidth、offsetHeight等属性是只读属性,只能获取不能赋值
所以,我们想要获取元素大小位置,用offset更合适

(2)style

① style 只能得到行内样式表中的样式值
② style.width 获得的是带有单位的字符串
③ style.width、style.height获得的是不包含padding和border 的值
④ style.width、style.height是可读写属性,可以获取也可以赋值
所以,我们想要给元素更改值,则需要用style改变

3.案例:模态框拖拽

需求:

1. 点击弹出层, 会弹出模态框, 并且显示灰色半透明的遮挡层。
2. 点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明遮挡层。
3. 鼠标放到模态框最上面一行,可以按住鼠标拖拽模态框在页面中移动。
4. 鼠标松开,可以停止拖动模态框移动。

<!-- css样式 -->
<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    .login-bg {
        display: none;
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0;
        left: 0;
        background: rgba(0, 0, 0, .3);
    }
    .login-header {
        font-size: 20px;
        margin: 10px 0;
        text-align: center;
    }
    a {
        text-decoration: none;
        color: #333;
    }
    .login {
        position: fixed;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        display: none;
        width: 480px;
        padding-bottom: 40px;
        background-color: #fff;
        border: 1px solid #ebebeb;
        box-shadow: 0px 0px 20px #ddd;
        z-index: 3;
    }
    .login-title {
        position: relative;
        text-align: center;
        padding: 20px 0 30px;
        font-size: 18px;
        cursor: move;
    }
    .close-login {
        position: absolute;
        top: -20px;
        right: -20px;
        display: block;
        text-align: center;
        line-height: 40px;
        width: 40px;
        height: 40px;
        border-radius: 50%;
        font-size: 12px;
        border: 1px solid #ccc;
        background-color: #fff;
    }
    
    .login-input-content {
        margin-left: 20px;
        font-size: 14px;
    }
    .login-input:nth-child(1) label {
        margin-left: 14px;
    }
    .login-input-content input {
        width: 340px;
        height: 30px;
        outline: none;
        border: none;
        border: 1px solid #ccc;
        margin-bottom: 30px;
        padding-left: 5px;
    }
    .login-button {
        padding-bottom: 30px;
        width: 260px;
        height: 30px;
        border: 1px solid #ccc;
        margin: 0 auto;
        text-align: center;
        line-height: 30px;
    }
</style>
<body>
    <!-- html结构 -->
    <div class="login-header">
        <a href="javascript:;">点击,弹出登录框</a>
    </div>
    <div class="login">
        <div class="login-title">登录会员
            <span><a href="javascript:;" class="close-login">关闭</a></span>
        </div>
        <div class="login-input-content">
            <div class="login-input">
                <label for="">用户名:</label>
                <input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="username">
            </div>
            <div class="login-input">
                <label for="">登录密码:</label>
                <input type="text" placeholder="请输入登录密码" name="info[password]" id="password" class="password">
            </div>
        </div>
        <div class="login-button" id="loginBtn">
            <a href="javascript:;" id="login-button-submit">登录会员</a>
        </div>
    </div>
    <!-- 遮盖层 -->
    <div id="bg" class="login-bg"></div>
    <!-- js代码 -->
    <script>
        // 1. 获取元素
        let loginHeader = document.querySelector('.login-header');
        let login = document.querySelector('.login');
        let bg = document.getElementById('bg');
        let close = document.querySelector('.close-login');
        // 2. 点击,弹出登录框和遮盖层
        loginHeader.onclick = function() {
            login.style.display = 'block';
            bg.style.display = 'block';
        };
        // 3. 点击关闭,隐藏登录框和遮盖层
        close.onclick = function() {
            login.style.display = 'none';
            bg.style.display = 'none';
        };
        // 4. 鼠标放到模态框最上面的登录会员一行,可以按住鼠标拖拽模态框在页面中移动
        // 由于鼠标拖拽模态框时,鼠标的位置是不变的,所以要先获取鼠标在登录会员框中的位置
        // (1) 当鼠标按下,就能获得鼠标在盒子内的坐标
        let title = document.querySelector('.login-title');
        title.onmousedown = function(e) {
            let x = e.pageX - login.offsetLeft;
            let y = e.pageY - login.offsetTop;
     // (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去鼠标在盒子内的坐标就是模态框的left和top值
            document.addEventListener('mousemove', move);
        // 由于后面会移除事件,为了方便使用所以这里给回调函数单独设置并命名为move
            function move(e) {
                login.style.left = e.pageX - x + 'px';
                login.style.top = e.pageY - y + 'px';
            };
            // (3) 鼠标弹起mouseup,就让鼠标移动事件移除
            document.addEventListener('mouseup', function() {
                document.removeEventListener('mousemove', move)
            })
        }
    </script>
</body>

案例分析:

① 点击弹出层, 模态框和遮挡层就会显示出来 display:block;
② 点击关闭按钮,模态框和遮挡层就会隐藏起来 display:none;
③ 在页面中拖拽的原理: 鼠标按下并且移动, 之后松开鼠标
④ 触发事件是鼠标按下 mousedown, 鼠标移动mousemove 鼠标松开 mouseup
⑤ 拖拽过程: 鼠标移动过程中,获得最新的值赋值给模态框的left和top值, 这样模态框可以跟着鼠标走了,所以模态框必须要带定位
⑥ 鼠标按下触发的事件源是 最上面一行,就是 class 为 title 
⑦ 鼠标的坐标 减去 鼠标在盒子内的坐标, 才是模态框真正的位置。
⑧ 鼠标按下,我们要得到鼠标在盒子的坐标。
⑨ 鼠标移动,就让模态框的坐标 设置为 : 鼠标坐标 减去盒子坐标即可,注意移动事件写到按下事件里面。
⑩ 鼠标松开,就停止拖拽,就是可以让鼠标移动事件解除

猜你喜欢

转载自blog.csdn.net/JJ_Smilewang/article/details/125388549