1. 事件的模式
1.1 内联模式
- 直接在标签中绑定事件(要加小括号),
- 相对应的函数一定要是全局函数,
- this指向window
1.2 脚本模式
-
- 获取dom元素
-
- 绑定事件
-
- this指向的是当前dom元素
【注】运行顺序:
- ① 页面dom结构渲染,遇到script标签页面停止渲染,开始加载外部资源,加载完立即执行js脚本,执行完再加载页面。
- ② async:页面渲染和加载同时进行,script加载完之后立即执行js脚本,执行的过程中页面停止渲染,执行完再加载页面。async必须和script的src属性同时使用。
- ③ defer:页面渲染和加载同时进行,页面渲染完之后再执行js脚本。defer必须和script的src属性同时使用。
2. 事件的分类
2.1 鼠标事件
- ① 单击事件 onclick
- ② 双击事件 ondblclick
- ③ 鼠标按下事件 onmousedown
- ④ 鼠标抬起事件 onmouseup
- ⑤ 鼠标进入事件 onmouseenter
- ⑥ 鼠标离开事件 onmouseleave
- ⑦ 鼠标移动事件 onmousemove
- ⑧ 鼠标进入事件 onmouseover ---> 进入子元素会再次触发
- ⑨ 鼠标离开事件 onmouseout ---> 离开子元素会再次触发
- ⑩ 鼠标滚轮事件 onmousewheel
2.2 键盘事件
- ① 键盘按下事件 onkeydown
- ② 键盘抬起事件 onkeyup
- ③ 非功能键按下事件 onkeypress ---> 功能键:shift,ctrl,esc,delete...
2.3 html事件
-
① 页面加载事件 window.onload ---> 页面加载完成+外部资源加载完成后,触发
1) 页面的dom结构加载完成; 2) 外部资源也要加载完成; 3) 凡是带有src属性的标签,都有一个onload事件 (img,script) -
② 卸载事件 window.onunload
-
③ 改变窗口大小事件 window.onresize ---> 为了防止刷新失效,需要加事件的触发--->
window.resize(); -
④ 文本框选中事件 onselect ---> 选中输入框的内容+松开鼠标
-
⑤ 文本框改变内容事件 onchange ---> 内容改变后+失去焦点
-
⑥ 文本框输入事件 oninput ---> 内容改变就触发
-
⑦ 光标聚焦事件 onfocus
-
⑧ 失去焦点 onblur
-
⑨ 滚轮事件 window.onwheel
-
⑩ 滚动条事件 window.onscroll
-
⑪ 错误事件 window.onerror ---> 收集前端所有的错误(用于下次升级)
-
⑫ 右击菜单事件 document.oncontextmenu ---> 需要阻止右击的默认行为(
return fasle) -
⑬ 表单提交 onsubmit ---> form表单的提交事件!!!
1) 先触发js的onsubmit事件。(写了return false默认提交事件将不会被触发。) 2) 再触发表单的默认提交 -
⑭ 表单重置 onreset
【注】防抖和节流
- debounce防抖:事件连续触发且间隔时间小于规定时间,只触发最后一次事件。
- throttle节流:在规定时间内只执行一次。
3. 事件对象e
3.1 事件对象是什么:事件触发时会产生一条记录信息,包括点击的位置、点击的元素、触发的事件...
3.2 事件对象的兼容写法:
var e = evt || window.event
- window.event ---> ie的写法
- evt ---> 事件对应函数的一个形参
3.3 事件对象的常用属性:
- ①
e.button---> 0 左键,1 中间键,2 右键 - ②
e.ctrlKey---> 默认false,如果按下了ctrl键,就是true - ③
e.shiftKey---> 默认false,如果按下了shift键,就是true - ④
e.altKey---> 默认false,如果按下了alt键,就是true - ⑤
e.metaKey---> 默认false,如果按下了meta键,就是true - ⑥
e.keyCode---> 和onkeydown搭配使用 ---> enter 13,左 37,上 38,右 39,下 40 - ⑦
e.charCode---> 和onkeypress搭配使用 - ⑧
e.pageX,e.pageY---> 鼠标点的点到页面的距离 - ⑨
e.clientX,e.clientY---> 鼠标点击的点到浏览器可视区的距离 - ⑩
e.offsetX,e.offsetY---> 鼠标点击的点当前元素左上角的距离 - ⑪
e.screenX,e.screenY---> 鼠标点击的点到屏幕的距离
4. offset 三大家族
4.1 offsetWidth,offsetHeight ---> 获取自身宽高(自身宽高+border+padding)
【注意】 offsetWidth,offsetHeight 和 style.width,style.height 的区别:
offsetWidth,offsetHeight用来获取自身宽高。---> 能拿到内联样式内部样式外部样式里面设置的宽高,而且不带单位,便于计算style.width,style.height用来设置自身宽高。---> 只能获取到内联样式设置的宽高而且带单位
4.2 offsetLeft,offsetTop ---> 获取当前元素到有定位父元素之间的距离。如果父元素都没有定位,就到body的距离
4.3 offsetParent ---> 获取带有定位的父元素
5. 事件委托与目标元素 e.target
- 什么是事件委托:把事件绑定给父元素,通过 e.target 得到被点击的元素。
- 事件委托的作用:可以减少事件绑定带来的开销
6. 阻止事件冒泡
6.1 事件流:
- 事件是有传递性的,当几个都具有事件的元素层叠在一起的时候,那么你点击其中一个元素,层叠在你点击范围的所有元素都会触发事件。捕获阶段:由外向内。冒泡阶段:由内向外。
6.2 为什么要阻止事件冒泡:
- 当只在指定的节点上添加事件, 而不想让其传递到外层节点触发事件, 这样我们就需要阻止事件冒泡。
6.3 阻止事件冒泡的方法 ---> 通过事件对象e
-
e.stopPropagation( );---> google 火狐 (重点) -
e.cancelBubble = true;---> ie -
兼容写法:
if (e.stopPropagation) { //判断e有没有这个方法,如果有调用这个方法,否则else调用另外一种方法。方法也是属性的一种,只是方法的值是一个函数。 e.stopPropagation(); } else { e.cancelBubble = true; }
7. 阻止默认行为
7.1 默认行为
- ① a标签的跳转
- ② 表单的提交
- ③ 表单的重置
- ④ 图片的拖拽
- ⑤ 右击菜单
7.2 阻止默认行为的方法
-
方式一:
return false; -
方式二:通过事件对象 e
-
e.preventDefault( ) ---> google 火狐 (重点)
-
e.returnValue = false ---> ie
-
兼容写法:
if (e.preventDefault) { //判断e有没有这个方法,如果有调用这个方法,否则else调用另外一种方法。方法也是属性的一种,只是方法的值是一个函数。 e.preventDefault(); } else { e.returnValue = false; }
-
8. 事件监听
多次绑定事件的好处:单个事件可以实现多种功能。
oBox.onclick=fn; 不能多次绑定事件。(因为直接多次用事件绑定很容易被覆盖) ---> 多次绑定事件需要用到事件监听。
8.1 添加事件监听 oBox.addEventListener(参数1,参数2,参数3)
- ① 参数1:事件名称(没有on)
- ② 参数2:回调函数fn
- ③ 参数3:布尔值 / 对象
- 1)若是Boolean值。表示是否在捕获阶段监听。
- 默认值是false ---> 冒泡阶段;true---> 捕获阶段
- 2)若是对象。表示用来修饰回调函数fn的一些可选属性。{ }里面的可选值:
- once:true, // fn执行一次就清除fn
- capture:true, // fn在捕获阶段执行
- passive:true, // fn永远不会调用 preventDefault( )
- 1)若是Boolean值。表示是否在捕获阶段监听。
【了解】oBox.attachEvent("onclick",fn); // 添加事件 (ie678写法)
8.2 移除事件监听 oBox.removeEventListener("事件名称",回调函数)
【注意】添加的函数与移除的函数必须是同一个才生效。函数是引用类型,储存在堆中,不会被轻易改变。
【了解】
oBox.detachEvent("onclick",fn); // 移除事件 (ie678写法)
8.3 事件流的捕获阶段 ---> 要用事件监听
9. 封装工具库
- 全局函数、全局变量的缺点:容易被污染,被其他的所覆盖或者修改。
- 解决办法:自执行函数,自运行函数,会自己运行起来。写法:
(function(){})()。- ① 第1个小括号里面放匿名函数;
- ② 第2个小括号表示调用,可以往里面传参
- 封装js库的格式:
10. 一些封装的方法
10.1 随机颜色
function randomColor() { // 16进制写法
var str = "#";
for (var i = 0; i < 6; i++) {
str += parseInt(Math.random() * 16).toString(16);
}
return str;
}
10.2 生成范围内的随机数
function randomNum(n, m) {
var max = n > m ? n : m;
var min = n < m ? n : m;
return parseInt(Math.random() * (max - min + 1)) + min;
}
10.3 数组去重
function noRepeat(arr) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) == -1) {
newArr.push(arr[i]);
}
}
return newArr;
}
10.4 获取元素的属性值 ---> 当元素被隐藏时部分属性值获取不到,就需要用到该方法
function getStyle(ele, attr) {
if (window.getComputedStyle) {
return window.getComputedStyle(ele, null)[attr];
// window.getComputedStyle(参数1,参数2) ---> 谷歌,火狐写法
// 参数1:指定元素
// 参数2: ① null ---> 获取指定元素(参数1)的样式属性
// ② :before, :after ---> 获取指定元素的伪元素
}
return ele.crrentStyle[attr];
// 指定元素.crrentStyle ---> ie写法
}
10.5 获取元素到body的距离 ---> offsetParent最高级别是body
function offset(ele) {
var o = { left: ele.offsetLeft, top: ele.offsetTop };
while (ele.offsetParent) {
ele = ele.offsetParent;
o.left += ele.offsetLeft;
o.top += ele.offsetTop;
}
return o;
}
10.6 获取不可见区域的高度
function getScroll() {
if (window.pageYOffset != undefined) { // 适用ie9,谷歌,火狐而且不用考虑DTD
return {
left: window.pageXOffset,
top: window.pageYOffset,
}
} else if (document.compatMode == "CSS1Compat") { // 判断是否有声明头
return {
left: document.documentElement.scrollLeft,
top: document.documentElement.scrollTop,
}
}
return {
left: document.body.scrollLeft,// 适用 ie 6 7 8
top: document.body.scrollTop,
}
}