成人精品一区二区三区中文字幕-成人精品一区二区三区-成人精品一级毛片-成人精品亚洲-日本在线视频一区二区-日本在线视频免费

導航首頁 ? 技術教程 ? 詳解Jquery實現ready和bind事件
全站頭部文字 我要出現在這里
詳解Jquery實現ready和bind事件 690 2024-03-08   

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

  (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對象里面加方法。

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



主站蜘蛛池模板: 我和我的父辈 电影| 妻子出轨| 大红枣儿甜又香简谱| 案例分析100例| 追龙演员表全部名单| 情侣不雅| 名字简写设计| 好妻子电视剧免费在线观看| 春心荡漾第二季无删减| outlander| 飞虎神鹰1-42集免费| 家庭理论电影| 罗比威廉姆斯| 艾米·怀恩豪斯| 孕期检查项目一览表| 敦煌夜谭在线观看| 季芹| 乱世佳人电视剧免费观看完整版| 转正意见发言简短| 女人高潮私密按摩视频| 免费观看美国破釜沉舟电影| 小姐诱心在线| 南来北往分集剧情| 梁祝小提琴独奏曲谱完整版| 家庭琐事电影| 啪啪电影网| 彭丹丹最惊艳的电影| 陈浩民演的电视剧大全| 戴氏家族目前最大官| 天堂在线电影| 郭京飞个人资料简介| 密会韩剧| 求佛的歌词| 光彩年华| 大头儿子第一季小鸽子| 曹东| 02j331| 100以内加减法题库100题可打印| 女演员大作战| 老友记 第一季 1994 詹妮弗·安妮斯顿 | 历史试卷反思|

!!!站長長期在線接!!!

網站、小程序:定制開發/二次開發/仿制開發等

各種疑難雜癥解決/定制接口/定制采集等

站長微信:lxwl520520

站長QQ:1737366103