JavaScript事件處理的三種方式(轉)

一、什么是JavaScript事件?

? ?

?

? ? ? 事件(Event)是JavaScript應用跳動的心臟,也是把所有東西粘在一起的膠水,當我們與瀏覽器中Web頁面進行某些類型的交互時,事件就發生了。

? ? ? 事件可能是用戶在某些內容上的點擊、鼠標經過某個特定元素或按下鍵盤上的某些按鍵,事件還可能是Web瀏覽器中發生的事情,比如說某個Web頁面加載完成,或者是用戶滾動窗口或改變窗口大小。說白了,事件是文檔或瀏覽器中發生的特定交互瞬間!

? ? ? 通過使用JavaScript,你可以監聽特定事件的發生,并規定讓某些事件發生以對這些事件做出響應。

?

二、事件流

?

?

? ? ? 事件流就是描述了頁面中接受事件的順序,在瀏覽器發展的初期,兩大瀏覽器廠商IE和Netscape互掐,出現了一個坑爹的情況,那就是他們對事件流的解釋出現了兩中截然相反的定義。也就是我們所熟悉的:IE的事件冒泡,Netscape的事件捕獲。先來一張圖,簡要的看下結構:

? ? ? 1、事件冒泡

? ? ? 事件冒泡即事件最開始由最具體的元素(文檔中嵌套層次最深的那個節點)接收,然后逐級向上傳播至最不具體的節點(文檔)。拿上面的圖來說明,就是當點擊text部分時,先由text處的元素接收,然后逐級傳播至window,即執行6-7-8-9-10的過程。

? ? ? 2、事件捕獲

? ? ? 事件捕獲即事件最早由不太具體的節點接收,而最具體的節點最后接收到事件。同理,在上面的模型中,就是點擊text部分時,先由window接收,然后逐級傳播至text元素,即執行1-2-3-4-5的過程。

具體在代碼中怎樣表現呢?后面給出!

?

三、Javascript事件處理程序的3種方式

?

? ? ?

? ? ? 產生了事件,我們就要去處理他,Javascript事件處理程序主要有3種方式:

? ? ? 1、HTML事件處理程序

? ? ? 即我們直接在HTML代碼中添加事件處理程序,如下面這段代碼:

1 <input id="btn1" value="按鈕" type="button" onclick="showmsg();">
2   <script>
3       function showmsg(){
4           alert("HTML添加事件處理");
5       }
6   </script>

? ? ? 從上面的代碼中我們可以看出,事件處理是直接嵌套在元素里頭的,這樣有一個毛病:就是html代碼和js的耦合性太強,如果哪一天想要改變js中showmsg,那么不但要再js中修改,還需要到html中修改,一兩處的修改我們能接受,但是當你的代碼達到萬行級別的時候,修改起來就需要勞民傷財了,所以,這個方式我們并不推薦使用。

? ? ? 2、DOM0級事件處理程序

? ? ? 即為指定對象添加事件處理,看下面的一段代碼:

1 <input id="btn2" value="按鈕" type="button">
2   <script>
3     var btn2= document.getElementById("btn2");
4       btn2.onclick=function(){
5       alert("DOM0級添加事件處理");
6     } 
7     btn.onclick=null;//如果想要刪除btn2的點擊事件,將其置為null即可
8   </script> 

? ? ? 從上面的代碼中,我們能看出,相對于HTML事件處理程序,DOM0級事件,html代碼和js代碼的耦合性已經大大降低。但是,聰明的程序員還是不太滿足,期望尋找更簡便的處理方式,下面來看第三種處理方法。? ?

? ? ? 3、DOM2級事件處理程序

? ? ? DOM2也是對特定的對象添加事件處理程序,但是主要涉及到兩個方法,用于處理指定和刪除事件處理程序的操作:addEventListener()和 removeEventListener()。它們都接收三個參數:要處理的事件名、作為事件處理程序的函數和一個布爾值(是否在捕獲階段處理事件),看下面的一段代碼:

1 <input id="btn3" value="按鈕" type="button">
2   <script>
3      var btn3=document.getElementById("btn3");
4      btn3.addEventListener("click",showmsg,false);//這里我們把最后一個值置為false,即不在捕獲階段處理,一般來說冒泡處理在各瀏覽器中兼容性較好
5      function showmsg(){
6          alert("DOM2級添加事件處理程序");
7      }
8      btn3.removeEventListener("click",showmsg,false);//如果想要把這個事件刪除,只需要傳入同樣的參數即可
9   </script>

? ? ? 這里我們可以看到,在添加刪除事件處理的時候,最后一種方法更直接,也最簡便。但是馬海祥提醒大家需要注意的是,在刪除事件處理的時候,傳入的參數一定要跟之前的參數一致,否則刪除會失效!

?

四、事件冒泡和事件捕獲的流程與區別

?

?

? ? ? 說到這里,再給大家來一點代碼來說明下事件冒泡和事件捕獲的流程,同時也讓大家能看出二者的區別:

 1 <!doctype html>
 2   <html lang="en">
 3   <head>
 4       <meta charset="UTF-8">
 5       <title>Document</title>
 6       <style>
 7           #p{width:400px;height:200px;border:1px solid black;}
 8           #c{width:200px;height:100px;border:1px solid red;}
 9       </style>
10   </head>
11   <body>
12       <div id="p">
13           i am www.mahaixiang.cn
14           <div id="c">i like www.mahaixiang.cn</div>
15       </div>
16       <script>
17        var p = document.getElementById('p');
18          var c = document.getElementById('c');
19          c.addEventListener('click', function () {
20               alert('子節點捕獲')
21           }, true);
22          c.addEventListener('click', function () {
23               alert('子節點冒泡')
24          }, false);
25          p.addEventListener('click', function () {
26                alert('父節點捕獲')
27            }, true);
28          p.addEventListener('click', function () {
29              alert('父節點冒泡')
30           }, false);
31       </script>
32   </body>
33 </html>

?

? ? ? 運行上面的代碼,點擊子元素的時候,我們會發現,執行的先后順序是:父節點捕獲--子節點捕獲--子節點冒泡--父節點冒泡。從這個例子中,大家也就明白了,另外,DOM2級事件規定事件包括三個階段:

? ? ? 1、事件捕獲階段;

? ? ? 2、處于目標階段

? ? ? 3、事件冒泡階段。

? ? ? 首先是捕獲,然后處于目標階段(即來到事件的發出位置),最后才是冒泡,不科學的是,居然木有DOM1級事件處理程序,大家注意下,別鬧出笑話了!

五、補充

?

? ? ?

? ? ? 1. IE事件處理程序也對應有兩個方法:attachEvent()添加事件,detachEvent()刪除事件,這兩個方法接收相同的兩個參數:事件處理程序名稱與事處理函數。這里為什么沒有布爾值呢?因為ie8以及更早的版本只支持事件冒泡,所以最后一個參數默認的相當于false來處理!(支持IE事件處理程序的瀏覽器有IE,opera)。

? ? ? 2.?事件對象是用來記錄一些事件發生時的相關信息的對象,但事件對象只有事件發生時才會產生,并且只能是事件處理函數內部訪問,在所有事件處理函數運行結束后,事件對象就被銷毀!

?

? ? ? 文章轉自:?http://www.mahaixiang.cn/js/694.html

?

轉載于:https://www.cnblogs.com/alkq1989/p/5432292.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374773.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374773.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374773.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Erlang與Java內存架構

我讀了一篇關于Erlang VM的內存管理策略的非常非常有趣的文章。 它是Jesper Wilhelmsson撰寫的論文 &#xff0c;我認為討論Erlang的內存設置和Oracle的Java VM之間的差異可能會很好。 作為對從未聽說過Erlang的人的真正的簡短介紹; 它是一種功能語言&#xff0c;使用異步消息傳…

Xuggler教程:轉碼和媒體修改

注意&#xff1a;這是我們的“ Xuggler開發教程 ”系列的一部分。 在之前的教程中&#xff0c;我對視頻處理Xuggler進行了簡短介紹 。 在這一部分中&#xff0c;我們將看到Xuggler和FFmpeg提供的一些更令人興奮的功能&#xff0c;例如視頻轉碼和媒體修改。 不要忘記Xuggler是一…

Web工程師必備的43款可視化工具

國外站點DATAVISUALIZATION.CH為大家總結出了當前熱用的43款可視化工具&#xff0c;包括Arbor、Chroma.js、D3.js、Google Chart Tools等&#xff0c;絕對讓你一飽眼福。 1.Arbor.js Arbor是一個免費的、可視化的圖形庫&#xff0c;基于矢量創建動態的連接圖。它為圖形組織和屏…

力扣7. 整數反轉

方法一&#xff1a;官方給的&#xff0c;自己懂了后照著敲了一遍 class Solution {public int reverse(int x) {int rev 0;while (x ! 0) {//if判斷條件過于復雜&#xff0c;我好不容易看懂了if (rev < Integer.MIN_VALUE / 10 || rev > Integer.MAX_VALUE / 10) {retu…

AndroidManifest.xml中的application中的name屬性

被這個不起眼的屬性折磨了一天&#xff0c;終于解決了。 由于項目需要&#xff0c;要合并兩個android應用&#xff0c;于是拷代碼&#xff0c;拷布局文件&#xff0c;拷values&#xff0c;所有的都搞定之后程序還是頻頻崩潰&#xff0c;一直沒有找到原因&#xff0c;學android…

完美單身

我不時遇到一些Java程序員&#xff0c;他們不確定他們應該如何正確實現Singleton模式。 &#xff08;如果您不知道什么是Singleton&#xff0c;請嘗試Wikipedia&#xff1a; Singleton模式 &#xff09;。 我并不是在談論在線程環境中的正確實現。 但是&#xff0c;使用最常見的…

力扣移動零

給定一個數組 nums&#xff0c;編寫一個函數將所有 0 移動到數組的末尾&#xff0c;同時保持非零元素的相對順序。 我寫的代碼思路是從開始元素找0&#xff0c;找到了就將這個0后面的元素向前移一位 class Solution {public void moveZeroes(int[] nums) {int n nums.length;…

Doclava:來自Google的自定義Javadoc Doclet

Doclava是Google的自定義Javadoc Doclet&#xff0c;由Google Guice使用&#xff08;請參閱稍冷的 Javadocs &#xff09;。 Doclava使用JSilver作為其模板引擎&#xff0c;這是Clearsilver的純Java實現。 我個人喜歡聯合文檔的想法&#xff0c;它允許文檔在打開的項目上相互鏈…

linux cat顯示若干行

【一】從第3000行開始&#xff0c;顯示1000行。即顯示3000~3999行 cat filename | tail -n 3000 | head -n 1000 【二】顯示1000行到3000行 cat filename| head -n 3000 | tail -n 1000 *注意兩種方法的順序 分解&#xff1a; tail -n 1000&#xff1a;顯示最后1000行 tail -n …

【Stackoverflow好問題】java在,如何推斷陣列Array是否包括指定的值

問題java中&#xff0c;怎樣推斷數組Array是否包括指定的值精華回答1.Arrays.asList(...).contains(...) 2.使用 Apache Commons Lang包中的ArrayUtils.containsString[] fieldsToInclude { "id", "name", "location" };if ( ArrayUtils.contai…

力扣移除元素

給你一個數組 nums 和一個值 val&#xff0c;你需要 原地 移除所有數值等于 val 的元素&#xff0c;并返回移除后數組的新長度。 不要使用額外的數組空間&#xff0c;你必須僅使用 O(1) 額外空間并 原地 修改輸入數組。 元素的順序可以改變。你不需要考慮數組中超出新長度后面…

在域驅動設計中使用狀態模式

域驅動設計&#xff08;DDD&#xff09;是一種軟件開發方法&#xff0c;其中&#xff0c;通過將實現與核心業務概念的不斷發展的模型相連接&#xff0c;可以解決問題的復雜性。 該術語是由Eric Evans創造的&#xff0c;并且有一個DDD專用站點可以促進其使用。 根據其定義&#…

使用selenium進行密碼破解(繞過賬號密碼JS加密)

經常碰到網站&#xff0c;賬號密碼通過js加密后進行提交。通過burp攔截抓到的賬號密碼是加密后的&#xff0c;所以無法通過burp instruder進行破解。只能模擬瀏覽器填寫表單并點擊登錄按鈕進行破解。于是想到了自動化web測試工具selenium&#xff0c;代碼如下&#xff0c;測試效…

力扣刪除排序數組中的重復項

給你一個有序數組 nums &#xff0c;請你 原地 刪除重復出現的元素&#xff0c;使每個元素 只出現一次 &#xff0c;返回刪除后數組的新長度。 不要使用額外的數組空間&#xff0c;你必須在 原地 修改輸入數組 并在使用 O(1) 額外空間的條件下完成。 我沒注意到“有序”這一條…

POJ1789-Truck History .

題目鏈接&#xff1a;http://poj.org/problem?id1789 題目的大概意思就是給你n個字符串。每個字符串只有7的長度。然后分別給這些字符串編號。不同編號之間的距離就是他們有多少個不同的字母。&#xff08;同一個位置字母不相同也算&#xff09;然后一個編號只能由另一個派生…

Java Fork / Join進行并行編程

最近幾年&#xff0c;計算機處理器領域發生了范式轉變。 多年來&#xff0c;處理器制造商一直在提高時鐘頻率&#xff0c;因此開發人員享受到這樣的事實&#xff0c;即他們的單線程軟件執行得更快&#xff0c;而無需他們付出任何努力。 現在&#xff0c;處理器制造商青睞多核芯…

arm-elf-gcc交叉編譯器的使用教程

arm-elf-gcc交叉編譯器的使用教程 一開始需要安裝arm-elf-gcc&#xff0c;但是這是一個32位的程序&#xff0c;我是安裝了64位的系統&#xff0c;據說安裝ia32.libs依賴庫能運行這個&#xff0c;但是看到博客上面前人安裝完了系統圖標少了一半&#xff0c;然后就怕了。經過了翻…

力扣刪除排序數組中的重復項 II

給你一個有序數組 nums &#xff0c;請你 原地 刪除重復出現的元素&#xff0c;使每個元素 最多出現兩次 &#xff0c;返回刪除后數組的新長度。 不要使用額外的數組空間&#xff0c;你必須在 原地 修改輸入數組 并在使用 O(1) 額外空間的條件下完成。 思路&#xff1a; 雙指針…

2 android學習資料

http://blog.csdn.net/lmj623565791 http://blog.csdn.net/harvic880925/article/details/50995268轉載于:https://www.cnblogs.com/YyuTtian/p/5440930.html

建立自己的GWT Spring Maven原型

大家好&#xff0c; 在觀看Justin撰寫的有關Spring和GWT的非常有趣的文章時&#xff0c;我認為展示如何構建自己的自定義Maven原型非常有用。我們將展示的原型基于Justin的上一個項目&#xff0c;并包括各種技術&#xff0c;例如Spring &#xff0c; GWT &#xff0c; AspectJ…