<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [toc] ## 由 JS 事件引入 事件是 JS DOM 中極具活力的內容,你可以隨時監聽 DOM 的變化,并對它們及時的做出反應,如果你不是太懂 JS 中的事件,建議你先去看一些相關介紹的文章,直接看 jQuery 中的事件委托頭會頭大的。 事件的處理順序由兩個環節,一個是捕獲環節,一個是冒泡環節,借用別人的一張圖: ![](http://olphpb1zg.bkt.clouddn.com/1803376728-58b37acba12b8_articlex.jpg) 如果把處理也算進的話,整個事件分為三個階段,分別是捕獲階段,目標處理階段和冒泡階段。捕獲階段由外向內尋找 target,冒泡階段由內向外直到根結點。這只是一個事件,當這三個階段中又穿插著更多的事件時,還需要將事件的執行順序考慮進去。 而 jQuery 事件委托的概念:事件目標自身不處理事件,而是將其委托給父元素或祖先元素或根元素,而借助事件的冒泡性質(由內向外)來達到最終處理事件。 ## jQuery 中的事件優化 首先必須要知道,綁定事件越多,瀏覽器內存占用越大,就會間接的影響性能。而且一旦出現 ajax,局部刷新導致重新綁定事件。 使用事件委托可以解決以上帶來的問題,借助事件的冒泡,尤其當一個父元素的子元素過多,而且子元素綁定的事件非常多時,委托事件的作用就體現出來了。 我本人不善于比較 JS 中的性能問題,感興趣的可以去看看這篇文章關于事件委托性能的設計和比較。深入理解-事件委托。 在早期的 jQuery 版本,使用的是 .delegate()、.bind()、.live()等方法來實現事件監聽,當然也包括.click()方法,隨著 jQuery 的發展,像 live 方法已經明確從 jQuery 中刪除,而其余的方法,比如 bind 方法也將在 3.0 之后的版本陸續刪除,取而代之的是 .on()方法。而且剩下的其它方法都是通過 on 方法來間接實現的,如果介紹,只需要看 on 的源碼即可。 on 函數在 jQuery 中的用法也很簡單,.on( events [, selector ] [, data ], handler(eventObject) )events 表示綁定的事件,比如 "click" 或 "click mouseleave",selector 和 data 是可選的,分別表示要綁定事件的元素和要執行的數據,handler 表示事件執行函數。 off 函數的用法 .off( events [, selector ] [, handler ] ),events 代表要移除的事件,selector 表示選擇的 dom,handler 表示事件處理函數。還有更殘暴的比如 .off()不接受任何參數,表示著移除所有 on 綁定的函數。 ## on off 函數源碼 雖然我分析的源碼時 jQuery 3.1.1,但這個時候 bind 和 delegate 函數并沒有從源碼中移除呢,先來看看它們怎么調用 on: ``` jQuery.fn.extend( { bind: function( types, data, fn ) { return this.on( types, null, data, fn ); }, unbind: function( types, fn ) { return this.off( types, null, fn ); }, delegate: function( selector, types, data, fn ) { return this.on( types, selector, data, fn ); }, undelegate: function( selector, types, fn ) { // ( namespace ) or ( selector, types [, fn] ) return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); } } ); ``` 可以看得出來,全都被 on 和 off 這兩個函數來處理了。 ``` jQuery.fn.extend( { on: function (types, selector, data, fn) { // on 又依托于全局的 on 函數 return on(this, types, selector, data, fn); } } ); function on( elem, types, selector, data, fn, one ) { var origFn, type; // 支持 object 的情況 if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } // 一次執行 object 的每一個 for ( type in types ) { on( elem, type, selector, data, types[ type ], one ); } return elem; } // 參數為兩個的情況 if ( data == null && fn == null ) { // ( types, fn ) fn = selector; data = selector = undefined; } else if ( fn == null ) { if ( typeof selector === "string" ) { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if ( fn === false ) { // returnFalse 是一個返回 false 的函數 fn = returnFalse; } else if ( !fn ) { return elem; } if ( one === 1 ) { origFn = fn; fn = function( event ) { // Can use an empty set, since event contains the info jQuery().off( event ); return origFn.apply( this, arguments ); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); } return elem.each( function() { // 關鍵 jQuery.event.add( this, types, fn, data, selector ); } ); } ``` 是的,你沒有看錯,這個全局的 on 函數,其實只是起到了校正參數的作用,而真正的大頭是: ``` jQuery.event = { global = {}, add: function(){...}, remove: function(){...}, dispatch: function(){...}, handlers: function(){...}, addProp: function(){...}, fix: function(){...}, special: function(){...} } ``` off 函數: ``` jQuery.fn.off = function (types, selector, fn) { var handleObj, type; if (types && types.preventDefault && types.handleObj) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery(types.delegateTarget).off( handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if (typeof types === "object") { // ( types-object [, selector] ) for (type in types) { this.off(type, selector, types[type]); } return this; } if (selector === false || typeof selector === "function") { // ( types [, fn] ) fn = selector; selector = undefined; } if (fn === false) { fn = returnFalse; } return this.each(function() { // 關鍵 jQuery.event.remove(this, types, fn, selector); }); } ``` ## 總結 可見 jQuery 對于參數的放縱導致其處理起來非常復雜,不過對于使用者來說,卻非常大便利。 委托事件也帶來了一些不足,比如一些事件無法冒泡,load、submit 等,會加大管理等復雜,不好模擬用戶觸發事件等。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看