详解Jquery实现ready和bind事件
来源: 阅读:834 次 日期: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对象里面加方法。

以上就是本文的全部内容,希望能够帮助大家。

更多信息请查看网络编程
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:hfpxwx
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map