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
big.jpg
-
封装动画
第一步
<!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); }
如有不足,请多指教,
未完待续,持续更新!
大家一起进步!