文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php教程>你值得了解的JavaScript“继承之jquery”使用方法(代码详解)

你值得了解的JavaScript“继承之jquery”使用方法(代码详解)

时间:2021-08-31  来源:互联网

今天PHP爱好者给大家带来JavaScript“继承之jquery”的使用方法,之前的文章《深入解析JS中数组reduce方法(附代码)》中,给大家了解一下JS中数组reduce方法。下面本篇文章给大家了解一下JS-继承之jquery使用方法,小伙伴们可以参考一下。希望对大家有所帮助。

jquery截止到当前已经 3.3.1 版本了,如今随着各种浏览器的盛行,前端的框架层出不穷,jquery独步天下,老夫写代码只用jquery,拿起代码就是干的辉煌时代已经过去了。

2006 年,jQuery的第一个版本的面世,凭借着简洁、灵活的编程风格受到了开发者的喜爱。而它本身是一个JavaScript框架,它的设计的宗旨是“write LessDo More”,即倡导写更少的代码,做更多的事情。它封装了JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。

从之前的风靡到如今的被抛弃,究其原因,不少前端工程师表示,对于jQuery来说,大量的操作DOM虽然方便,但是会牺牲很多页面的性能。另一方面,现阶段ReactVueAngularjs等主流前端框架并不依赖jQuery,都可以独立使用。况且浏览器的兼容问题越来越少,当浏览器兼容不再是问题时,jQuery的价值就大打折扣了

就在微软收购github的 52 天,github改变也已经放弃了jquery,奇替代方案使用了原生的 js

  • 使用querySelectorAll来查询DOM节点;

  • 使用fetch来代替ajax

  • 事件处理使用了事件代理;

  • 使用DOM标准化写了polyfill

  • 使用了自定义元素。

微信截图_20210819112650.jpg

假如不用,学习下还是可以的

本文粗燥的实现jqueryready、each、bind、``$.fn.extend、$.extend

初始化$

(function (win) {
 var _$ = function (selector, context) {
   /**
    * 通常咱们定义一个 函数 var Fun = function(){}
    * 然后定义一个 Fun.prototype.init = function(){}
    * 那么咱们调用init 的时候 得先要实例化对象 var f = new Fun()
    * 然后f.init()
    * 这里就省去了 var $ = new $()
    */
   return new _$.prototype.Init(selector, context);
 };
 _$.prototype = {
   //初始化$
   Init: function (selector, context) {
     this.elements = [];
     /**
      * 传入的类型是function 就执行ready事件,如果是document 就将document对象插入到this.elements
      * 主要就是判断$(document).ready  和 $(function(){}) 这两种的ready事件的写法
      */
     if (typeof selector === "function") {
       this.elements.push(document);
       this.ready(selector);
     } else {
       var context = context || document;
       var isDocument = (ele) =>
         Object.prototype.toString.call(ele) == "[object HTMLDocument]" ||
         "[object Document]";
       if (isDocument(selector)) {
         this.elements.push(selector);
       } else {
         /**
          * 如果是字符串的话就查询该节点 $('.class') | $('#id')
          */
         if (context.querySelectorAll) {
           var arr = context.querySelectorAll(selector);
           for (var i = 0; i < arr.length; i++) {
             this.elements.push(arr[i]);
           }
         }
       }
     }
   },
   //实现each
   each: function (callback) {},
   //实现ready
   ready: function (callback) {},
   //实现bind
   bind: function (type, callback) {},
 };
 /**
  * 让两个作用域不一样的对象共享一个方法,让他们的原型指向一致,即Init.prototype = _$.prototype
  * 那么原型一致之后 就可以共享this.elements 属性了。
  */
 _$.prototype.Init.prototype = _$.prototype;
 window.$ = _$;
})(window || global);

ready

//实现ready
ready: function (callback) {
 var isDocument = (ele) => Object.prototype.toString.call(ele) == '[object HTMLDocument]' || '[object Document]'
 //如果已经取得了节点
 if (isDocument(this.elements[0])) {
   if (document.addEventListener) { //判断火狐、谷歌
     /**
      * DOM树构建完成的时候就会执行DOMContentLoaded
      * 页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,才会触发window.onload
      * 这也就是$(document).ready() 比 window.onload 执行早的原因
      *
      * arguments.callee 博客里面有一篇文章 [js-递归] 里面专门讲到了,这里不再解释了
      */
     document.addEventListener('DOMContentLoaded', function () {
       document.removeEventListener('DOMContentLoaded', arguments.callee, false)
       callback()
     }, false)
   } else if (document.attachEvent) { //判断IE
     document.attachEvent('onreadystatechange', function () {
       if (document.readyState == 'complete') {
         document.detachEvent('onreadystatechange', arguments.callee);
         callback()
       }
     })
   } else if (document.lastChild == document.body) { //body已经加载完了,就直接回调了
     callback()
   }
 }
},

each

//实现each
each: function (callback) {
   if (this.elements.length > 0) {
       for (var i = 0; i < this.elements.length; i++) {
       callback.call(this, this.elements[i], i);
       }
   }
},

bind

//实现bind
bind: function (type, callback) {
 if (document.addEventListener) { //判断火狐、谷歌
   this.each(function (item, i) {
       item.addEventListener(type, callback, false)
   })
   } else if (document.attachEvent) { //判断IE
   this.each(function (item, i) {
       item.attachEvent('on' + type, callback)
   })
   } else {
   this.each(function (item, i) { //其他浏览器 egg: item.onclick = function(){}
       item['on' + type] = callback
   })
 }
}

$.fn.extend/$.extend

$.fn.extend是为查询的节点对象扩展方法,是基于$的原型扩展的方法

$.extend是扩展常规方法,是$的静态方法

官方给出解释:

jQuery.extend(): Merge the contents of two or more objects together into the first object.(把两个或者更多的对象合并到第一个当中)

jQuery.fn.extend():Merge the contents of an object onto the jQuery prototype to provide new jQuery instance methods.(把对象挂载到jQueryprototype属性,来扩展一个新的jQuery实例方法)

$.fn.extend方法的初衷是我们扩展之后可以用$("").newMetod()这样访问,实际上就是给$原型加一个extend方法。这中间的fn其实类似于命名空间的作用,没什么实际的意义。为的是和$.extend作区分

$.fn.extend

; (function (win) {
 ...
 _$.prototype.Init.prototype = _$.prototype;

  _$.fn = _$.prototype; //把对象挂载到jQuery的prototype属性

 var isObj = (o) => Object.prototype.toString().call(o) === '[object Object]';
 $.fn.extend = function (obj) {
   if (isObj(obj)) {
     for (var i in obj) {
       this[i] = obj  //注意这里的this指向是 $.prototype
     }
   }
 }

$.extend

var isObj = (o) => Object.prototype.toString().call(o) === '[object Object]';
...
_$.extend = function (obj) {
   if (isObj(obj)) {
       for (var i in obj) {
           this[i] = obj[i]; //注意这里的this指向是 $
       }
   }
}

这俩看上去一模一样啊,没啥区别,注释里面已经说了,this指向不同。咱们来看个例子:

<!DOCTYPE html>
<html>
 <head>
   <title>jQuery.extend()与jQuery.fn.extend()区别</title>
   <meta charset="utf-8" />
   <script type="text/javascript" src="jquery.js"></script>
   <!-- 开始扩展 -->
   <script type="text/javascript">
     (function ($) {
       $.extend({
         sayHello: function () {
           console.log("Hello");
         },
       });
       $.fn.extend({
         sayHello: function () {
           console.log("Hello");
         },
       });
     })(jQuery);
   </script>
   <!-- 调用 -->
   <script type="text/javascript">
     $(document).ready(function () {
       //$.extend扩展调用
       $.sayHello();

       //$.fn.extend扩展调用
       $("#test").sayHello();
     });
   </script>
 </head>
 <body>
   <p id="test"></p>
 </body>
</html>

这样以来就看的很明白了。jQuery.extend(object); 为扩展jQuery类本身,为自身添加新的方法。$.xxx()

jQuery.fn.extend(object);jQuery对象添加方法$('#test').xxx()

$.extend常见用法

//在jquery全局对象中扩展一个net命名空间。
$.extend({ net: {} });

//方法扩展到之前扩展的Jquery的net命名空间中去。
$.extend($.net, {
 sayHello: function () {
   console.log("Hello");
 },
});

//extend方法还有一个重载原型
//extend(boolean,dest,src1,src2,src3...),第一个参数boolean代表是否进行深度拷贝
var a = { protocol: "http", hash: { a: 1, b: 2 } };
var b = { host: "chuchur.com", hash: { b: 1, c: 2 } };

var result = $.extend(true, {}, a, b);
console.log(result); //{ protocol: 'http',host: 'chuchur.com', hash: { a: 1, b: 1,c:2 } }

var result = $.extend(false, {}, a, b);
console.log(result); //{ protocol: 'http',host: 'chuchur.com', hash: { b: 1, c:2 } }

完整代码

(function (win) {
 var _$ = function (selector, context) {
   /**
    * 通常咱们定义一个 函数 var Fun = function(){}
    * 然后定义一个 Fun.prototype.init = function(){}
    * 那么咱们调用init 的时候 得先要实例化对象 var f = new Fun()
    * 然后f.init()
    * 这里就省去了 var $ = new $()
    */
   return new _$.prototype.Init(selector, context);
 };
 _$.prototype = {
   //初始化$
   Init: function (selector, context) {
     this.elements = [];
     /**
      * 传入的类型是function 就执行ready事件,如果是document 就将document对象插入到this.elements
      * 主要就是判断$(document).ready  和 $(function(){}) 这两种的ready事件的写法
      */
     if (typeof selector === "function") {
       this.elements.push(document);
       this.ready(selector);
     } else {
       var context = context || document;
       var isDocument = (ele) =>
         Object.prototype.toString.call(ele) == "[object HTMLDocument]" ||
         "[object Document]";
       if (isDocument(selector)) {
         this.elements.push(selector);
       } else {
         /**
          * 如果是字符串的话就查询该节点 $('.class') | $('#id')
          */
         if (context.querySelectorAll) {
           var arr = context.querySelectorAll(selector);
           for (var i = 0; i < arr.length; i++) {
             this.elements.push(arr[i]);
           }
         }
       }
     }
   },
   //实现each
   each: function (callback) {
     if (this.elements.length > 0) {
       for (var i = 0; i < this.elements.length; i++) {
         callback.call(this, this.elements[i], i);
       }
     }
   },
   //实现ready
   ready: function (callback) {
     var isDocument = (ele) =>
       Object.prototype.toString.call(ele) == "[object HTMLDocument]" ||
       "[object Document]";
     //如果已经取得了节点
     if (isDocument(this.elements[0])) {
       if (document.addEventListener) {
         //判断火狐、谷歌
         /**
          * DOM树构建完成的时候就会执行DOMContentLoaded
          * 页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,才会触发window.onload
          * 这也就是$(document).ready() 比 window.onload 执行早的原因
          *
          * arguments.callee 博客里面有一篇文章 js-递归里面专门讲到了,这里不再解释了
          */
         document.addEventListener(
           "DOMContentLoaded",
           function () {
             document.removeEventListener(
               "DOMContentLoaded",
               arguments.callee,
               false
             );
             callback();
           },
           false
         );
       } else if (document.attachEvent) {
         //判断IE
         document.attachEvent("onreadystatechange", function () {
           if (document.readyState == "complete") {
             document.detachEvent("onreadystatechange", arguments.callee);
             callback();
           }
         });
       } else if (document.lastChild == document.body) {
         //body已经加载完了,就直接回调了
         callback();
       }
     }
   },
   //实现bind
   bind: function (type, callback) {
     if (document.addEventListener) {
       //判断火狐、谷歌
       this.each(function (item, i) {
         item.addEventListener(type, callback, false);
       });
     } else if (document.attachEvent) {
       //判断IE
       this.each(function (item, i) {
         item.attachEvent("on" + type, callback);
       });
     } else {
       this.each(function (item, i) {
         //其他浏览器 egg: item.onclick = function(){}
         item["on" + type] = callback;
       });
     }
   },
 };
 /**
  * 让两个作用于不一样的对象共享一个方法,让他们的原型指向一直,即Init.prototype = _$.prototype
  * 那么指向之后 就可以共享this.elements 属性了。
  */
 _$.prototype.Init.prototype = _$.prototype;

 var isObj = (o) => Object.prototype.toString().call(o) === "[object Object]";
 $.fn.extend = function (obj) {
   if (isObj(obj)) {
     for (var i in obj) {
       this[i] = obj; //注意这里的this指向是 $.prototype
     }
   }
   //....这里是简写
 };

 _$.extend = function (obj) {
   if (isObj(obj)) {
     for (var i in obj) {
       this[i] = obj[i]; //注意这里的this指向是 $
     }
   }
   //....这里是简写
 };

 window.$ = _$;
})(window || global);

以上就是你值得了解的JavaScript“继承之jquery”使用方法(代码详解)的详细内容,更多请关注php爱好者其它相关文章!

相关阅读更多 +
最近更新
排行榜 更多 +
元梦之星最新版手游

元梦之星最新版手游

棋牌卡牌 下载
我自为道安卓版

我自为道安卓版

角色扮演 下载
一剑斩仙

一剑斩仙

角色扮演 下载