一,鼠标事件
```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 不支持冒泡
```
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>鼠标事件</title> <style> .box { width: 200px; height: 200px; background-color: red; } .sup { width: 200px; height: 200px; background-color: orange; margin: 0 auto; } .sub { width: 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
// onkeydown: 键盘按下会触发, 长按会持续触发
// onkeyup: 键盘抬起会触发
// ev.keyCode: 按下的键盘键的标号
```
- 其他事件
```js
// window.onload: 页面加载完毕触发
// window.onscroll | document.onscroll => window.scrollY(页面下滚距离): 页面滚动触发
```
<!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>
二.js盒模型
```js
// content: 通过计算后样式获取
// padding + content: box.clientWidth | box.clientHeight
// border + padding + content: box.offsetWidth | box.offsetHeight
// 绝对定位top|left: box.offsetTop | box.offsetLeft
```
<!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>
三动画中定时器
``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) }
<!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>