• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
小许学习笔记
博客园    首页    新随笔    联系   管理    订阅  订阅
JavaScript 【事件】UI事件

以下大部分为学习《JavaScript 高级程序设计》(第 3 版) 所做笔记。

目录:

1. 了解 UI 事件

2. load 事件

3. unload 事件

4. resize 事件

5. scroll 事件

 

了解UI事件

Q: UI 是什么意思?

A: UI 是 User Interface 的缩写,意思是用户界面。

Q: 什么是 UI 事件?

A: UI 事件指的是那些不一定与用户操作有关的事件。

Q: UI 事件什么时候会被触发?

A: 当用户与页面上的元素交互时触发。

Q: UI 事件有哪些?

A: DOMActivate load unload abort error select resize scroll

 

load 事件

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

 

unload 事件

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 事件。

 

resize 事件

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>

 

scroll 事件

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>

 

posted on 2020-06-17 18:45  xiaoxustudy  阅读(798)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3