JavaScript DOM 事件初探的圖文程式碼詳細介紹
事件,就是在文件或瀏覽器視窗中發生的一些特定的互動瞬間,例如點擊、雙擊、滑鼠懸浮等。
事件流
事件流描述的是從頁面中接收事件的順序,或者說是事件在頁面中傳播的順序。
IE的事件流叫做事件冒泡(event bubbling):由最具體的元素開始執行事件,然後逐級向上傳播到window對象。
網景團隊提出的事件流叫做事件擷取(event capturing):由最外層的window 物件開始執行事件,然後逐漸向下傳播到最具體的元素。
下面我們要做個小實驗來說明這兩個事件流的差異:
// html 文档 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件流 实验</title> </head> <body> <p id="test" style="font-size:3em;">点我点我,我是p</p> </body> </html>
// 事件冒泡 var p = document.getElementById("test"); p.addEventListener("click",function(){ console.log("i am p"); }, false); document.body.addEventListener("click",function(){ console.log("i am body"); }, false); document.documentElement.addEventListener("click",function(){ console.log("i am html"); }, false); document.addEventListener("click",function(){ console.log("i am document"); }, false); window.addEventListener("click",function(){ console.log("i am window"); }, false);
点击p,控制端会打印如下: i am p i am body i am html i am document i am window
// 事件捕获 var p = document.getElementById("test"); p.addEventListener("click",function(){ console.log("i am p"); }, true); document.body.addEventListener("click",function(){ console.log("i am body"); }, true); document.documentElement.addEventListener("click",function(){ console.log("i am html"); }, true); document.addEventListener("click",function(){ console.log("i am document"); }, true); window.addEventListener("click",function(){ console.log("i am window"); }, true);
圖片經過二次處理,略醜,請見諒!
点击p,控制端会打印如下: i am window i am document i am html i am body i am p
可以看出,事件冒泡和事件捕獲是兩種完全相反的事件流。
平常,一般都是在使用事件冒泡,只在特殊情況下使用事件捕獲。
DOM2級事件規定的事件流包含三個階段:事件擷取階段、處於目標階段、事件冒泡階段。
// 事件冒泡和事件捕获混合一下 var p = document.getElementById("test"); p.addEventListener("click",function(){ console.log("i am p"); }, true); document.body.addEventListener("click",function(){ console.log("i am body"); }, false); // 改为在冒泡阶段调用事件处理程序 document.documentElement.addEventListener("click",function(){ console.log("i am html"); }, true); document.addEventListener("click",function(){ console.log("i am document"); }, true); window.addEventListener("click",function(){ console.log("i am window"); }, false); // 改为在冒泡阶段调用事件处理程序
這張圖片是直接從書上摘得,自己腦補一下,把 window 物件自行添上去吧!
点击p,控制端会打印如下: i am document i am html i am p i am body i am window
事件處理程序
事件處理程序:指的是回應處理某個事件的函數
HTML 事件處理程序
某個元素支援的每個事件,都可以使用一個與對應事件處理程序同名的HTML 特性來指定。
// 情况一 <button onclick="alert('I am button!');">按钮</button> // 情况二 <button onclick="show();">按钮</button> <script> function show(){ alert("I am button!"); } </script>
建議永遠不要使用這種方式為元素添加事件,因為這種方法有一個巨大的缺點,就是使得 HTML 與 JavaScript 的程式碼緊密耦合,不符合網頁設計的行為與結構分離。
DOM0 層級事件處理程序
每個元素(包括window 和document)都有自己的事件處理程序屬性,例如onclick、 onmouseup 等。
把上面的程式碼改寫如下:
<button id="test">按钮</button> var button = document.getElementById("test"); button.onclick = function(){ // this 对象指向 button 元素 console.log(this); alert("I am button!"); }; /* 删除指定的事件处理程序 */ button.onclick = null;
DOM2 級事件處理程序
DOM2 級事件 定義了兩個方法,用來處理指定和刪除事件處理程序的動作:addEventListener()和 removeEventListener()。
這兩個方法都有三個參數,第一個參數是事件名,第二個參數是作為事件處理程序的函數,第三個參數是一個布林值,預設值是false,表示在冒泡階段呼叫事件處理程序,如果這個值是true,表示在擷取階段呼叫事件處理程序。
繼續改寫上面的程式碼:
var button = document.getElementById("test"); function show(){ // this 对象指向 button 元素 console.log(this); alert("I am button!"); } // 添加事件处理程序 button.addEventListener("click",show, false); button.addEventListener("click",function(){ alert("I am second alert!"); },false); // 删除事件处理程序 button.removeEventListener("click",show, false); // 删除成功 button.removeEventListener("click",function(){ // 删除失败 alert("I am second alert!"); },false);
使用 DOM2 層級方法新增事件處理程序的主要好處是可以為一個元素新增多個事件處理程序。
如果 addEventListener() 新增的事件處理函數是匿名函數,則無法透過 removeEventListener() 刪除這個事件處理程序。
IE 事件處理程序
IE8 以及更早的IE 版本,只支援事件冒泡,不支援addEventListener() 和removeEventListener(),但是它實作了與這兩個方法類似的兩個方法:attachEvent() 和 detachEvent()。這兩個方法只有兩個參數,一個事件名稱(是 onclick,不是 click),一個事件處理函數。
與 addEventListener() 不同,使用attachEvent() 方法的情況下,事件處理函數會在全域作用域下執行,所以 this 等於 window,這點需要特別注意。
var button = document.getElementById("test"); button.attachEvent("onclick", function(){ // this 对象指向了全局作用域,即 window console.log(this); alert("I am button!"); }); button.attachEvent("onclick",function(){ alert("I am second alert!"); }); // 上面也是为同一个按钮绑定了两个事件处理程序 button.detachEvent("onclick",function(){ // 删除失败 alert("I am second alert!"); });
除非你想讓你的程式相容至 IE8- 瀏覽器,否則不要使用這兩個函數。
瀏覽器預設行為
對於一些特定的事件,瀏覽器有它預設的行為。例如:點擊連結會進行跳到指定的頁面、點擊滑鼠右鍵會呼出瀏覽器右鍵選單、填寫表單時按回車會自動提交到伺服器等。
預設的瀏覽器行為和冒泡行為是獨立的,取消事件預設行為是不會取消事件冒泡的,反之亦然。同一個元素的多個事件處理函數也是相互獨立的。
<p> <a id="test" href="http://baidu.com">点我点我,我是链接</a> </p> var link = document.getElementById("test"); // 方法一 event.preventDefault() link.onclick = function(event){ console.log("You click!"); event.preventDefault(); }; // 方法二 return false link.onclick = function(event){ console.log("You click!"); return false; };
參考:事件-4.瀏覽器預設行為-宇卿
事件物件event
在觸發DOM 上的某個事件時,會產生一個事件物件event,而這個物件中包含著所有與該事件有關的資訊。
event 对象只存在于事件处理程序执行期间,一旦执行完毕,立即被销毁。
<p> <a id="test" href="http://baidu.com">点我点我,我是链接</a> </p> /* 下列 event 对象的属性和方法都是只读的 */ var link = document.getElementById("test"); link.onclick = function(event){ // 判断当前事件是否会向 DOM 树上层元素冒泡 console.log(event.bubbles); // 判断是否可以取消事件的默认行为 console.log(event.cancelable); // 使用该方法可以取消事件的默认行为(使用前提是 cancelable 属性的值为 true) event.preventDefault(); // 判断是否已经调用了 preventDefault() 方法(DOM3级事件新增) console.log(event.defaultPrevented); // 指向事件遍历 DOM 时,识别事件的当前目标对象 console.log(event.currentTarget); // 指向触发事件的对象 console.log(event.target); // 表示事件流当前处于哪一个阶段 // 值为 1 表示在捕获阶段,值为 2 表示处于目标阶段,值为 3 表示在冒泡阶段 console.log(event.eventPhase); // 返回一个字符串, 表示该事件对象的事件类型 console.log(event.type); // 立即停止当前事件在 DOM 层次中的传播,即取消进一步的事件捕获或冒泡 event.stopPropagation(); };
为了进一步说明 event.stopPropagation() 的运行效果,借用前面的代码,更改如下:
// 事件冒泡和事件捕获混合一下 var p = document.getElementById("test"); p.addEventListener("click",function(){ console.log("i am p"); }, true); document.body.addEventListener("click",function(){ console.log("i am body"); }, false); // 改为在冒泡阶段调用事件处理程序 document.documentElement.addEventListener("click",function(){ console.log("i am html"); event.stopPropagation(); // 立即停止事件在 DOM 中的传播 }, true); document.addEventListener("click",function(){ console.log("i am document"); }, true); window.addEventListener("click",function(){ console.log("i am window"); }, false); // 改为在冒泡阶段调用事件处理程序
点击p,控制端会打印如下: i am document i am html
看到了吧,后面元素的事件就不会被激发了。
事件类型
UI 事件
UI 事件指的是简单的用户界面事件
load 事件:当页面所有资源(比如图像、css文件、js文件等资源)完全加载完毕后,就会触发 window 上面的 load 事件。
当然,我们也可以单独为某个元素设置 load 事件,比如为一个图片绑定这个事件,就可以检测这个图片是否加载完毕了。
<img src="/static/imghw/default1.png" data-src="1.jpg" class="lazy" id="myImg" / alt="JavaScript DOM 事件初探的圖文程式碼詳細介紹" > var img = document.getElementById("myImg"); img.onload = function(){ alert("Image loaded!"); };
scroll 事件:在文档被滚动期间,重复触发该事件。
window.onscroll = function(){ console.log("Scroll!"); };
焦点事件
焦点事件会在页面元素获得或失去焦点时触发。
注意:默认情况下,只有部分 html 元素能获得鼠标焦点(如 input,a),很大一部分 html 元素是不能获得鼠标焦点的(如 p,img),这些能够获得鼠标焦点的元素就是 focusable 元素。
不过,可以通过为这些默认没有焦点事件的元素添加一个 tabindex 属性,从而使它可以支持焦点事件。
document.activeElement:返回当前页面中获得焦点的元素,如果没有某个元素获得焦点,则该属性的值为当前页面中的元素
document.hasFocus():判断当前文档或者当前文档的子节点是否获得了焦点
HTMLElement.focus():使得指定的元素获得焦点(前提是这个元素是一个可以获得焦点的元素)
HTMLElement.blur():移除当前元素获得的焦点
上面是一些 HTML5 中添加的焦点管理 API。下面说焦点事件:
focus 事件:在元素获得焦点时触发,这个事件不会冒泡
blur 事件:在元素失去焦点时触发,这个事件不会冒泡
focusin 事件:在元素获得焦点时触发,与 focus 事件等价,但会冒泡
focusout 事件:在元素失去焦点时触发,与 blur 事件等价,但会冒泡
<img src="/static/imghw/default1.png" data-src="1.jpg" class="lazy" id="img" tabindex="1" / alt="JavaScript DOM 事件初探的圖文程式碼詳細介紹" > var img = document.getElementById("img"); document.body.onscroll = function() { img.blur(); }; img.onfocus = function() { console.log("Img focused!"); }; img.onblur = function() { console.log("Img lose focus!"); }; img.onclick = function() { console.log(document.activeElement); console.log(document.hasFocus()); };
注意: focusin 和 focusout 事件,所有的 Firefox 版本都不支持,看这里。chrome 和 safari 中只有通过 addEventListener 方式绑定这两个事件才能正常使用,其他方式绑定都不行。
说说focus /focusin /focusout /blur 事件(推荐)
(WHATWG)Focus management APIs
鼠标与滚轮事件
DOM3 级事件中定义了9个鼠标事件。
<body> <p id="test"> <button>按钮</button> </p> </body> // css p { width: 300px; height: 300px; margin: 50px auto; border: 1px solid #aaa; }
mouseover 事件:鼠标指针首次进入一个元素边界之内时触发,会冒泡
mouseout 事件:鼠标指针移出这个元素边界时触发,会冒泡
var test = document.getElementById("test"); test.onmouseover = function(event){ event.target.style.border = "3px solid #666"; }; test.onmouseout = function(event){ event.target.style.border = "none"; };
mouseenter 事件:鼠标指针首次移动到元素范围之内时触发,不冒泡
mouseleave 事件:鼠标指针移动到元素范围之外时触发,不冒泡
var test = document.getElementById("test"); test.onmouseenter = function(event){ event.target.style.border = "10px solid #666"; }; test.onmouseleave = function(event){ event.target.style.border = "none"; };
mousemove 事件:当鼠标在元素内部移动时重复触发,会冒泡
// 这里写一个鼠标在 body 内移动时,背景颜色随机变化的脚本 document.body.onmousemove = function(){ var r = Math.floor(Math.random() * 256) g = Math.floor(Math.random() * 256) b = Math.floor(Math.random() * 256); document.body.style.background = "rgb("+r+","+g+","+b+")"; };
mousedown 事件:用户通过按下任意鼠标按钮时触发
mouseup 事件:用户释放鼠标按钮时触发
click 事件:用户单击鼠标左键时或按下回车键时触发
dblclick 事件:用户双击鼠标左键时触发
var body = document.body; body.onmousedown = function(){ console.log("Mouse down!"); }; body.onmouseup = function(){ console.log("Mouse up!"); }; body.onclick = function(){ console.log("One click!"); }; body.ondblclick = function(){ console.log("Double click!"); };
// 双击 body,控制端打印: Mouse down! Mouse up! One click! Mouse down! Mouse up! One click! Double click!
只有在同一个元素上相继触发 mousedown 和 mouseup 事件,才会触发 click 事件,缺一不可。类似地,只有连续触发两次 click 事件,才会触发 dblclick 事件。
获取点击坐标
clientX 和 clientY:鼠标指针在视口中的坐标
pageX 和 pageY:鼠标指针在页面中的坐标
screenX 和 screenY:鼠标指针在屏幕中的坐标
在页面没有滚动的情况下,pageX 和 pageY 的值与 clientX 和 clientY 的值相等。
document.body.onclick = function() { console.log("Client: " + "(" + event.clientX + "," + event.clientY + ")"); console.log("Page: " + "(" + event.pageX + "," + event.pageY + ")"); console.log("Screen: " + "(" + event.screenX + "," + event.screenY + ")"); };
键盘与文本事件
keydown 事件:当用户按下任意键时触发,而且如果按住不放的话,会重复触发此事件
keypress 事件:当用户按下任意字符键时触发,而且如果按住不放的话,会重复触发此事件
keyup 事件:当用户释放键盘上的按键时触发
在用户按下一个字符键并且立马释放这个按键的过程中,先触发 keydown 事件,再触发 keypress 事件,最后触发 keyup 事件。
window.onkeydown = function() { console.log("on key down"); }; window.onkeyup = function() { if (event.keyCode === 65) { console.log(event.key); } console.log("one key up"); }; window.onkeypress = function() { console.log("one key press"); };
为了知道自己按下的是哪个按键,可以使用 event.which 来获得你按下按键的键码(比如字母 A 的键码为 65)。也可以通过键码属性(event.keyCode)来对特定的按键来进行响应。键码参考表
发生 keypress 事件时,会存在一个 charCode 属性,返回这个按键代表字符的 ASCII 编码。ASCII table
event.which 返回一个 keyCode 或 charCode 值,详情看下面代码
String.fromCharCode() 静态方法可以将 event.which 转化为相应的字符。
// 请自行粘贴复制于浏览器控制端测试 // 分别输入 a 和 A // A和a 的 ASCII码分别为65,97 window.onkeydown = function(){ if(event.keyCode === 65){ console.log("(keydown keyCode)You press 'a' or 'A'!"); } if(event.charCode === 65){ console.log("(keydown charCode)You press 'A'!"); } console.log("keydown event.which = " + event.which); console.log("(keydown:)" + String.fromCharCode(event.which)); }; window.onkeypress = function(){ if(event.keyCode === 65){ console.log("(keypress keyCode)You press 'A'!"); } if(event.charCode === 65){ console.log("(keypress charCode)You press 'A',not 'a'!"); } console.log("keypress event.which = " + event.which); console.log("(keypress:)" + String.fromCharCode(event.which)); };
在 DOM3 级事件中,做了一些变化,不再推荐使用 keyCode、charCode、which 属性,而是出现了两个新属性:
key
和char
,用来替代keyCode
和charCode
属性。但是不建议使用 key、char 属性,因为有一部分浏览器对他支持的不是很好。点这里
参考:JavaScript 事件——“事件类型”中“键盘与文本事件”的注意要点
变动事件
变动事件是在 DOM 结构发生变化时触发
在 DOM2 中定义了多个变动事件,但是在 DOM3 中又废除了一些,在这里先简单提一下有这个东西,以后用到再作补充。
HTML5 事件
contextmenu 事件:单击鼠标右键,会触发这个事件并调出页面的上下文菜单。这个事件是鼠标事件的一种,并且支持冒泡。
在上面的例子中,我们演示了利用 contextmenu 事件来设置自定义右键菜单,以及屏蔽右键菜单。
然而,屏蔽右键菜单却难不倒高手,Greasy Fork 上面有一个脚本(网页限制解除),专门来打破对右键菜单有限制的页面。
beforeunload 事件:当浏览器窗口,文档或其资源将要卸载时或者刷新页面时,会触发这个事件【MDN】
下面有几点需要注意一下:
1. 如果处理函数为 Event 对象的 returnValue 属性赋值非空字符串,浏览器会弹出一个对话框,来询问用户是否确定要离开当前页面。没有赋值时,该事件不做任何响应。
2. 从2011年5月25号开始,HTML5规范指出在此事件处理函数中,对于window.alert(), window.confirm(), 和 window.prompt() 的调用会被忽略。
3. 旧版本的浏览器可能会在提示框里显示返回的信息,但是新版本浏览器都默认采用浏览器内设的提示信息。
// 复制粘贴于浏览器控制端,然后关闭页面,会出现提示框 window.addEventListener("beforeunload", function() { var message = "你真的要离开吗?"; event.returnValue = message; return message; }, false);
DOMContentLoaded 事件:在页面文档形成完整的 DOM 树时触发,不理会图像、js文件、css文件等资源是否加载完毕
这个事件可以为 document 或 window 绑定,但实际目标是 document。这个事件会冒泡。
注意:这个事件与 load 事件是不一样的,正常情况下,会早于 load 事件被触发。
感觉篇幅太长了,事件委托、移动设备中的事件、事件对内存性能的影响等内容将在以后逐渐写出。
以上就是JavaScript DOM 事件初探的图文代码详细介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

dom是一種文件物件模型,同時也是用於html程式設計的接口,透過dom來操作頁面中的元素。 DOM是HTML文件的記憶體中物件表示,它提供了使用JavaScript與網頁互動的方式。 DOM是節點的層次結構(或樹),其中document節點為根。

vue3ref綁定dom或元件失敗原因分析場景描述在vue3中常用到使用ref綁定元件或dom元素的情況,很多時候,明明使用ref綁定了相關元件,但是經常ref綁定失敗的情況。 ref綁定失敗情況舉例ref綁定失敗的絕大多數情況是,在ref和元件綁定的時候,該元件還未渲染,所以綁定失敗。或是元件剛開始未渲染,ref未綁定,當元件開始渲染,ref也開始綁定,但是ref和元件並未綁定完成,這個時候使用元件相關的方法就會出現問題。 ref綁定的元件使用了v-if,或他的父元件使用了v-if導致頁面

1.原生js取得DOM節點:document.querySelector(選擇器)document.getElementById(id選擇器)document.getElementsByClassName(class選擇器)....2.vue2中取得目前元件的實例物件:因為每個vue的元件實例上,都包含一個$refs對象,裡面儲存著對應的DOM元素或元件的參考。所以在預設情況下,元件的$refs指向一個空物件。可以先在元件上加上ref="名字",然後透過this.$refs.

dom和bom物件有:1、「document」、「element」、「Node」、「Event」和「Window」等5種DOM物件;2、「window」、「navigator」、「location」、「history」和「screen」等5種BOM物件。

在網頁開發中,DOM(DocumentObjectModel)是一個非常重要的概念。它可以讓開發者輕鬆地對一個網頁的HTML或XML文件進行修改和操作,例如新增、刪除、修改元素等。而PHP內建的DOM操作庫也為開發者提供了豐富的功能,本文將介紹PHP中的DOM操作指南,希望可以幫助大家。 DOM的基本概念DOM是一個跨平台、獨立於語言的API,它可以將

bom和dom在作用和功能、與JavaScript的關係、相互依賴性、不同瀏覽器的兼容性和安全性考量等方面都有區別。詳細介紹:1、作用和功能,BOM的主要作用是操作瀏覽器窗口,它提供了瀏覽器窗口的直接訪問和控制,而DOM的主要作用則是將網頁文檔轉換為一個對象樹,允許開發者透過這個物件樹來取得和修改網頁的元素和內容;2、與JavaScript的關係等等。

dom 內建物件有:1、document;2、window;3、navigator;4、location;5、history;6、screen;7、document.documentElement;8、document.body;9、document.head;10、document .title;11、文檔.cookie。

DOM實現了對網頁內容的動態訪問和更新,BOM則提供了與瀏覽器視窗進行交互的API,包括控制瀏覽器的行為、獲取瀏覽器和用戶環境的信息,DOM主要用於操作網頁內容,而BOM則主要用於操作瀏覽器視窗和與瀏覽器交互,兩者共同構成了Web前端開發中重要的基礎,為開發者提供了豐富的方法來控制和操作網頁及瀏覽器,實現交互性強、使用者體驗良好的Web應用程式。
