• <tfoot id="ukgsw"><input id="ukgsw"></input></tfoot>
    
    • 久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
      分享

      JavaScript面試問題:事件委托和this

       月影曉風 2015-07-22

      來自:淡忘~淺思

      英文出處:http:///2014/11/25/javascript-interview-questions-event-delegation/

      鏈接:http://www./1570.html

      JavaScript不僅門檻低,而且是一門有趣、功能強大和非常重要的語言。各行各業的人發現自己最混亂的選擇是JavaSscript編程語言。由于有著各種各樣的背景,所以不是每個人都對JavaScript及其基本原理有廣泛的認識。通常來書,除非你去參加工作面試才會去思考為什么或者怎么做,否則JavaScript只是你工作的內容。


      這個系類的目標是深入探討JavaScript的一些概念和理論。主題來自于 Darcy Clarke的JavaScript典型面試問題列表。希望你不僅僅是為了答案而閱讀完這篇文章,每一篇文章會讓對過去學過的知識有一個新的理解,或者重溫你學習的東西,這有利于你用JavaScript實現所有交互。


      詳解事件委托


      事件委托是一種由其它元素而非事件目標元素來響應事件產生的行為的思想。用document元素來處理按鈕的點擊行為就是事件委托的一個例子,另一種常見情況是,用ul元素來處理其子元素li的事件。


      有多種方法來處理事件委托。標準方法來源于原生瀏覽器的功能。瀏覽器以一種特定的工作流程來處理事件,并支持事件捕獲和事件冒泡。W3C關于瀏覽器怎么支持事件的文檔:W3C DOM Level 3 Events。一些JS庫和框架公開了其它方式,如發布/訂閱模型(將在后文提及)。


      事件捕獲和事件冒泡是事件流中的兩個階段,任何事件產生時,如點擊一個按鈕,將從最頂端的容器開始(一般是html的根節點)。瀏覽器會向下遍歷DOM樹直到找到觸發事件的元素,一旦瀏覽器找到該元素,事件流就進入事件目標階段,該階段完成后,瀏覽器會沿DOM樹向上冒泡直到最頂層容器,看看是否有其它元素需要使用同一個事件。


      下面的示例說明了這個過程。點擊按鈕會導致事件流識別本身在容器下面的文本,每一個元素都接收同樣的點擊監聽代碼,由于事件捕獲,點擊事件會首先觸發HTML節點綁定的點擊處理程序,然后在事件冒泡階段的末尾返回到最頂層元素。

      var nodes = $('*'),

      node = {};

      for (var i = 0; i < nodes.length; i ) {

      node = nodes[i];


      node.addEventListener('click', function (event) {

      $('#EventListing').append('Bubble ' (event.currentTarget.id || event.currentTarget.tagName) '<br/>');

      });


      node.addEventListener('click', function (event) {

      if (event.currentTarget != event.target) {

      $('#EventListing ').append('Capture ' (event.currentTarget.id || event.currentTarget.tagName) ' <br/>');

      }

      }, true);

      }

      View this on JSFiddle


      大多數現代庫使用冒泡監聽,而在捕獲階段處理。瀏覽器包含一個方法來管理事件冒泡。事件處理程序可以調用stopPropagation告訴DOM事件停止冒泡,第二個方式是調用stopImmediatePropagation,它不僅停止冒泡,也會阻止這個元素上其它監聽當前事件的處理程序觸發。然而,停止傳播事件時要小心,因為你不知道是否有其它上層的DOM元素可能需要知道當前事件。


      還有第三個可以控制元素如何對事件作出回應的方法。所有現代瀏覽器支持preventDefault方法,這個方法會阻止瀏覽器處理事件的默認行為。一個常見示例就是鏈接,使用鏈接執行UI操作是一種常見的做法。然而,當我們不希望鏈接跟普通被激活的鏈接一樣會在新標簽頁打開一個新頁面,就可以使用preventDefault方法來阻止這個默認行為。


      還有其它實現事件委托的方法可以考慮,其中值得一提的就是發布/訂閱模型。發布/訂閱模型也稱為了廣播模型,牽涉到兩個參與者。通常,兩個參與者在DOM中并沒有緊密的聯系,而且可能是來自兄弟的容器。可以給它們共同的祖先元素設置監聽處理程序,但是如果共同的祖先元素在DOM樹中處于較高層次(離根節點比較近),就會監聽很多同輩元素的事件,會造成意想不到的結果;當然,也可能存在邏輯或結構原因要分開這兩個元素。


      發布/訂閱模型也能自定義事件。發布/訂閱模型從一個元素發送消息后并向上遍歷,有時也向下遍歷,DOM會通知遍歷路徑上的所有元素事件發生了。在下面的示例中,JQuery通過trigger方法傳遞事件。

      $('#container').on('myCustomEvent', function (e, data) {

      $('#insertText').append(data);

      });


      $('#button2').click(function () {

      $('#button2').trigger('myCustomEvent', ['I triggered']);

      });

      View this on JSFiddle


      使用事件委托來管理事件流有很多優點,其中最大的優點是改善性能。元素綁定的每一個監聽器都會占用一些內存,如果頁面上只有少數幾個監聽器,我們也不會注意到它們之間的區別,然后,如果要監聽一個50行5列的表格中的每個單元格,你的Web應用會開始變慢,為了使應用程序最快運行的最好方式是保持盡可能低的內存使用。


      使用事件委托能減少監聽器數量,在元素的容器上綁定事件意味著只需要一個監聽器。這種方法的缺點是,父容器的偵聽器可能需要檢查事件來選擇正確的操作,而元素本身不會是一個監聽器。額外處理帶來的影響遠低于許多存在內存中的監聽器。


      更少的監聽器和更少的DOM交互也易于維護。父容器層次的監聽器能處理多種不同的事件操作,這是一種簡單的方法來管理相關的事件操作,這些事件通常需要執行相關功能或需要共享數據。


      如果父容器是監聽器,然后要執行獨立的內部操作而并不需要添加或者移除本身的監聽器。元素操作在單頁應用中是極其常見的,為某部分添加一個按鈕這樣簡單的事情也會為應用程序創建一個潛在的性能塊,沒有合適的事件委托,就必須手動為每一個按鈕添加監聽,如果每個偵聽器不清理干凈,它可能會導致內存泄漏。瀏覽器不會清理頁面,因此在單頁應用中,所有從內存中清理不當的碎片都會留在內存中,這些碎片會降低程序性能。


      當在頁面中添加交互時,仔細考慮一下,是否真的需要去監聽元素。


      另一篇值得一讀的文章:Event Delegation In JavaScript


      this在JavaScript中是怎么工作的


      this 關鍵字在JavaScript中的一種常用方法是指代碼當前上下文。


      ●如果this沒有被設置,則默認指向全局對象,其通常是window


      ●如果一個函數中運行了一個內聯函數,比如一個事件監聽器,則this指向內聯函數的源代碼。例如,當設置一個按鈕的單擊處理程序,this將引用匿名函數內的按鈕。


      ●如果函數是一個對象的構造函數,this指向新對象。


      ●如果函數被定義在一個對象上,然后調用對象時,this指向該對象。


      在異步編程中,this可以很容易改變過程中一個功能操作。保持處理程序上下文的一個小技巧是將其設置到閉包內的一個變量,當在上下文改變的地方調用一個函數時,如setTimeout,你仍然可以通過該變量引用需要的對象。


      操作this的另一種方式是通過call、apply和bind。三種方法都被用于調用一個函數,并能指定this的上下文,你可以讓代碼使用你規定的對象,而不是依靠瀏覽器去計算出this指向什么。Call、apply和bind本身是相當復雜的,應該有自己的文檔記錄,我們會把這當做未來待解決問題的一部分。下面是一個改變this指向方法的示例:

      setTimeout(function () {

      div.append(checkForWindow(this));

      div.append('<strong>that</strong> is the ' that.tagName '<br/>');

      }, 300);

      });



      function checkForWindow(elm) {

      if (elm instanceof Window) {

      return 'this is the Window<br/>';

      } else if (elm.tagName) {

      return ('this is the ' elm.tagName '<br/>');

      } else {

      return ('this is ' elm '<br/>');

      }

      }

      View this on JSFiddle


      事件委托和this是現代JavaScript中重要的功能,理解它們的工作原理是成功開發產品的關鍵,并且可以肯定的是,這是應聘JavaScript工程師必須要了解的。

      本文根據@Nicolas Bevacqua的《JavaScript Interview Questions: Event Delegation and This》所譯,整個譯文帶有我自己的理解與思想,如果譯得不好或有不對之處還請同行朋友指點。如需轉載此譯文,需注明英文出處:http:///2014/11/25/javascript-interview-questions-event-delegation/

        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發表

        請遵守用戶 評論公約

        類似文章 更多

        主站蜘蛛池模板: 亚洲AVAV天堂AV在线网阿V| 羞羞影院午夜男女爽爽免费视频| 真人无码作爱免费视频| 亚洲 制服 丝袜 无码| 六月丁香婷婷色狠狠久久 | 国语做受对白XXXXX在线| 中文字幕人妻无码一夲道| 成人免费视频在线观看播放| 中文精品久久久久人妻不卡| 日本高清在线观看WWW色| 国产69精品久久久久999小说| 少妇高潮水多太爽了动态图| 国产亚洲AV无码AV男人的天堂| 国产稚嫩高中生呻吟激情在线视频| 久久久国产精品VA麻豆| 亚洲精品无码久久一线| 熟妇人妻中文字幕| 午夜DY888国产精品影院| 精品久久久久中文字幕日本| 国产欧美VA天堂在线观看视频| 国产精品毛片在线完整版SAB| 国产成人综合欧美精品久久| 99久久激情国产精品| 久久午夜无码鲁丝片| 一本大道中文日本香蕉| 久久一区二区中文字幕| 成人午夜福利视频镇东影视| 中国CHINA体内裑精亚洲日本| 综合偷自拍亚洲乱中文字幕| 久久99精品九九九久久婷婷| 香港日本三级亚洲三级| 午夜无码区在线观看亚洲| 伊人狠狠色丁香婷婷综合| 中文字幕亚洲制服在线看| 少妇激情AV一区二区三区| 久久精品国产99精品国产2021| 伊人色综合一区二区三区影院视频| 亚洲欧美日韩国产精品专区| 精品无码国产自产拍在线观看| 国产成年码AV片在线观看| 国产乱码1卡二卡3卡四卡5|