以下大部分为学习《JavaScript 高级程序设计》(第 3 版) 所做笔记。
目录:
1. 了解 UI 事件
2. load 事件
3. unload 事件
4. resize 事件
5. scroll 事件
Q: UI 是什么意思?
A: UI 是 User Interface 的缩写,意思是用户界面。
Q: 什么是 UI 事件?
A: UI 事件指的是那些不一定与用户操作有关的事件。
Q: UI 事件什么时候会被触发?
A: 当用户与页面上的元素交互时触发。
Q: UI 事件有哪些?
A: DOMActivate load unload abort error select resize scroll
Q: 何时会在何处触发 load 事件?
A: 页面完全加载后(包括所有图像、JavaScript文件、CSS文件等外部资源)在 window 上触发,当所有框架都加载完毕时在框架上面触发,当图像加载完毕时在 <img> 元素上面触发。
定义 onload 事件处理程序的方式
第一种方式:通过 JS 来指定事件处理程序的方式。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
var EventUtil = {
//视情况分别使用 DOM0 级方法、DOM2 级方法或 IE 方法来添加事件
addHandler: function(element, type, handler){
if(element.addEventListener){
element.addEventListener(type, handler, false)
}else if(element.attachEvent){
element.attachEvent("on"+type, handler);
}else{
element["on"+type] = handler;
}
},
//返回对 event 的引用
getEvent: function(event){
return event ? event : window.event;
},
//返回事件的目标
getTarget: function(event){
return event.target || event.srcElement;
},
//取消事件的默认行为
preventDefault: function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
},
//移除之前添加的事件处理程序
removeHandler: function(element, type, handler){
if(element.removeEventListener){
element.removeEventListener(type, handler, false)
}else if(element.detachEvent){
element.detachEvent("on"+type, handler);
}else{
element["on"+type] = null;
}
},
//阻止事件流
//因为 IE不支持事件捕获,所以在跨浏览器情况下也只能用于阻止事件冒泡
stopPropagation: function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
};
EventUtil.addHandler(window, "load", function(event){
console.log("loaded");
})
</script>
</body>
</html>

(跨浏览器对象 EventUtil :https://www.cnblogs.com/xiaoxuStudy/p/13131725.html#three )
控制台输出:

第二种方式:为 <body> 元素添加一个 onload 特性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body onload="console.log('loaded')">
</body>
</html>

控制台输出:

🔹 根据 "DOM2 级事件" 规范,应该在 document 而非 window 上面触发 load 事件。但是,所有浏览器都在 window 上面实现了该事件,以确保向后兼容。
🔹 因为在 HTML 中无法访问 window 元素,所以在 window 上发生的任何事件都可以在 <body> 元素中通过相应的特性来指定。
图像上触发onload事件
方式1:在 HTML 中为图像指定 onload 事件处理程序
下面例子实现图片加载完毕之后控制台输出“图片加载完毕”。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<img src="pic.jpg" onload="console.log('图片加载完毕')">
</body>
</html>

图片加载完毕后触发图像上面的 onload 事件,控制台打印"图片加载完毕"。

方式2:通过 JS 为图像指定事件处理程序
下面例子实现图片加载完毕之后在控制台输出图片的src。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<img src="pic.jpg" id="pic1">
<script>
//跨浏览器对象 EventUtil
var EventUtil = {
//视情况分别使用 DOM0 级方法、DOM2 级方法或 IE 方法来添加事件
addHandler: function(element, type, handler){
if(element.addEventListener){
element.addEventListener(type, handler, false)
}else if(element.attachEvent){
element.attachEvent("on"+type, handler);
}else{
element["on"+type] = handler;
}
},
//返回对 event 的引用
getEvent: function(event){
return event ? event : window.event;
},
//返回事件的目标
getTarget: function(event){
return event.target || event.srcElement;
},
//取消事件的默认行为
preventDefault: function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
},
//移除之前添加的事件处理程序
removeHandler: function(element, type, handler){
if(element.removeEventListener){
element.removeEventListener(type, handler, false)
}else if(element.detachEvent){
element.detachEvent("on"+type, handler);
}else{
element["on"+type] = null;
}
},
//阻止事件流
//因为 IE不支持事件捕获,所以在跨浏览器情况下也只能用于阻止事件冒泡
stopPropagation: function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
};
//取得图片的引用
var image = document.getElementById("pic1");
//添加load事件,注册到image上
EventUtil.addHandler(image, "load", function(event){
event = EventUtil.getEvent(event);
console.log(EventUtil.getTarget(event).src);
})
</script>
</body>
</html>

🔹 新图像元素不一定要从添加到文档后才开始下载,只要设置了 src 属性就会开始下载。
实现:预先加载图像,再添加 onload 事件,再为图片设置 src
方式1:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
//跨浏览器对象 EventUtil
var EventUtil = {
//视情况分别使用 DOM0 级方法、DOM2 级方法或 IE 方法来添加事件
addHandler: function(element, type, handler){
if(element.addEventListener){
element.addEventListener(type, handler, false)
}else if(element.attachEvent){
element.attachEvent("on"+type, handler);
}else{
element["on"+type] = handler;
}
},
//返回对 event 的引用
getEvent: function(event){
return event ? event : window.event;
},
//返回事件的目标
getTarget: function(event){
return event.target || event.srcElement;
},
//取消事件的默认行为
preventDefault: function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
},
//移除之前添加的事件处理程序
removeHandler: function(element, type, handler){
if(element.removeEventListener){
element.removeEventListener(type, handler, false)
}else if(element.detachEvent){
element.detachEvent("on"+type, handler);
}else{
element["on"+type] = null;
}
},
//阻止事件流
//因为 IE不支持事件捕获,所以在跨浏览器情况下也只能用于阻止事件冒泡
stopPropagation: function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
};
//为 window 指定 onload 事件处理程序
//确保往 DOM 中添加新元素之前页面已经加载完毕,如果在页面加载完毕之前操作 document.body 会出错
EventUtil.addHandler(window, "load", function(){
//创建一个图片元素
var image = document.createElement("img");
//为 image 指定 onload 事件
//图片加载完毕之后给出提示,控制台输出 src 作为提示
EventUtil.addHandler(image, "load", function(){
event = EventUtil.getEvent(event);
console.log(EventUtil.getTarget(event).src);
});
//添加节点 image
document.body.appendChild(image);
//设置图像的 src
//新图像元素不一定要从添加到文档后才开始下载,只要设置了 src 属性就会开始下载
image.src = "pic.jpg";
})
</script>
</body>
</html>

方式2 : 使用 DOM0 级的 Image 对象实现
❔ 不知道哪里出问题了,图片没显示出来...

为 <script> 元素指定事件处理程序
用处:开发人员确定动态加载的 JS 文件是否加载完毕
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
//跨浏览器对象 EventUtil
var EventUtil = {
//视情况分别使用 DOM0 级方法、DOM2 级方法或 IE 方法来添加事件
addHandler: function(element, type, handler){
if(element.addEventListener){
element.addEventListener(type, handler, false)
}else if(element.attachEvent){
element.attachEvent("on"+type, handler);
}else{
element["on"+type] = handler;
}
},
//返回对 event 的引用
getEvent: function(event){
return event ? event : window.event;
},
//返回事件的目标
getTarget: function(event){
return event.target || event.srcElement;
},
//取消事件的默认行为
preventDefault: function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
},
//移除之前添加的事件处理程序
removeHandler: function(element, type, handler){
if(element.removeEventListener){
element.removeEventListener(type, handler, false)
}else if(element.detachEvent){
element.detachEvent("on"+type, handler);
}else{
element["on"+type] = null;
}
},
//阻止事件流
//因为 IE不支持事件捕获,所以在跨浏览器情况下也只能用于阻止事件冒泡
stopPropagation: function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
};
//为 window 指定 onload 事件处理程序
EventUtil.addHandler(window, "load", function(){
//创建一个 <script> 元素
var script = document.createElement("script");
//为 script 指定 onload 事件处理程序
EventUtil.addHandler(script, "load", function(){
//script 加载完毕之后在控制台输出提示
console.log("JS文件加载完毕");
});
//设置 script 的 src
script.src="test.js";
//将 script 添加到文档中
document.body.appendChild(script);
})
</script>
</body>
</html>

🔹 只有在设置了 <script> 元素的 src 属性并将该元素添加到文档后,才会开始下载 JS 文件。也就是说对于<script>元素而言,指定 src 属性和指定事件处理程序的先后顺序不重要了。
🔹 大多数浏览器中 event 对象的 target 属性引用的是 <script> 节点,在 Firefox3 之前引用的是 document。
🔹 IE8 及更早版本不支持 <script> 元素上的 load 事件。
为 <link> 元素指定事件处理程序
用处:开发人员确定样式表是否加载完毕
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
//跨浏览器对象 EventUtil
var EventUtil = {
//视情况分别使用 DOM0 级方法、DOM2 级方法或 IE 方法来添加事件
addHandler: function(element, type, handler){
if(element.addEventListener){
element.addEventListener(type, handler, false)
}else if(element.attachEvent){
element.attachEvent("on"+type, handler);
}else{
element["on"+type] = handler;
}
},
//返回对 event 的引用
getEvent: function(event){
return event ? event : window.event;
},
//返回事件的目标
getTarget: function(event){
return event.target || event.srcElement;
},
//取消事件的默认行为
preventDefault: function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
},
//移除之前添加的事件处理程序
removeHandler: function(element, type, handler){
if(element.removeEventListener){
element.removeEventListener(type, handler, false)
}else if(element.detachEvent){
element.detachEvent("on"+type, handler);
}else{
element["on"+type] = null;
}
},
//阻止事件流
//因为 IE不支持事件捕获,所以在跨浏览器情况下也只能用于阻止事件冒泡
stopPropagation: function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
};
//为 window 指定 onload 事件处理程序
EventUtil.addHandler(window, "load", function(){
//创建一个 <link> 元素
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
//为 link 指定 onload 事件处理程序
EventUtil.addHandler(link, "load", function(){
//link 加载完毕之后在控制台输出
console.log("样式表加载完毕");
});
//设置 link 的 href
link.href = "test.css";
//将 link 添加到文档中
document.body.appendChild(link);
})
</script>
</body>
</html>

🔹 在未指定 href 属性并将 <link> 元素添加到文档之前不会开始下载样式表
🔹 支持的浏览器:IE、Opera
Q: 何时在何处会触发 unload 事件?
A: 文档被完全卸载后在 window 上面触发 unload 事件,当所有框架都卸载后在框架集上触发,当嵌入的内容卸载完毕后在 <object> 元素上触发。只要用户从一个页面切换到另一个页面,就会发生 unload 事件。
Q: 什么情况需要用到 unload 事件?
A: 清除引用的时候。清除引用避免内存泄漏。
指定 onunload 事件处理程序的方式
方式1: 通过 JS 来指定事件处理程序
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script type="text/javascript" src="EventUtil.js"></script>
<script>
//为 window 指定 onunload 事件处理程序
EventUtil.addHandler(window, "unload", function(){
alert("unloaded");
})
</script>
</body>
</html>
方式2:为 <body> 元素添加一个 onunload 特性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body onunload="alert('unloaded')">
</body>
</html>
❔ 在浏览器运行方式1跟方式2的代码,尝试了点击链接、关闭浏览器窗口、重新载入页面,不知道为什么都没有触发 unload 事件。
🔹 为了确保向后兼容,所有浏览器都在 window 上实现了 unload 事件。即使,根据"DOM2级事件",应该在 <body> 元素而非 window 对象上触发 unload 事件。
Q: 什么情况会触发 resize 事件?
A: 当浏览器窗口被调整到一个新的高度或宽度时会触发。浏览器窗口最大化或最小化也会触发。
Q: 何时会触发 resize 事件?
A: 不同浏览器有不同的机制。
▶ IE、Safari、Chrome、Opera:浏览器窗口变化了 1 像素时触发,然后随着变化不断触发
▶ Firefox:只会在用户停止调整窗口大小时才会触发
Q: 不同浏览器存在不同的机制,在进行开发时应该注意什么?
A: 应该注意不要在事件的处理程序中加入大计算量的代码,因为这些代码可能会被频繁执行,从而导致浏览器反应明显变慢。
Q: resize 事件在哪里触发?
A: window(窗口)上
指定 resize 事件处理程序的方式
方式1: 通过 JS 来指定事件处理程序
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script type="text/javascript" src="EventUtil.js"></script>
<script>
//为 window 指定 onresize 事件处理程序
EventUtil.addHandler(window, "resize", function(){
console.log("resized");
})
</script>
</body>
</html>

方式2:为 <body> 元素添加一个 resize 特性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body onresize="console.log('resized')">
</body>
</html>

Q: 在何时何处触发 scroll 事件?
A: scroll 事件是在 window 对象上发生的。当用户滚动带滚动条的元素中的内容时,在该元素上触发。<body> 元素中包含所加载页面的滚动条。
Q: scroll 事件表示什么?
A: 表示页面中相应元素的变化。
Q: 使用 scroll 事件时需要注意什么?
A: 与 resize 事件类似,scroll 事件也会在文档被滚动期间重复被触发,所以有必要保持事件处理程序的代码简单
指定 scroll 事件处理程序的方式
下例实现:滑动滚动条时,在框下文字动态提示滚动了多少次。
方式1: 通过 JS 来指定事件处理程序
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
div{
border: 10px solid yellowgreen;
width: 200px;
height: 200px;
overflow: scroll;
}
</style>
</head>
<body>
<div id="div1">
2020年5月30日,爱奇艺《青春有你第二季》总决赛举行。通过总决赛最后一次考核舞台现场,九名女团人选最终确定,她们分别是:刘雨昕、虞书欣、许佳琪、喻言、谢可寅、安崎、赵小棠、孔雪儿、陆柯燃,组合名称为“THE NINE”,代表独一无二的九人女团。
</div>
<p>滚动<span id="scrollNum"> 0 </span>次</p>
<script type="text/javascript" src="EventUtil.js"></script>
<script>
var div = document.getElementById("div1");
var x = 0;
//为 div 指定 onscroll 事件处理程序
EventUtil.addHandler(div, "scroll", function(){
document.getElementById("scrollNum").innerHTML = x += 1;
})
</script>
</body>
</html>

方式2: 为 <div> 元素添加一个 resize 特性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
div{
border: 10px solid yellowgreen;
width: 200px;
height: 200px;
overflow: scroll;
}
</style>
</head>
<body>
<div onscroll="fn()">
2020年5月30日,爱奇艺《青春有你第二季》总决赛举行。通过总决赛最后一次考核舞台现场,九名女团人选最终确定,她们分别是:刘雨昕、虞书欣、许佳琪、喻言、谢可寅、安崎、赵小棠、孔雪儿、陆柯燃,组合名称为“THE NINE”,代表独一无二的九人女团。
</div>
<p>滚动<span id="scrollNum"> 0 </span>次</p>
<script>
x = 0;
function fn(){
document.getElementById("scrollNum").innerHTML = x += 1;
}
</script>
</body>
</html>

浙公网安备 33010602011771号