前端与移动开发----webAPI---- offset,client,scroll获取元素位置和大(案例:拖拽, 放大镜,封装动画)

JavaScript

offset【获取元素位置和大小】

☞ dom.offsetLeft  ---> 获取当前元素在网页中的位置信息-水平偏移
☞ dom.offsetTop   ---> 获取当前元素在网页中的位置信息-垂直偏移
注意:offsetLeft默认是相对整个HTML标签,如果其父元素是一个定位元素那么就相对其父元素(类似于css中的绝对定位)

☞ dom.offsetWidth  ---> 获取当前元素在浏览器中的实际宽度(内容+边框+内边距)   
☞ dom.offsetHeight ---> 获取当前元素在浏览器中的实际高度(内容+边框+内边距)   

在这里插入图片描述

client【获取元素位置和大小】

☞ dom.clientLeft  --> 获取元素边框的左边框的宽度
☞ dom.clientTop --->  获取元素上边框的宽度

☞ dom.clientWidth   -->  元素宽度【不包括边框,但是包括内边距】
☞ dom.clientHeight  -->  元素高度【不包括边框,但是包括内边距】

总结:
	clientHeight = 内容区域 + padding
	clientWidth = 内容区域 + padding

在这里插入图片描述

scroll【获取元素位置和大小】

☞ dom.scrollLeft   --->获取元素拖拽滚动条水平移动(滚动)的距离
☞ dom.scrollTop    --->滚动条向上滚动的距离【内容滚出去的距离】
  注意:
    1.必须有滚动条            
    2.onscroll事件中获取
☞ dom.scrollWidth   ---> 
  1.如果内容区域小于当前元素,那么scrollWidth就代表当前元素大小【算内边距,不算边框】
  2.如果内容区域大于当前元素,那么scrollWidth就等于内容区域大小+左内边距
	 
☞ dom.scrollHeight  --->整个内容区域高度

在这里插入图片描述

案例

  • 拖拽

    鼠标按下事件: onmousedown
    鼠标抬起事件: onmouseup
    鼠标移动事件: onmousemove
    案例思路:
     1. 鼠标按下时候的位置和鼠标离开时候的位置是相同的
     2. 鼠标按下时候的位置= 鼠标在页面中的位置(e.pagex)- 当前元素在页面中的位置(offsetLeft)
     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>
            * {
                margin: 0;
                padding: 0;
            }
            .box {
                width: 200px;
                height: 200px;
                background-color: red;
                position: absolute;
                left: 0;
                top: 0;
            }
        
        </style>
    </head>
    <body>
        <div class="box"></div>
        <script>
            //拖拽效果: 
            //给标签设置定位
            var box= document.querySelector('.box');
            //给当前盒子注册一个鼠标按下事件
            box.onmousedown = function(e) {
                //获取鼠标按下时候在网页中的位置
                var mx = e.clientX;
                var my = e.clientY;
                //鼠标在盒子中的坐标位置
                var x = mx - this.offsetLeft;
                var y = my - this.offsetTop;
                // 给整个页面注册一个鼠标移动事件
                document.onmousemove = function(e) {
                    //获取鼠标在页面中移动后的位置
                    var move_x = e.clientX;
                    var move_y = e.clientY;
    
                    //计算盒子最后的位置
                    var box_x = move_x - x;
                    var box_y = move_y - y;
    
                    //将计算后的位置设置给div
                    box.style.left = box_x + 'px';
                    box.style.top = box_y + 'px';
                }
            }
            //给盒子注册一个鼠标抬起事件
            box.onmouseup = function() {
                //移除鼠标移动事件
                document.onmousemove = null;
            }
    
        </script>
    </body>
    </html> 
    
  • 放大镜

     1. onmouseenter 和 onmouseleave 属于一组,不会有事件冒泡
     2. onmouseover 和 onmouseout 属性一组,有事件冒泡
    <!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;
            }
            .box {
                width: 450px;
                height: 450px;
                border: 2px solid blue;
                margin-left: 50px;
                margin-top: 50px;
                position: relative;
                cursor: move;
            }
            .leftBox {
                width: 100%;
                height: 100%;
                position: relative;
            }
            .rightBox {
               width: 100%;
               height: 100%;
               border: 2px solid blue;
               position: absolute;
               top: 0;
               right: -470px;
               overflow: hidden;
               display: none;
            }
    
            .cover {
                width: 200px;
                height: 200px;
                background-color: yellow;
                opacity: 0.5;
                position: absolute;
                left: 0;
                top: 0;
                display: none;
            }
    
            img {
                vertical-align: middle;
            }
    
            .rightBox img {
                position: absolute;
                left: 0;
                top: 0;
            }
        </style>
    </head>
    <body>
    
        <div class="box">
            <div class="leftBox">
                  <img src="img/small.jpg" alt="">
                  <div class="cover"></div>
            </div>
          
            <div class="rightBox">
                <img src="img/big.jpg" alt="">
            </div>
        </div>
    
        <script>
            var box = document.querySelector('.box');
            var rightBox = document.querySelector('.rightBox');
            var cover = document.querySelector('.cover');
            var img = document.querySelector('.rightBox img');
    
            //鼠标进入事件 + 鼠标移动事件 + 鼠标离开事件
            box.onmouseenter = function() {
                // 功能1,功能2显示盒子
                cover.style.display = 'block';
                rightBox.style.display = 'block';
                // 功能3, 给盒子注册鼠标移动事件
                box.onmousemove = function(e) {
                    //实现遮罩盒子跟随鼠标移动,计算鼠标在盒子中的位置
                    var x = e.clientX - this.offsetLeft - cover.offsetWidth / 2;
                    var y = e.clientY - this.offsetTop - cover.offsetHeight / 2;
                    //设置边界值
                    var min_x = 0;
                    var min_y = 0;
                    var max_x = this.offsetWidth - cover.offsetWidth;
                    var max_y = this.offsetHeight - cover.offsetHeight;
                    //比较
                    x = x < min_x ? min_x : x;
                    x = x > max_x ? max_x : x;
                    y = y < min_y ? min_y : y;
                    y = y > max_y ? max_y : y;
                    //将鼠标的位置赋值给遮罩盒子
                    cover.style.left = x + 'px';
                    cover.style.top = y + 'px';
                    //功能: 实现遮罩盒子移动,右侧盒子中的图片也要跟随移动
                    //比例:
                    // 遮罩盒子移动的距离 : 大盒子的宽度 = 图片移动的距离 : 图片的宽度
                    // 图片移动的距离 = 遮罩盒子移动的距离 * 图片的宽度 / 大盒子的宽度;
                    img.style.left = -x * img.offsetWidth / this.offsetWidth + 'px';
                    img.style.top = -y * img.offsetHeight / this.offsetHeight + 'px';
                }
            }
            //鼠标离开事件
            box.onmouseleave = function() {
                // 功能1,功能2 隐藏盒子
                cover.style.display = 'none';
                rightBox.style.display = 'none';
            }        
        </script>
    </body>
    </html>
    

    small.jpg
    small
    big.jpg
    big

  • 封装动画

    第一步

    <!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;
            }
            .box {
                width: 150px;
                height: 150px;
                background-color: red;
                position: absolute;
                left: 0;
            }   
        </style>
    </head>
    <body>
        <input type="button" value="移动" class="btn1">
        <div class="box"></div>
        <script>    
            //准备工作: 需要使用定时器
            var div = document.querySelector('.box');
            var btn1 = document.querySelector('.btn1');
            //每次要移动的距离
            var step = 10;
            //移动的开始位置
            var start = 0;
            //移动到目标位置
            var target = 900;
            //定义一个变量接收定时器
            var timeID;
            btn1.onclick = function() {
              //开启定时器
              timeID = setInterval(function(){
                    //代表当前的位置还没有走到结束位置
                    if(start < target) {
                        start += step;
                    }else {
                        //代表当前的位置和结束重合
                        start = target;
                        //停止定时器
                        clearInterval(timeID);
                    }
                    //将移动后的位置赋值给当前div
                    div.style.left = start + 'px';
                }, 20)
            }
            //问题: 当多次快速点击按钮的时候,元素移动的速度越来越快
            //原因: 因为页面中每点击一次按钮,就会一个新的定时器
            //解决: 只要保证定时器只要一个即可
        </script>
    </body>
    </html>
    

    第二步

    <!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;
             }
    
             .box {
                 width: 150px;
                 height: 150px;
                 background-color: red;
                 position: absolute;
                 left: 0;
             }
         </style>
    </head>
    <body>
         <input type="button" value="移动" class="btn1">
         <div class="box"></div>
        <script> 
            //准备工作: 需要使用定时器
            var div = document.querySelector('.box');
            var btn1 = document.querySelector('.btn1');
            //每次要移动的距离
            var step = 10;
            //移动的开始位置
            var start = 0;
            //移动到目标位置
            var target = 900;
            //定义一个变量接收定时器
            var timeID = '';
            //问题: 当多次快速点击按钮的时候,元素移动的速度越来越快
            //原因: 因为页面中每点击一次按钮,就会一个新的定时器
            //解决: 只要保证定时器只要一个即可
            btn1.onclick = function() {
                animate(start, target, step, div, 20);
            }  
            //封装成函数的时候,遇到一个问题,每次点击按钮要重新调用函数,元素都是从0位置开始移动
            //解决方案: 只要保证元素移动后的位置和当前元素的位置同步即可
            function animate(start, target, step, elemt, time) {
                 //元素对象.offsetLeft 获取当前元素的位置
                 start = elemt.offsetLeft;
                //解决: 将页面中已存在的定时器停止
                if(timeID != '') {
                    clearInterval(timeID);
                }
                //开启定时器
                timeID = setInterval(function(){
                    //代表当前的位置还没有走到结束位置
                    if(start < target) {
                        start += step;
                    }else {
                        //代表当前的位置和结束重合
                        start = target;
                        //停止定时器
                        clearInterval(timeID);
                    }
                    //将移动后的位置赋值给当前div
                    elemt.style.left = start + 'px';
                }, time)
            }   
        </script>
    </body>
    </html>
    

    第三步

    <!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;
            }
            .box {
                width: 150px;
                height: 150px;
                background-color: red;
                position: relative;
                left: 0;
            }
            .box1 {
                width: 150px;
                height: 150px;
                background-color: blue;
                position: relative;
                left: 0;
            }   
        </style>
    </head>
    <body>
        <input type="button" value="移动" class="btn1">
        <div class="box"></div>
        <div class="box1"></div>
        <script>
            //准备工作: 需要使用定时器
            var div = document.querySelector('.box');
            var div1 = document.querySelector('.box1');
            var btn1 = document.querySelector('.btn1');
            //每次要移动的距离
            var step = 10;
            //移动的开始位置
            var start = 0;
            //移动到目标位置
            var target = 900;
            //定义一个变量接收定时器
            var timeID = '';
            btn1.onclick = function() {
                animate(start, target, step, div, 20);
                animate(start, 800, step, div1, 20);
            }        
            function animate(start, target, step, elemt, time) {
                //元素对象.offsetLeft 获取当前元素的位置
                start = elemt.offsetLeft;
                //解决: 将页面中已存在的定时器停止
                if(elemt.timeID != '') {
                    clearInterval(elemt.timeID);
                }
                //开启定时器
                elemt.timeID = setInterval(function(){
                    //代表当前的位置还没有走到结束位置
                    if(start < target) {
                        start += step;
                    }else {
                        //代表当前的位置和结束重合
                        start = target;
                        //停止定时器
                        clearInterval(elemt.timeID);
                    }
                    //将移动后的位置赋值给当前div
                    elemt.style.left = start + 'px';
                }, time)
            }  
            // 问题: 最后一个元素在动,前一个元素不动
            // 原因: 页面中多个元素使用了同一个定时器
            // 解决: 每一个元素维护自己的一个定时器 (一一对应)
        </script>
    </body>
    </html>
    

    第四步

    html代码:

    <!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;
            }
            .box {
                width: 150px;
                height: 150px;
                background-color: red;
                position: absolute;
                left: 0;
            }   
        </style>
    </head>
    <body>
        <input type="button" value="向右移动" class="btn1">
        <input type="button" value="向左移动" class="btn2">
        <div class="box"></div>
        <script src="./19animat.js"></script>
        <script>
             //准备工作: 需要使用定时器
             var div = document.querySelector('.box');
             var btn1 = document.querySelector('.btn1');
             var btn2 = document.querySelector('.btn2');
             //每次要移动的距离
             var step = 10;
             //移动的开始位置
             var start = 0;
             //移动到目标位置
             var target = 900;
             //定义一个变量接收定时器
             var timeID = '';
            //向右移动
            btn1.onclick = function() {
                animate(start, target, step, div, 20);
            }
            // 向左移动
            btn2.onclick = function() {
                animate(900, 0, step, div, 20);
            }       
        </script>
    </body>
    </html>
    
    

    js代码:

    var timeID = '';
    function animate(start, target, step, elemt, time) {
        //元素对象.offsetLeft 获取当前元素的位置
        start = elemt.offsetLeft;
        //解决: 将页面中已存在的定时器停止
        if (elemt.timeID != '') {
            clearInterval(elemt.timeID);
        }
        //开启定时器
        elemt.timeID = setInterval(function () {
            //问题: 需要判断是否到达终点,要通过距离比较
            // 两点之间的距离 和 元素每次移动的距离比较
            //如果开始位置大于结束位置,元素往回走
            if (start > target) {
                step = -Math.abs(step);
            }
            //代表当前的位置还没有走到结束位置
            if (Math.abs(start - target) > Math.abs(step)) {
                start += step;
            } else {
                //代表当前的位置和结束重合
                start = target;
                //停止定时器
                clearInterval(elemt.timeID);
            }
            //将移动后的位置赋值给当前div
            elemt.style.left = start + 'px';
        }, time);
    }
    

如有不足,请多指教,
未完待续,持续更新!
大家一起进步!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

東三城

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

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

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

打赏作者

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

抵扣说明:

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

余额充值