首頁 > web前端 > js教程 > 主體

你值得了解的JavaScript「繼承之jquery」使用方法(程式碼詳解)

奋力向前
發布: 2021-08-19 11:53:03
轉載
2189 人瀏覽過

之前的文章《深入解析JS中數組reduce方法(附程式碼)》中,給大家了解JS中數組reduce方法。以下這篇文章給大家了解JS-繼承之jquery使用方法,小夥伴可以參考一下。

你值得了解的JavaScript「繼承之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;

你值得了解的JavaScript「繼承之jquery」使用方法(程式碼詳解)

事件處理使用了事件代理程式;

使用

DOM標準化寫了polyfill;

使用了自訂元素。


假如不用,學習下還是可以的

本文粗燥的實作jquery
ready、each、bind、``$.fn.extend、$.extend

#初始化

$

##<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">(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 === &quot;function&quot;) { this.elements.push(document); this.ready(selector); } else { var context = context || document; var isDocument = (ele) =&gt; Object.prototype.toString.call(ele) == &quot;[object HTMLDocument]&quot; || &quot;[object Document]&quot;; if (isDocument(selector)) { this.elements.push(selector); } else { /** * 如果是字符串的话就查询该节点 $(&amp;#39;.class&amp;#39;) | $(&amp;#39;#id&amp;#39;) */ if (context.querySelectorAll) { var arr = context.querySelectorAll(selector); for (var i = 0; i &lt; 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);</pre><div class="contentsignin">登入後複製</div></div>ready

//实现ready
ready: function (callback) {
  var isDocument = (ele) => Object.prototype.toString.call(ele) == &#39;[object HTMLDocument]&#39; || &#39;[object Document]&#39;
  //如果已经取得了节点
  if (isDocument(this.elements[0])) {
    if (document.addEventListener) { //判断火狐、谷歌
      /**
       * DOM树构建完成的时候就会执行DOMContentLoaded
       * 页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,才会触发window.onload
       * 这也就是$(document).ready() 比 window.onload 执行早的原因
       *
       * arguments.callee 博客里面有一篇文章 [js-递归] 里面专门讲到了,这里不再解释了
       */
      document.addEventListener(&#39;DOMContentLoaded&#39;, function () {
        document.removeEventListener(&#39;DOMContentLoaded&#39;, arguments.callee, false)
        callback()
      }, false)
    } else if (document.attachEvent) { //判断IE
      document.attachEvent(&#39;onreadystatechange&#39;, function () {
        if (document.readyState == &#39;complete&#39;) {
          document.detachEvent(&#39;onreadystatechange&#39;, 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(&#39;on&#39; + type, callback)
    })
    } else {
    this.each(function (item, i) { //其他浏览器 egg: item.onclick = function(){}
        item[&#39;on&#39; + 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.(把物件掛載到jQuery

prototype屬性,來擴充一個新的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) === &#39;[object Object]&#39;;
  $.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) === &#39;[object Object]&#39;;
...
_$.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>
    <div id="test"></div>
  </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: &#39;http&#39;,host: &#39;chuchur.com&#39;, hash: { a: 1, b: 1,c:2 } }

var result = $.extend(false, {}, a, b);
console.log(result); //{ protocol: &#39;http&#39;,host: &#39;chuchur.com&#39;, 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 {
          /**
           * 如果是字符串的话就查询该节点 $(&#39;.class&#39;) | $(&#39;#id&#39;)
           */
          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);
登入後複製
###【完】######推薦學習:###jQuery影片教學#######

以上是你值得了解的JavaScript「繼承之jquery」使用方法(程式碼詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:chuchur.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板