詳解Jquery實現ready和bind事件
來源:易賢網 閱讀:1028 次 日期:2016-07-08 11:02:52
溫馨提示:易賢網小編為您整理了“詳解Jquery實現ready和bind事件”,方便廣大網友查閱!

這篇文章主要為大家詳細介紹了Jquery實現ready和bind事件的相關資料,感興趣的小伙伴們可以參考一下

講這一節之前,先回顧之前一段代碼:

(function (win) {

    var _$ = function (selector, context) {

      return new _$.prototype.Init(selector, context);

    }

    _$.prototype = {

      Init: function (selector, context) {

        this.elements = [];

        var context = context || document;

        if (context.querySelectorAll) {

          var arr = context.querySelectorAll(selector);

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

            this.elements.push(arr[i]);

          }

        }

        ////這一塊是選擇器的實現,沒有寫完,可以自己實現

      },

      each: function (callback) {

        if (this.elements.length > 0) {

          for (var i = 0; i < this.elements.length; i++) {

            callback.call(this, i, this.elements[i]);

          }

        }

      }

    }

    _$.prototype.Init.prototype = _$.prototype;

    window.$ = _$;

  })(window || global);

上面我們實現了節點的查找,今天要講的是對節點的事件綁定。

熟悉Jquery 源碼的TX應該知道:我們上面的代碼少了ready事件,只是針對節點進行查詢,并沒有將document對象考慮進去。我之前單獨講過window.onload和 document. ready的區別,還對document.ready事件進行了擴展。

現在我們把擴展方法加到這里面:

我們的Init方法要改正一下:

Init: function (selector, context) {

         this.elements = [];

         if (typeof selector === "function") {

           this.elements.push(document);

           this.ready(selector);

         }

         else {

           var context = context || document;

           var isDocument = function (ele) {

             var tostring = Object.prototype.toString;

             return tostring.call(ele) == "[object HTMLDocument]" || "[object Document]";

           }

           if (isDocument(selector)) {

             this.elements.push(selector);

           }

           else if (context.querySelectorAll) {

             var arr = context.querySelectorAll(selector);

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

               this.elements.push(arr[i]);

             }

           }

         }

       }

這段代碼的大致意思是:如果傳入的參數selector是function類型,就執行ready事件。如果是document就將document對象插入到this.elements數組里面(這個傳入之后,會在ready事件里面進行判斷)。如果是字符竄,就查詢出節點,循環插入到this.elements數組里面,沒什么難度。主要考慮到$(document).ready和$(function(){})這兩種ready事件的寫法。

我們接下來把ready函數加進來:

ready: function (callback) {

        var isDocument = function (ele) {

          var tostring = Object.prototype.toString;

          return tostring.call(ele) == "[object HTMLDocument]" | "[object Document]";

        }

        if (isDocument(this.elements[0])) {

          if (document.addEventListener) {

            document.addEventListener('DOMContentLoaded', function () {

              document.removeEventListener('DOMContentLoaded', arguments.callee, false);

              callback();

            }, false);

          }

          else if (document.attachEvent) {

            document.attachEvent('onreadystatechange', function () {

              if (document.readyState == "complete") {

                document.detachEvent('onreadystatechange', arguments.callee);

                callback();

              }

            });

          }

          else if (document.lastChild == document.body) {

            callback();

          }

        }

      }

這段代碼我之前其實講過了(onload和ready的區別),不知道的可以看看。

現在ready事件,我們實現了。然后就可以針對節點進行事件注冊了。

我們來實現bind函數,代碼如下:

bind: function (type, callback) {

         if (document.addEventListener) {

           this.each(function (i, item) {

             item.addEventListener(type, callback, false);

           });

         }

         else if (document.attachEvent) {

           this.each(function (i, item) {

             item.attachEvent('on' + type, callback);

           });

         }

         else {

           this.each(function (i, item) {

             tem['on' + type] = callback;

           });

         }

       }

這里面都是些兼容性代碼,實現節點的事件注冊。之前的each,大家可能不知道是要干嘛的。現在在這里面就用到了。

主要作用是針對節點循環做一些操作。

完整代碼,來一份:

(function (win) {

  var _$ = function (selector, context) {

    return new _$.prototype.Init(selector, context);

  }

  _$.prototype = {

    Init: function (selector, context) {

      this.elements = [];

      if (typeof selector === "function") {

        this.elements.push(document);

        this.ready(selector);

      }

      else {

        var context = context || document;

        var isDocument = function (ele) {

          var tostring = Object.prototype.toString;

          return tostring.call(ele) == "[object HTMLDocument]" | "[object Document]";

        }

        if (isDocument(selector)) {

          this.elements.push(selector);

        }

        else if (context.querySelectorAll) {

          var arr = context.querySelectorAll(selector);

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

            this.elements.push(arr[i]);

          }

        }

      }

    },

    each: function (callback) {

      var length = this.elements.length;

      if (length > 0) {

        for (var i = 0; i < length; i++) {

          callback.call(this, i, this.elements[i]);

        }

      }

    },

    ready: function (callback) {

      var isDocument = function (ele) {

        var tostring = Object.prototype.toString;

        return tostring.call(ele) == "[object HTMLDocument]" | "[object Document]";

      }

      if (isDocument(this.elements[0])) {

        if (document.addEventListener) {

          document.addEventListener('DOMContentLoaded', function () {

            document.removeEventListener('DOMContentLoaded', arguments.callee, false);

            callback();

          }, false);

        }

        else if (document.attachEvent) {

          document.attachEvent('onreadystatechange', function () {

            if (document.readyState == "complete") {

              document.detachEvent('onreadystatechange', arguments.callee);

              callback();

            }

          });

        }

        else if (document.lastChild == document.body) {

          callback();

        }

      }

    },

    bind: function (type, callback) {

      if (document.addEventListener) {

        this.each(function (i, item) {

          item.addEventListener(type, callback, false);

        });

      }

      else if (document.attachEvent) {

        this.each(function (i, item) {

          item.attachEvent('on' + type, callback);

        });

      }

      else {

        this.each(function (i, item) {

          tem['on' + type] = callback;

        });

      }

    }

  }

  _$.prototype.Init.prototype = _$.prototype;

  window.$ = _$;

})(window);

這幾個函數基本上可以實現對節點的事件注冊了。其余的一些特效,還需要擴展。如果感興趣的話可以自己在  _$.prototype對象里面加方法。

以上就是本文的全部內容,希望能夠幫助大家。

更多信息請查看網絡編程
易賢網手機網站地址:詳解Jquery實現ready和bind事件
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026國考·省考課程試聽報名

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
未满十八18勿进黄网站免费看