本文目录:
一、鼠标事件
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>鼠标事件</title> <style> .box { 200px; height: 200px; background-color: red; } .sup { 200px; height: 200px; background-color: orange; margin: 0 auto; } .sub { 100px; height: 100px; background-color: pink; } </style> </head> <body> <div class="box"></div> <div class="sup"> <div class="sub"></div> </div> </body> <script> var box = document.querySelector('.box'); // 1. 点击事件 box.onclick = function () { console.log("单击"); }; // 2. 双击事件(应用场景不广) box.ondblclick = function () { console.log("双击"); }; // 3. 鼠标右键 box.oncontextmenu = function () { console.log("右键了"); return false; }; // 4. 鼠标悬浮 | 移动 | 按下 | 抬起 | 离开 box.onmouseover = function () { console.log("悬浮"); }; box.onmousemove = function () { console.log("移动"); }; box.onmousedown = function () { console.log("按下"); }; box.onmouseup = function () { console.log("抬起"); }; box.onmouseout = function () { console.log("离开"); } </script> <script> // over out | enter leave var sup = document.querySelector('.sup'); var sub = document.querySelector('.sub'); sup.onmouseenter = function (ev) { ev.cancelBubble = true; console.log("enter 悬浮"); }; sup.onmouseover = function () { console.log("over 悬浮"); }; sup.onmouseleave = function () { console.log("leave 离开"); }; sup.onmouseout = function () { console.log("out 离开"); } // 从父级移至子级, 会触发out事件, 紧接着触发子级的over事件, 并可以冒泡给父级 // 从父级移至子级, leave事件并不会触发, 它认为子级是属于父级的一部分, enter事件, 也不会再次触发 // 悬浮子级: // sub over => sup over 支持冒泡 // sup enter => sub enter 不支持冒泡 sub.onmouseenter = function (ev) { ev.cancelBubble = true; console.log("sub enter 悬浮"); }; sub.onmouseover = function () { console.log("sub over 悬浮"); }; // 总结: // 1. 将子级与父级分开考虑, 大家都有各自的悬浮离开事件, 采用 over | out 组合 // 2. 将子级纳入父级考虑范围, 也就是只有父级去相应悬浮离开事件, 采用 enter | leave 组合 // 3. 单独考虑一个盒子的悬浮离开事件, 两套均可以 </script> </html>
二、js盒模型
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>js盒模型</title> <style> .box { width: 100px; height: 100px; background: gray; padding: 20px; border: 10px solid red; } .box { position: absolute; top: 30px; left: 30px; } body { position: relative; } </style> </head> <body> <div class="box"></div> </body> <script> var box = document.querySelector('.box'); // width | height var width = getComputedStyle(box, null).width; console.log(width); // 100px => 100 console.log(parseInt(width)); // console.log(width.substr(0, 3)); // 从索引0开始截取3个长度 console.log(width.slice(0, 3)); // [0, 3) 开索引0开始截取到索引3之前 // padding: padding + width | padding + height console.log(box.clientWidth); console.log(box.clientHeight); // border: border + padding + width | border + padding + height console.log(box.offsetWidth); console.log(box.offsetHeight); // 匹配绝对定位的方位实现 => 映射绝对定位元素的 top | left 定位方位值 console.log(box.offsetTop); console.log(box.offsetLeft); </script> </html>
三、鼠标拖拽
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>鼠标拖拽</title> <style> .box { width: 100px; height: 100px; background: gray; padding: 20px; border: 10px solid red; position: absolute; top: 50px; left: 50px; } </style> </head> <body> <div class="box"></div> </body> <script> var box = document.querySelector('.box'); // 事件之间的关系 box.onmousedown = function (ev) { console.log("按下"); // 在该位置获取点击点相对于自身原点的偏移量 // 偏移量 = 鼠标点 - 盒子原点 var dX = ev.clientX - box.offsetLeft; var dY = ev.clientY - box.offsetTop; // 触发使用频率的, 防止操作过快, 脱离了box, 但是还是在document中 document.onmousemove = function (ev) { console.log("移动"); var x = ev.clientX; var y = ev.clientY; // 盒子默认原点跟随鼠标移动 // 减去100|100, 代表盒子的100,100点跟随鼠标移动 // 想让点击点跟随鼠标移动 => 减去鼠标在自身位置上的偏移量 box.style.left = x - dX + 'px'; box.style.top = y - dY + 'px'; } }; box.onmouseup = function () { document.onmousemove = null; } </script> </html>
四、键盘事件
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>键盘事件</title> <style> .box { width: 100px; height: 100px; background: orange; position: absolute; top: 0; left: 0; } </style> </head> <body> <div class="box"></div> </body> <script> // 键盘长按会一直触发按下事件 document.onkeydown = function (ev) { console.log(ev); // 按下的键盘编号 console.log("按下", ev.keyCode); // console.log(ev.which); } document.onkeyup = function (ev) { console.log("抬起", ev.keyCode); } // 左上右下: 37-40 var box = document.querySelector('.box'); document.onkeydown = function (ev) { switch (ev.keyCode) { case 37: box.style.left = box.offsetLeft - 10 + 'px'; break; case 38: box.style.top = box.offsetTop - 10 + 'px'; break; case 39: box.style.left = box.offsetLeft + 10 + 'px'; break; case 40: box.style.top = box.offsetTop + 10 + 'px'; break; } } </script> </html>
五、其他时间应用
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>其他事件</title> <script> // 当页面加载完毕之后再回调 window.onload = function () { var box = document.querySelector('.box'); console.log(box); } // 页面滚动可以设置给 window | document var isShow = false; window.onscroll = function () { console.log(window.scrollY); if (window.scrollY >= 1200) { if (!isShow) { console.log("将返回Top按钮显示"); isShow = true; } } else { if (isShow) { isShow = false; } } } </script> </head> <body> <div class="box"></div> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> </body> </html>
六、定时器
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>定时器</title> </head> <body> </body> <script> // 1. 一次性定时器 // 三个参数: 逻辑函数, 时间间隔, 函数所需参数(一般情况下可以省略) setTimeout(function (arg1, arg2) { console.log(arg1, arg2); console.log("页面已经加载1s了, 我再执行, 且就一次"); }, 1000, "所需参数", 100); // 2. 持续性定时器 function action() { console.log("永久执行, 1s一次"); } // 定时器第一次执行,一定是设置的时间间隔第一次达到 var timer = setInterval(action, 1000); // timer用来接收定时器,那就是代表定时器 // 不会立马执行逻辑, 需要立马执行逻辑可以通过功能的手动调用 action(); // 3.清除定时器 // 前提: 明确清除哪一个定时器还是页面所有的定时器 // clearTimeout | clearInterval, 但是两者是通的 document.onclick = function () { clearTimeout(timer) } // 结论: // 1. 清除定时器直接可以混用 // 2. 创建定时器是有返回值的, 返回值就是创建定时器的数字标号 // 3. 对一个数字做定时器清除操作, 就会清除数字对应的定时器, // 如果数字没有对应定时器, 相当于清除失败, 无副作用 // 需求: 如果页面中有n个定时器 var n = setTimeout(function () {}, 1); for (var i = 1; i < n; i++) { clearInterval(i) } </script> </html>
七、定时器案例
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>定时器案例</title> </head> <body> <div class="box">12 : 01 : 35</div> </body> <script> // 时间类 var date = new Date(); // 时间戳 console.log(date.getTime()) var box = document.querySelector('.box') // 1s更新一次时间 setInterval(updateTime, 1); // 时间需要页面已加载就更新一次 function updateTime() { // 获取时间 var date = new Date(); var h = date.getHours(); var m = date.getMinutes(); var s = date.getSeconds(); // 格式化时间 h = h >= 10 ? h : "0" + h; m = m >= 10 ? m : "0" + m; s = s >= 10 ? s : "0" + s; var res = h + " : " + m + " : " + s; // 更新时间(页面标签内容) box.innerText = res; } updateTime(); </script> </html>
八、随机数
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>随机数</title> </head> <body> 随机数 </body> <script> var randomNum = Math.random(); // 随机数的取值范围: [0, 1) console.log(randomNum); // 要产生[n, m]之间的正整数 var r1 = parseInt(Math.random() * 11) + 5; // [5, 15] var r2 = parseInt(Math.random() * 21) + 7; // [7, 27] // var r3 = parseInt(Math.random() * (m - n + 1)) + n; // [n, m] function rFn(n, m) { return parseInt(Math.random() * (m - n + 1)) + n; } for (var i = 0; i < 20; i++) { console.log(rFn(3, 19)) } </script> </html>
小结: ## 1.事件总结 - 鼠标事件 ```js var box = document.querySelector('.box'); // 1. 点击事件 box.onclick = function () { console.log("单击"); }; // 2. 双击事件(应用场景不广) box.ondblclick = function () { console.log("双击"); }; // 3. 鼠标右键 box.oncontextmenu = function () { console.log("右键了"); return false; }; // 4. 鼠标悬浮 | 移动 | 按下 | 抬起 | 离开 box.onmouseover = function () { console.log("悬浮"); }; box.onmousemove = function () { console.log("移动"); }; box.onmousedown = function () { console.log("按下"); }; box.onmouseup = function () { console.log("抬起"); }; box.onmouseout = function () { console.log("离开"); } ``` ```js // over | out VS enter | leave // 总结: // 1. 将子级与父级分开考虑, 大家都有各自的悬浮离开事件, 采用 over | out 组合 // 2. 将子级纳入父级考虑范围, 也就是只有父级去相应悬浮离开事件, 采用 enter | leave 组合 // 3. 单独考虑一个盒子的悬浮离开事件, 两套均可以 // 特性 // 从父级移至子级, 会触发out事件, 紧接着触发子级的over事件, 并可以冒泡给父级 // 从父级移至子级, leave事件并不会触发, 它认为子级是属于父级的一部分, enter事件, 也不会再次触发 // 悬浮子级: // sub over => sup over 支持冒泡 // sup enter => sub enter 不支持冒泡 ``` - 键盘事件 ```js // onkeydown: 键盘按下会触发, 长按会持续触发 // onkeyup: 键盘抬起会触发 // ev.keyCode: 按下的键盘键的标号 ``` - 其他事件 ```js // window.onload: 页面加载完毕触发 // window.onscroll | document.onscroll => window.scrollY(页面下滚距离): 页面滚动触发 ``` ## 二.js盒模型 ```js // content: 通过计算后样式获取 // padding + content: box.clientWidth | box.clientHeight // border + padding + content: box.offsetWidth | box.offsetHeight // 绝对定位top|left: box.offsetTop | box.offsetLeft ``` ## 三.动画 - 定时器 ```js // 一次性定时器 var timeout = setTimeout(function(a, b){}, 1000, 10, 20); // 持续性定时器 var timer = setInterval(function(a, b){}, 1000, 10, 20); // 清除定时器 // clearTimeout | clearInterval //结论: // 1. 定时器不会立即执行 // 2. 一次性定时器只执行一次, 持续性定时器不做清除的话会一直执行 // 3. 声明定时器第一个参数为逻辑函数地址, 第二个参数为事件间隔, 第三个为逻辑函数所需参数(可以为多个,一般省略) // 4. 清除定时器可以混用, 本质就是清除创建定时器时的数字标号, 该编号就是创建定时器时的返回值 // 小技巧: 如果页面中有n个定时器 var n = setTimeout(function () {}, 1); for (var i = 1; i < n; i++) { clearInterval(i) } ```