純粋なJavaScriptでの基本的なjQuery関数の実装と代替

私がWebプログラミングを学び始めたとき、私は最高のフレームワークであるJQueryに出会いました。 JavaScriptが95で行ったことを1行で実行できるため、これまでは通常のプログラミングを想像することは不可能でした。



今日、JavaScriptは大きく変わりました。 多くの機能が追加され、コードの量が減り、プログラミングがより便利になりました。 しかし、これらの更新を行っても、彼はJQueryから最も単純な関数を再現することはできず、このフレームワークを放棄することに決めたとき、彼はこのために多少の困難を感じます。



そのため、この記事では、純粋なJavaScriptでのjQueryの一部の関数の実装について説明します。





  1. $(ドキュメント).ready(関数); または$(関数);



    知らない人のために、これはDOMツリー準備機能です。 すなわち この関数は、ページのDOMが完全にロードされると起動します。



    IE9以降では、この関数はDOMContentLoaded



    でハングしたDOMContentLoaded



    イベントを使用して置き換えることができdocument







    例:

     document.addEventListener('DOMContentLoaded', function() { //   }, false);
          
          





    IE4 +以降のサポートが必要な場合は、古いメソッドを使用できます。 document



    でハングアップしたreadystatechange



    イベントを使用して、 readyState



    を確認します。



    例:

     document.onreadystatechange = function(){ if(document.readyState === 'complete'){ //   } };
          
          





    jQueryソースを見ると、次の関数が表示されます。



    例:

     var ready = (function() { var readyList, DOMContentLoaded, class2type = {}; class2type["[object Boolean]"] = "boolean"; class2type["[object Number]"] = "number"; class2type["[object String]"] = "string"; class2type["[object Function]"] = "function"; class2type["[object Array]"] = "array"; class2type["[object Date]"] = "date"; class2type["[object RegExp]"] = "regexp"; class2type["[object Object]"] = "object"; var ReadyObj = { //   DOM   ?   true,    . isReady: false, // ,    ,    . . #6781 readyWait: 1, //  ( )   holdReady: function(hold) { if (hold) { ReadyObj.readyWait++; } else { ReadyObj.ready(true); } }, // ,  DOM  ready: function(wait) { //    ,   DOMready/load     if ((wait === true && !--ReadyObj.readyWait) || (wait !== true && !ReadyObj.isReady)) { // ,   ,   ,  ,  IE  (ticket #5443). if (!document.body) { return setTimeout(ReadyObj.ready, 1); } //   DOM  ReadyObj.isReady = true; //    DOM Ready ,   ,  , if (wait !== true && --ReadyObj.readyWait > 0) { return; } //   ,  readyList.resolveWith(document, [ReadyObj]); //     //if ( ReadyObj.fn.trigger ) { // ReadyObj( document ).trigger( "ready" ).unbind( "ready" ); //} } }, bindReady: function() { if (readyList) { return; } readyList = ReadyObj._Deferred(); //  ,  $(document).ready()   //  ,   . if (document.readyState === "complete") { //    ,       return setTimeout(ReadyObj.ready, 1); } // Mozilla, Opera  webkit nightlies       if (document.addEventListener) { //   callback  document.addEventListener("DOMContentLoaded", DOMContentLoaded, false); //   window.onload,     window.addEventListener("load", ReadyObj.ready, false); //     IE } else if (document.attachEvent) { //    , // , ,     iframes document.attachEvent("onreadystatechange", DOMContentLoaded); //   window.onload,     window.attachEvent("onload", ReadyObj.ready); //  IE,   frame //  ,    var toplevel = false; try { toplevel = window.frameElement == null; } catch (e) {} if (document.documentElement.doScroll && toplevel) { doScrollCheck(); } } }, _Deferred: function() { var //  callback callbacks = [], // stored [ context , args ] fired, //   ,     firing, //  ,    cancelled, //  deferred = { // done( f1, f2, ...) done: function() { if (!cancelled) { var args = arguments, i, length, elem, type, _fired; if (fired) { _fired = fired; fired = 0; } for (i = 0, length = args.length; i < length; i++) { elem = args[i]; type = ReadyObj.type(elem); if (type === "array") { deferred.done.apply(deferred, elem); } else if (type === "function") { callbacks.push(elem); } } if (_fired) { deferred.resolveWith(_fired[0], _fired[1]); } } return this; }, //       resolveWith: function(context, args) { if (!cancelled && !fired && !firing) { // ,    (#8421) args = args || []; firing = 1; try { while (callbacks[0]) { callbacks.shift().apply(context, args); //shifts a callback, and applies it to document } } finally { fired = [context, args]; firing = 0; } } return this; }, //          resolve: function() { deferred.resolveWith(this, arguments); return this; }, //    ? isResolved: function() { return !!(firing || fired); }, //  cancel: function() { cancelled = 1; callbacks = []; return this; } }; return deferred; }, type: function(obj) { return obj == null ? String(obj) : class2type[Object.prototype.toString.call(obj)] || "object"; } } //   DOM  Internet Explorer function doScrollCheck() { if (ReadyObj.isReady) { return; } try { //   IE,      // http://javascript.nwbox.com/IEContentLoaded/ document.documentElement.doScroll("left"); } catch (e) { setTimeout(doScrollCheck, 1); return; } //     ReadyObj.ready(); } //    document ready if (document.addEventListener) { DOMContentLoaded = function() { document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false); ReadyObj.ready(); }; } else if (document.attachEvent) { DOMContentLoaded = function() { // ,   ,   ,  ,  IE  (ticket #5443). if (document.readyState === "complete") { document.detachEvent("onreadystatechange", DOMContentLoaded); ReadyObj.ready(); } }; } function ready(fn) { //   ReadyObj.bindReady(); var type = ReadyObj.type(fn); //  callback' readyList.done(fn); // ReadyList   _Deferred() } return ready; })();
          
          





    関数の起動は次のとおりです。



     ready(function() { //   });
          
          





  2. $ .ajax(オブジェクト);



    知らない人のために、この関数は非同期HTTP(Ajax)リクエストを実行します。



    ありふれたことですが、Jquery.ajax()の代替はXMLHttpRequest







    使用について少し:



    まず、送信用のクロスブラウザ関数を作成する必要があります。 ブラウザによっては、送信機能が異なる場合があります。 この方法で作成されます:



     function getXmlHttp(){ var xmlhttp; try { xmlhttp = new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) { try { xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); } catch (E) { xmlhttp = false; } } if (!xmlhttp && typeof XMLHttpRequest !== 'undefined') { xmlhttp = new XMLHttpRequest(); } return xmlhttp; }
          
          





    そして、これはエラー処理を伴う標準的なPOSTリクエストの例です:



     var xmlhttp = getXmlHttp(); //    xmlhttp.open('POST', '/someurl', true); //  POST    "/someurl" //       xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState !== 4) return; //    ,     //   : //  0 —  XMLHttpRequest  ,   open()   . //  1 —    open().     setRequestHeader()      (request headers),  ,    ,     send() . //  2 —    send()     (response headers) . //  3 —   .  responseType       "text", responseText      . //  4 —    .     ,      ,   ,   . clearTimeout(timeout); //  Timeout,    if (xmlhttp.status == 200) { //         ,    console.log(xmlhttp.responseText); } else { //     ,      handleError(xmlhttp.statusText); } } //  ,     xmlhttp.send("a=5&b=4"); //    10 .    , ,      ,   var timeout = setTimeout( function(){ xmlhttp.abort(); handleError('Time over') }, 10000); //     function handleError(message) { //           console.log(': ' + message); }
          
          





    jQuery AJAX関数は、同じテクノロジーを使用して作成されます。

  3. グローバル関数$(...);



    誰も知らない場合、この関数はグローバルjQueryオブジェクトを作成します。



    ここでは、少なくとも1週間はかかるため、この関数のすべての機能を説明するのではなく、JQueryの例に従って同様のことをどのように作成するかを単純に記述します。



    最初に、引数(セレクターとコンテキスト)を含むLibrary



    などの通常の関数を作成します。



     var Library = function (selector, context) {};
          
          





    次に、一般的な関数を書きます。 jQueryでは、関数に分類される値は条件を使用してソートされ、結果が表示されます



     var init = function (selector, context) { //     , //      var array = []; /**    , *     *  HTML     */ if (typeof selector === 'string' ) { /**    HTML  *      . *    JQuery  *   : * /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/ */ if (/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/.exec(selector)) { //     var DOM = new DOMParser().parseFromString(selector, 'text/html'); var DOMList = DOM.body.childNodes; //      context      if (!context || {}.toString.call(context) !== '[object Object]') { context = null; }; //       for (var i = 0; i < DOMList.length; i++) { if (context) { for (var attr in context) { DOMList[i].setAttribute(attr, context + ''); }; }; array[array.length] = DOMList[i]; }; return array; } else { //    //    // context , //     //  var DOMList = {}.toString.call(context) === '[object HTMLElement]' ? context.querySelectorAll(selector) : document.querySelectorAll(selector); //       //   for (var i = 0; i < DOMList.length; i++) { array[array.length] = DOMList[i]; }; return array; }; //   ,      } else if ({}.toString.call(selector) === '[object Array]') { //     for (var i = 0; i < selector.length; i++) { array[array.length] = selector[i]; }; return array; //   ,       } else if ({}.toString.call(selector) === '[object Object]' || {}.toString.call(selector) === '[object HTMLElement]') { //       array[0] = selector; return array; //  ,     ? } else if ({}.toString.call(selector) === '[object HTMLCollection]' || {}.toString.call(selector) === '[object NodeList]') { //     for (var i = 0; i < selector.length; i++) { array[array.length] = selector[i]; }; return array; //    ,     } else { return array; } };
          
          





    これで、メインからこの関数の起動を追加できます



     var Library = function (selector, context) { //      var array = new init(selector, context); /**    . *   proto  *   , *     *   *  */ var object = { __proto__: Library.prototype }; //     //       //  length,    //  ,   //   for (var i = 0; i < array.length; i++) { object[i] = array[i]; }; object.length = array.length; return object; };
          
          





    できました。 これで、 Library(...);



    関数を介して要素の配列を取得できますLibrary(...);



    そして、そのような構築を通して追加の機能を作成しますLibrary.prototype.myFunction = function () {...};







今のところすべてです。 時間が経つにつれて、jQuery関数に関する記事をより具体的に公開します。



All Articles