三大家族(offset,scroll,client);事件对象;经典案例(商品放大镜)
offset家族:获取元素;自身 的真实宽高与位置
- offsetWidth / offsetHeight: 自身真实宽高 =content + padding +border
- offsetParent :获取最近的定位父元素
- offsetLeft / Top :获取‘自身’ 左 /上 外边框 到 定位父元素 左/上 内边距距离
scroll家族:获取元素 ‘内容’ 的真实宽高与位置
- scrollWidth / scrollHeight:内容真实宽高
- 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'; }; };
client家族 :获取元素 ‘可视区域’ 得真实宽高与位置
- clientWidth/clientHeight : ‘可视区域’得宽高
- 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('竖屏'); };
1.事件对象 : 存储与事件触发相关得数据。 (当用户触发事件得时候,浏览器会自动捕捉鼠标坐标点/键盘按键这些信息,然后存入对象
中,称之为事件对象)
2.事件对象 由 浏览器自动声明,自动赋值。
3.用户只需要获取即可 : 给事件处理函数添加一个形参 event ev e
* 原理:浏览器自动创建事件对象之后,会在触发事件得时候通过实参方式传递给事件处理函数
了解即可: 事件对象兼容性处理
谷歌火狐: 形参e
IE8 : 全局属性 window.event
*/
- screen坐标系:鼠标触发到 电脑屏幕左上角距离
- 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>
<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 :鼠标双击 onm ouseover :鼠标移入 onm ouseout :鼠标移出 onm ousemove :鼠标移动 onm ousedown : 鼠标按下 onm ouseup : 鼠标松开 2.拖拽事件由三个部分组成 2.1 拖拽开始: 鼠标按下 onm ousedown (给拖拽盒子注册) 2.2 拖拽进行 :鼠标移动 onm ousemove (给拖拽的区域注册,例如页面window) 2.3 拖拽结束 :鼠标松开 onm ouseup (给拖拽盒子注册) */ //1.获取元素 let father = document.querySelector('#father'); let son = document.querySelector('#son'); //2.注册拖拽事件 //2.1 拖拽开始: 鼠标按下 onm ousedown 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 拖拽进行 :鼠标移动 onm ousemove 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 拖拽结束 :鼠标松开 onm ouseup son.onmouseup = function () { console.log('鼠标松开.拖拽结束'); //结束拖拽:清除 鼠标移动事件 window.onmousemove = null; }; };
如果父元素存在margin,一定要在移动函数内计算father left和top时减去外边距。
需求分析:
- 鼠标移入smallBox : 显示mask盒子 和 bigBox大盒子
- 鼠标移出smallBox : 隐藏mask盒子 和 bigBox大盒子
- 鼠标移动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>
多敲多练,不多说了,我去接着肝了、