webApi07

本文详细解析了offset、scroll和client三个CSS坐标家族,包括它们在获取元素尺寸、定位及事件处理中的作用。通过实例演示了拖拽盒子和商城放大镜,展示了事件对象和坐标系的理解。同时涵盖了关键的事件处理技巧和布局优化技巧。
摘要由CSDN通过智能技术生成


小概

三大家族(offset,scroll,client);事件对象;经典案例(商品放大镜)


1.offset scroll client 三大家族

1.1 offset家族

offset家族:获取元素;自身 的真实宽高与位置

  1. offsetWidth / offsetHeight: 自身真实宽高 =content + padding +border
  2. offsetParent :获取最近的定位父元素
  3. offsetLeft / Top :获取‘自身’ 左 /上 外边框 到 定位父元素 左/上 内边距距离

1.2 scroll家族

scroll家族:获取元素 ‘内容’ 的真实宽高与位置

  1. scrollWidth / scrollHeight:内容真实宽高
  2. scrollLeft / scrollTop :内容真实位置:滚动条滚动的距离
    滚动条事件:onscroll
    经典场景:固定导航
    //1.获取元素
    let topPart = document.querySelector('#topPart');
    let navBar = document.querySelector('#navBar');
    let mainPart = document.querySelector('#mainPart');

    //2.注册事件
    window.onscroll = function(){
        //3.事件处理
        let h =  document.documentElement.scrollTop;
        if(h >= topPart.offsetHeight){
            navBar.style.position = 'fixed';
            navBar.style.top = 0;
            /* 问题:滚动得时候,底部盒子会顿闪
               分析: 元素设置为固定定位之后,就会脱标。 后面得标准流就会顶上去
               解决: 给后面得盒子一个margin, 撑开脱标得高度
             */
            mainPart.style.marginTop = 10 + navBar.offsetHeight + 'px';
        }else{
            navBar.style.position = 'static';
            //margin复位
            mainPart.style.marginTop = '10px';
        };
    };

1.3 client家族

client家族 :获取元素 ‘可视区域’ 得真实宽高与位置

  1. clientWidth/clientHeight : ‘可视区域’得宽高
  2. clientLeft/clientTop : ‘可视区域’得位置 (其实就是左边框与上边框宽度
    onresize :大小变化事件
    经典场景:响应式布局,横竖屏适配
    window.onresize = function(){
        let w = document.documentElement.clientWidth;
        let h = document.documentElement.clientHeight;

        if(w >= 1200){//大pc
            document.body.style.backgroundColor = 'red';
        }else if( w >= 992 ){
            document.body.style.backgroundColor = 'orange';
        }else if( w >= 768 ){
            document.body.style.backgroundColor = 'yellow';
        }else{
            document.body.style.backgroundColor = 'green';
        };
        /* 横竖屏适配 */
        w > h ? alert('横屏') : alert('竖屏');
    };

2. 事件对象

1.事件对象 : 存储与事件触发相关得数据。 (当用户触发事件得时候,浏览器会自动捕捉鼠标坐标点/键盘按键这些信息,然后存入对象
中,称之为事件对象)
2.事件对象 由 浏览器自动声明,自动赋值。
3.用户只需要获取即可 : 给事件处理函数添加一个形参 event ev e
* 原理:浏览器自动创建事件对象之后,会在触发事件得时候通过实参方式传递给事件处理函数
了解即可: 事件对象兼容性处理
谷歌火狐: 形参e
IE8 : 全局属性 window.event
*/

2.2 事件对象三大坐标系

  1. screen坐标系:鼠标触发到 电脑屏幕左上角距离
  2. client坐标系:鼠标触发点到 页面可视区左上角距离(页面滚动了,这个坐标也会变)
    3 page坐标系:最常用的坐标系:鼠标触发点到页面左/上的距离
    页面元素定位就是按照这个坐标系来定位的
	document.body.onclick=function(e){
		console.log(e.pageX,e.pageY);
	}
	//div 跟随鼠标
	    <script>
        let box =document.querySelector('#box');
        //为最大的window(最大视口)绑定移动事件
        window.onmousemove = function(e){
            //默认元素定位参考点是左上角,如果希望鼠标在元素中心,可以减去一半宽高
            box.style.left = e.pageX-box.offsetWidth/2 + 'px';
            box.style.top = e.pageY-box.offsetHeight/2 + 'px';
        }
    </script>
	

2.3 案例:拖拽盒子

    <style>
        #father {
            width: 200px;
            height: 400px;
            background-color: skyblue;
            position: absolute;
            top: 0px;
            left: 0px;
            margin: 50px;
        }

        #son {
            width: 200px;
            height: 100px;
            background-color: hotpink;
            cursor: move;
        }
    </style>
</head>

<body>

    <div id="father">
        <div id="son"></div>
    </div>

    <script>
        /* 
        1.复习鼠标事件
            onclick      : 鼠标单击(按下+松开)
            ondblclick   :鼠标双击
            onmouseover  :鼠标移入
            onmouseout   :鼠标移出
            onmousemove  :鼠标移动
            onmousedown  : 鼠标按下
            onmouseup    : 鼠标松开

        2.拖拽事件由三个部分组成
            2.1 拖拽开始: 鼠标按下 onmousedown  (给拖拽盒子注册)
                2.2 拖拽进行 :鼠标移动 onmousemove  (给拖拽的区域注册,例如页面window)
                2.3 拖拽结束 :鼠标松开 onmouseup  (给拖拽盒子注册)
        */


        //1.获取元素
        let father = document.querySelector('#father');
        let son = document.querySelector('#son');
        //2.注册拖拽事件

        //2.1 拖拽开始: 鼠标按下 onmousedown
        son.onmousedown = function (e) {
            //(1)求蓝线 = 红线(e.pageX)-绿线(father.offsetLeft)
            let x = e.pageX - father.offsetLeft;
            let y = e.pageY - father.offsetTop;
            console.log(x,y);
            
            //2.2 拖拽进行 :鼠标移动 onmousemove
            window.onmousemove = function (e) {
                //(2)求黑线 = 红线(e.pgaeX) - 蓝线
                let x1 = e.pageX - x;
                let y1 = e.pageY - y;
                /* 注意点: 元素定位是以margin左上角为参考点,如果盒子有margin,减去margin */
                father.style.left = x1 - 50 + 'px';
                father.style.top = y1 - 50 + 'px';
            };

            //2.3 拖拽结束 :鼠标松开 onmouseup
            son.onmouseup = function () {
                console.log('鼠标松开.拖拽结束');
                //结束拖拽:清除 鼠标移动事件
                window.onmousemove = null;
            };
        };

如果父元素存在margin,一定要在移动函数内计算father left和top时减去外边距。

3. 商城放大镜案例

在这里插入图片描述

需求分析:

  1. 鼠标移入smallBox : 显示mask盒子 和 bigBox大盒子
  2. 鼠标移出smallBox : 隐藏mask盒子 和 bigBox大盒子
  3. 鼠标移动smallBox :
    3.1 mask跟随鼠标移动
    3.2 鼠标在mask中心位置
    3.3 mask只能在smallBox里面移动(边界检测)
    3.4 大盒子中的图片bigImg对应移动
    图片移动距离 = mask移动距离 * 大盒子尺寸/mask尺寸
    //1.获取元素
    let box = document.querySelector('#box');//父盒子  他的offsetLeft才是到屏幕距离
    let smallBox = document.querySelector('#smallBox');
    let bigBox = document.querySelector('#bigBox');
    let mask = document.querySelector('#mask');
    let bigImg = document.querySelector('#bigImg');

    //2.注册事件

    //1.鼠标移入smallBox : 显示mask盒子 和  bigBox大盒子
    smallBox.onmouseover = function () {
      mask.style.display = 'block';
      bigBox.style.display = 'block';
    };
    //2.鼠标移出smallBox : 隐藏mask盒子 和  bigBox大盒子
    smallBox.onmouseout = function () {
      mask.style.display = 'none';
      bigBox.style.display = 'none';
    };
    //3.鼠标移动smallBox 
    smallBox.onmousemove = function (e) {
      //3.1 mask跟随鼠标移动
      //蓝线 = 红线(e.pageX) - 绿色(box.offsetLeft)
      let x = e.pageX - box.offsetLeft;
      let y = e.pageY - box.offsetTop;
      
      //3.2 鼠标在mask中心位置
      x -= mask.offsetWidth/2;
      y -= mask.offsetHeight/2;

      //3.3 mask只能在smallBox里面移动(边界检测)
      /* 
      0 <= x <= smallBox宽度-mask宽度
      */
      let maxX = smallBox.offsetWidth - mask.offsetWidth;
      let maxY = smallBox.offsetHeight - mask.offsetHeight;

      x = x < 0 ? 0 : x;
      x = x > maxX ? maxX : x;
      y = y < 0 ? 0 : y;
      y = y > maxY ? maxY : y;

      mask.style.left = x + 'px';
      mask.style.top = y + 'px';

      //3.4 大盒子中的图片bigImg对应移动
     bigImg.style.left = -x * bigBox.offsetWidth/mask.offsetWidth + 'px';
     bigImg.style.top = -y * bigBox.offsetHeight/mask.offsetHeight + 'px';

    };

  </script>
css样式
 <style>
    * {
      margin: 0;
      padding: 0;
    }
    .box {
      width: 350px;
      height: 350px;
      margin: 100px;
      border: 1px solid #ccc;
      position: relative;
    }
    .big {
      width: 400px;
      height: 400px;
      position: absolute;
      top: 0;
      left: 360px;
      border: 1px solid #ccc;
      overflow: hidden;
      display: none;
    }
    .mask {
      width: 175px;
      height: 175px;
      background: rgba(255, 255, 0, 0.4);
      position: absolute;
      top: 0;
      left: 0;
      cursor: move;
      display: none;
    }
    .small {
      position: relative;
    }
    .box img {
      vertical-align: top;
    }
    #bigBox>img {
      /*是让里面的图片脱标,为的就是让里面的图片进行一个移动*/
      position: absolute;
    }
  </style>

</head>

<body>
  <div class="box" id="box">
    <div class="small" id="smallBox">
      <img src="images/001.jpg" width="350" alt="" />

      <div class="mask" id="mask"></div>
    </div>
    <div class="big" id="bigBox">
      <img id="bigImg" src="images/0001.jpg" width="800" alt="" />
    </div>
  </div>

总结

多敲多练,不多说了,我去接着肝了、

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值