Modul_javascript reka bentuk rangka kerja JavaScript kemahiran benih

WBOY
Lepaskan: 2016-05-16 15:53:33
asal
1064 orang telah melayarinya

Modul benih juga dipanggil modul teras, yang merupakan bahagian pertama rangka kerja yang akan dilaksanakan. Malah perpustakaan fungsi fail tunggal seperti jQuery dibahagikan kepada banyak modul dalaman Sesetengah modul mesti dilaksanakan dengan segera di hadapan apabila dilaksanakan, dan beberapa modul hanya dilaksanakan apabila digunakan. Sesetengah modul boleh diketepikan, mempunyai rasa kewujudan yang lemah, dan hanya boleh dijalankan di bawah pelayar tertentu.

Modul benih adalah salah satu perintis Kaedah di dalamnya tidak semestinya perlu berfungsi sepenuhnya dan direka dengan baik, tetapi ia mestilah sangat berskala, biasa digunakan dan stabil.

Kebolehlanjutan bermakna modul lain boleh disertakan melaluinya; penggunaan biasa bermakna kebanyakan modul boleh menggunakannya untuk mengelakkan pertindihan kerja. Kestabilan bermakna ia tidak mudah digantikan dengan kaedah baharu semasa lelaran versi.

Merujuk kepada pelaksanaan banyak rangka kerja dan perpustakaan, kami percaya modul benih merangkumi fungsi berikut: pengembangan objek, tatasusunan, penentuan jenis, penjilidan dan pemunggahan mudah, pengendalian tanpa konflik, pemuatan modul dan domReady bab ini adalah berdasarkan Modul benih Rangka Kerja jisim ialah templat.

https://github.com/RubyLouvre/mass-Framework

1. Ruang nama

Sebagai bahagian awal rangka kerja, modul benih bertanggungjawab untuk membantu dalam membina infrastruktur global. jQuery mempunyai permulaan yang baik, menggunakan IIFE (ungkapan fungsi yang digunakan serta-merta).

LIFE ialah infrastruktur paling penting dalam rangka kerja JavaScript moden Ia membalut dirinya seperti sel untuk mengelakkan pencemaran berubah-ubah. Sama seperti pijakan, ini adalah ruang nama, seperti prototype.js dan mootools Mereka membuat anda tidak dapat merasakan kewujudan rangka kerja itu menjangkau setiap sudut keseluruhan persekitaran pelaksanaan seperti javascript, DOM, BOM, dll. , dan mempunyai kesan yang mendalam terhadap asli Prototaip objek boleh dilanjutkan. Disebabkan tentangan kuat Douglas (pengarang JSON), rangka kerja baharu dibina di atas ruang nama.

Mari lihat cara mensimulasikan ruang nama dalam JavaScript. JavaScript semuanya berdasarkan objek, tetapi hanya objek yang memenuhi jenis boleh memenuhi keperluan, seperti fungsi, RegExp dan Objek, tetapi yang paling biasa digunakan ialah objek dan fungsi. Kami menambah atribut pada objek, dan atribut ini adalah objek. Dengan cara ini, kami boleh membina rangka kerja kami dengan teratur. Jika pengguna ingin memanggil kaedah, dia boleh memanggilnya dalam bentuk xxx.yyy.zzz().

  if( typeof(Ten) === "undefined" ){
    Ten = {};
    Ten.Function = { /*略*/ }
    Ten.Array = { /*略*/ }
    Ten.Class = { /*略*/ }
    Ten.JSONP = new Ten.Class(/*略*/ )
    Ten.XHR = new Ten.Class(/*略*/ )
  }

Salin selepas log masuk

Melihat pelaksanaan perpustakaan utama, mereka pada asasnya mentakrifkan pembolehubah global sebagai ruang nama pada mulanya, dan kemudian memanjangkannya, seperti Base2's Base, Ext's Ext, jQuery's jQuery, YUI's YUI, dan dojo's dojo, mochKit untuk MochiKit . Dari perspektif tahap pencemaran pembolehubah global, ia dibahagikan kepada dua kategori:

prototype.js dan mootools diklasifikasikan ke dalam kategori yang sama seperti Base2 Falsafah Prototaip adalah untuk memanjangkan objek asli javascript. Pada tahun-tahun awal, prototaip hampir dipanggil standard de facto. Oleh itu, masalah kewujudan bersama dengan perpustakaan lain tidak diambil kira. Prototaip Asas juga telah membangunkan perpustakaan kelas yang sangat baik seperti script.aculo.us, rico, Plotr, protoChart, Script2 dan kategori besar pemalam berbayar. Selain itu, hampir semua pemalam dengan beberapa asal adalah berkaitan dengan Prototaip, seperti lightBox. mootools ialah versi prototype.js yang dipertingkatkan, yang lebih OO dan mereplikasi sepenuhnya APInya. Base2 mahu membetulkan pepijat IE dan membiarkan IE mempunyai API pelayar standard, jadi ia juga mencemarkan semua objek asli.

Kategori kedua ialah rangka kerja jQuery, YUI dan EXT YUI dan Ext dibina oleh objek bersarang dalam objek. jQuery mengambil pendekatan yang berbeza Ia berorientasikan pemilih, jadi ruang namanya adalah fungsi yang memudahkan pengguna untuk menghantar dalam rentetan css expressor. Ia kemudian mencari melalui pemilih dan akhirnya mengembalikan contoh objek jQuery.

jQuery pada mulanya menggunakan $ sebagai ruang namanya seperti Prototaip Oleh itu, ia melaksanakan mekanisme kewujudan bersama banyak perpustakaan Anda boleh bertukar antara $ dan jQuery sesuka hati Prinsip kewujudan berbilang perpustakaan adalah sangat mudah, jadi ia kemudiannya mekanisme kewujudan bersama banyak perpustakaan konfigurasi Standard untuk Xiaoku. Mula-mula, simpan ruang nama ke dalam pembolehubah sementara (perhatikan bahawa objek ini bukan sebahagian daripada rangka kerja anda sendiri pada masa ini, ia mungkin prototype.js atau lain-lain), dan kemudian gunakan noConflict untuk meletakkannya semula.

  //jQuery1.2
  var _jQuery = window.jQury , _$ = window.$; //把可能存在同名变量先保存起来
  jQury.extend({
    noConflict : function(deep) {
      window.$ = _$; //这时再放回去
      if (deep) //补充 if ( deep && window.jQuery === jQuery )
        window.jQury = _jQuery;
      return jQury;
    }
  })

Salin selepas log masuk

Rujukan: http://zhidao.baidu.com/question/1239712776390687219.html

Tetapi noConflict jQuery hanya berguna untuk rangka kerja perpustakaan kelas fail tunggal dan tidak boleh disalin seperti Ext. Oleh itu, selepas menamakan semula ruang nama, tetapkan Ext kepada null, dan kemudian masukkannya ke dalam fail javascript baharu melalui pemuatan dinamik Fail akan dipanggil dengan Ext, yang akan menyebabkan ralat.

2. Sambungan objek

Kami memerlukan mekanisme untuk menambah fungsi baharu pada ruang nama kami. Kaedah ini biasanya dipanggil extend atau mixin dalam JavaScript. Sebelum kelahiran deskriptor harta (Property Descriptor), objek JavaScript boleh menambah, menukar dan memadam ahlinya sesuka hati Oleh itu, memanjangkan objek adalah sangat mudah. Pelaksanaan kaedah sambungan mudah kelihatan seperti ini.

  function extend (destination,source){
    for (var property in source)
      destination[property] = source[property];
    return destination;
  }
Salin selepas log masuk

不过,旧版本IE在这里有个问题,它认为像Object的原型方法就是不应该被遍历出来,因此for in循环是无法遍历valueOf、toString的属性名。这导致,模拟Object.keys方法是现实时也遇到了这个问题。

  Object.keys = Object.keys || function(obj){
    var a = [];
    for(a[a.length] in obj);
    return a;
  }
Salin selepas log masuk

在不同的框架,这个方法还有不同的实现,如Ext分别为apply与applyIf两个方法,前者会覆盖目标对象的同名属性,而后者不会。dojo允许多个对象合并在一起。jQuery还支持深拷贝。下面是mass Farmework的mix方法。支持多对象合并与选择是否覆写。

  function mix(target,source){ //如果最后参数是布尔,判定是否覆盖同名属性
    var args = [].slice.call(arguments), i = 1, key,
      ride = typeof args[args.length - 1] == "boolean" ? args.pop() : true;
    if (args.length === 1){ //处理$.mix(hash)的情形
      target = !this.window ? this : {};
      i = 0;
    }  
    while ((source = args[i++])) {
      for (key in source){ //允许对象糅杂,用户保证都是对象
        if (ride || !(key in target)) {
          target[key] = source[key];
        }
      }
    }
    return target;
  }

Salin selepas log masuk

3.数组化

浏览器下存在很多类数组对象,如function内的arguments,通过document.forms、form.elements,document.links、select.options、document.getElementsByName,document.getElementsByTagName、childNodes、children等方式获取的节点的结合(HTMLCollection 、NodeList)或按照某些特殊的写法自定义对象。

类数组对象是一个很好的存储结构。不过功能太弱了,为了能使用纯数组的那些便捷的方法,我们会在处理它们前都会做一下转换。

通常来说,使用[].slice.call就能转换了 ,不过功能不够用,但在旧版本的HTMLCollection、NodeList不是Object的子类,采用如上的方法会导致IE执行异常。我们看一下

jQuery:makeArray

  var makeArray = function(array) {
    var ret = [] ;
    if(array != null){
      var i = array.length;
      if(i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval)
        ret[0] = array;
      else
        while (i)
          ret(--i) = array[i];
    }
    return ret;
  }

Salin selepas log masuk

mass的实现,一开始就进行区分,直接[].slice.call,IE的话自己动手实现一个slice方法

  $.slice = window.dispatchEvent ? function(nodes,start,end){
    return [].slice.call(nodes,start,end);
  } : function (nodes,start,end){
    var ret = [],
       n = nodes.length;
    if (end === void 0 || typeof end === "number" && isFinite(end)){
      start = parseInt (start,0) || 0;
      end = end == void 0 ? n:parseInt (end,10);
      if(start < 0){
        start += n;
      }
      if (end > n) {
        end =n
      };
      if (end < 0) {
        end += n
      };
      for (var i = start; i < end; ++i){
        ret[i-start] = nodes[i];
      }
    }
    return ret;
  }

Salin selepas log masuk

4.类型的判定

javascript存在两套类型系统,一套是基本的数据类型,另一套是对象类型系统。基本数据类型包括6中 。分别是undefined、string、null、boolean、function、object。基本数据类型是通过typeof来检测的。对象类型系统是以基础类型系统为基础的,通过instanceof来检测的。然而,javascript自带的这两套识别机制非常不靠谱,于是就催生了isXXX系列。就拿typeof来说,它只能粗略识别出string、number、boolearn、function、undefined、object这6种数据类型,无法识别null,RegExpArgument等细分的对象类型。

  typeof null // => "object"
  typeof document.childNodes //=> safari: "function"
  typeof document.creatElement('embed') //=> ff3-10 "function"
  typeof document.creatElement('object') //=> ff3-10 "function"
  typeof document.creatElement('object') //=> ff3-10 "function"
  typeof /\d/i //在实现了ecma262v4的浏览器返回"function"
  typeof window.alert //ie678 "object"
  var iframe = document.creatElement("iframe")
  document.body.appendChild(iframe)
  xArray = window.frames[window.frames.length - 1].Array;
  var arr = new xArray(1,2,3) //=>[1,2,3]
  arr instanceof Array ;// false
  isNaN("aaa") //=> true

Salin selepas log masuk

另外,以前人们总是以document.all来判断是否为ie,这其实是很危险的,因为,用document.all来取得页面中所有的元素是不错的注意,这个方法FF,chrome打算使用很久了,不过人们都这样判断,就是在chrome下有这样的闹剧。

  typeof document.all //undefined
  document.all //HTMLAllCollection [728] (728为元素总数)
Salin selepas log masuk

在判定undefined、null、string、number、boolean、function这六个还算简单,前面两个可以分别与void(0)、null比较,后面4个的typeof也可以满足90%的情形。这样说是因为string、number、boolean可以包装成伪对象。

  typeof new Boolean(1); //=>"object"
  typeof new Number(1); //=>"object"
  typeof new String("aa"); //=> "object"
Salin selepas log masuk

这些还不是最难的,难点在于RegExp与Array.判定RegExp的情况很少。Array则不一样。有关isArray的实现不下二十种。都是因为鸭式辨型被打破了。直到prototype.js把Object.prototype.toString发掘出来。此方法是直接输出内部的[[Class]],绝对精准。有了它,95%的陷阱被跳过了。

  function isArray(arr){
    return arr instanceof Array;
  }

  function isArray(arr){
    return !!arr && arr.constructor === Array;
  }

  function isArray(arr) { //prototype.js 1.6
    return arr != null && typeof arr === "object" && 'splice' in arr && 'join' in arr;
  }

  function isArray(arr){// Douglas Crockford(JSON作者,反对原型污染)
    return typeof arr.sort == "function"
  }

  function isArray(array){ //kriszyp
    var result = false;
    try{
      new array.constructor (Math.pow(2,32))
    } catch (e){
      result = /Array/.test(e.message)
    }
    return result;
  };

  function isArray(o){//kangax
    try{
      Array.prototype.toString.call(o);
      return true;
    } catch (e) {
    }
    return false;
  }

  function isArray(o){ //kangax
    if(o && typeof o == 'object' && typeof o.length == 'number' && isFinite(o.length))
    {
      var _origLength = o.length;
      o[o.length] = '__test__';
      var _newLength = o.length;
      o.length = _origLength;
      return _newLength == _origLength + 1;
    }
    return false
  }

Salin selepas log masuk

至于null 、 undefined 、NaN直接这样写

  function isNaN(obj) {
    return obj !== obj
  }

  function isNull(obj) {
    return obj === null;
  }

  function isUndefined(obj){
    return obj === void 0;
  }

Salin selepas log masuk

最后要判定的是对象是window,由于ECMA是不规范的Host对象,window对象属于host.所以也就没有被约定。就算Object.prototype.toString也对它没办法

  [object Object] IE6 
  [object Object] IE7 
  [object Object] IE8
  [object Window] IE9
  [object Window] ff3.6
  [object Window] opera10
  [object DOMWindow] safari 4.04
  [object global] chrome5.0

Salin selepas log masuk

不过根据window.window和window.setInterval去判定更加不靠谱,用一个技巧就可以完美识别ie6 ie7 ie8的window对象,其它还用toString,这个神奇的hack就是,window与document互相比较,如果顺序不一样,结果也是不一样的!

剩下的就是一些经典方法:

在prototype.js中,拥有isElement,isArray,isHash,isFunctoion,isString,isNumber,isDate,isUndefined。

mootools有一个typeOf判定基本类型,instanceOf判定自定义“类”

RightJS 有isFunction , isHash , isString , isNumber , isArray ,isElement, isNode.

Ext有比较全面的判断,isEmpty,isArray,isDate,isObject,isSimpleObject,isPrimitive,isFunction,isNumber,isMumeric,isString,isBoolean,isElement,isTextNode,isDefined,isIterable,应有尽有。最后,还有typeOf判断基本类型。

Underscore.js有isElement,isEmpty,isArray,isArgument,isObject,isFunction,isString,isNumber,isFinite,isNaN,isBoolean,isDate,isRegExp,isNull,isUndefined.

jQuery就不与其它框架一样了,在jQuery1.4中只有isFunction,isArray,isPlainObject,isEmptyObject。isFunction,isArray用户肯定用的较多,isPlainObject是用来判断是否是纯净的js对象。既不是DOM,BOM对象,也不是自定义的“类”的实例对象,制造它的目的最初是为了深拷贝,避开像window那样自己引用自己的对象。isEmptyObject是用于数据缓存的系统,当此对象为空时,就可以删除它。

  //jQuery2.0纯净数组的判定思路
  jQuery.isPlainObject = function(obj){
    //首先排除基础类型不为Object的类型,然后是DOM节点与window对象
    if(jQuery.type(obj) !== "object" || object.nodeType || jQuery.isWindow(obj)){
      return false;
    }

    //然后回溯它的最近的原型对象是否有isPrototypeOf.
    //旧版本的IE一些原生的对象没有暴露constructor、prototype。因此在这里过滤掉
    try{
      if (obj.constructor && !hasOwn.call(obj.constructor.prototype,"isPrototypeOf")){
        return false;
      }
    } case(e) {
      return false;
    }
    return true;
  }

Salin selepas log masuk

avalon.mobile中有一个更精简的版本,只支持最新的浏览器,可以大胆的使用ecma262v5新API

  avalon.isPlainObject = function(obj){
    return obj && typeof obj === "object" && Object.getPrototypeOf(obj) === Object.prototype
  }
Salin selepas log masuk

isArrayLike也是一个常用的方法,但是判定一个类数组太难了,唯一的识别方法就是判断有一个大于0或等于0的length属性,此外,还有一些共识,如window与函数和元素节点,如(form元素),不算类数组,虽然它们都满足前面的条件。因此,至今jQuery都没有把它暴露出来。

  //jQuery2.0
  function isArrayLike(obj){
    var length = obj.length , type = jQuery.type(obj);
    if (jQuery.isWindow(obj)){
      return false;
    }
    if (obj.nodeType === 1 && length){
      return true
    }
    return type === "array" || type !== "function" && (length === 0 || typeof length === "number" && length > 0 && (length -1) in obj);
  }

  // avalonjs
  function isArrayLike (obj) {
    if (obj && typeof obj === "object"){
      var n = obj.length
      if (+n === n && !( n % 1) && n >= 0){//检测length是否为非负整数
        try{
          if ({}.prototypeIsEnumerable.call(obj,'length') === false){
          return Array.isArray(obj) || /^\s&#63;function/.test(obj.item || obj.callee)
         }
        return true;
       } catch (e) { //IE的NodeList直接报错
        return true;
       }
      }
    }
  return false
  }

Salin selepas log masuk

在Prototype.js1.3版本中的研究成果(Object.prototype.toString.call)就应用于jQuery,在jQuery1.2中,判断一个变量是否为函数非常复杂。

复制代码 代码如下:

isFunction : function(fn){
return !!fn && typeof fn != "string" && !fn.nodeName && fn.constructor != Array && /^[\s[]?function/.test(fn + "");
}

jQuery1.43中引入isWindow来处理makeArray中对window的判定,引入isNaN用于确保样式赋值的安全。同时引入type代替typeof关键字,用于获取基本数据的基本类型。

  class2type = {};
  jQuery.each("Boolean Number String Function Array Date RegExpObject".split(" "),function( i , name ){
    class2type[ "[object " + name + "]" ] = name.toLowerCase();
  });

  jQuery.type = function(obj){
    return obj == null &#63; String(obj) : class2type[toString.call(obj)] || "object";
  }

Salin selepas log masuk

jQuery1.7中添加isNumeric代替isNaN。这是个不同于其它框架的isNumber,它可以是个字符串,只要外观上像数字就可以了。但jQuery1.7还做了一个违背之前提到稳定性的事情。冒然去掉jQuery.isNaN,因此,基于旧版jQuery的有大批插件失效。

  //jQuery.1.43-1.64
  jQuery.isNaN = function ( obj ) {
    return obj == null || !rdigit.test( obj ) || isNaN( obj );
  }

  //jQuery1.7就是isNaN的去反版
  jQuery.isNumeric = function ( obj ) {
    return obj != null && rdigit.test( obj ) && !isNaN( obj );
  }

  //jQuery.1.71 - 1.72
  jQuery.isNumeric = function ( obj ) {
    return !isNaN( parseFloat(obj) ) && isFinite( obj );
  }

  //jQuery2.1
  jQuery.isMumeric = function( obj ) {
    return obj - parseFloat(obj) >= 0;
  }

Salin selepas log masuk

massFarmeWork的思路与jQuery一致,尽量减少isXXX系列的代码,把is Window,isNaN,nodeName等方法做了整合。代码较长,既可以获取类型,也可以传入第二参数进行类型比较。

  var class2type = {
    "[objectHTMLDocument]" : "Document",
    "[objectHTMLCollection]" : "NodeList",
    "[objectStaticNodeList]" : "NodeList",
    "[objectIXMLDOMNodeList]" : "NodeList",
    "[objectDOMWindow]" : "window",
    "[object global]" : "window",
    "Null" : "Null",
    "undefined" : "undefined"
  },
  toString = class2type.toString;
  "Boolean,Number,String,Function,Array,Date,RegExp,Window,Document,Arguments,NodeList".replace($.rword,function( name ) {
    class2type[ "[object" + name + "]" ] = name;
  });

  //class2type这个映射几乎把常用的判定对象一网打尽
  mass.type = function( obj , str ){
    var result = class2type[ (obj == null || obj !== obj) &#63; obj : toString.call(obj) ] || obj.nodeName || "#";
    if(result.charAt(0) === "#") { //兼容旧版浏览器的个别情况,如window.opera
      //利用IE678 window === document为true,document === window为false
      if( obj == obj.document && obj.document != obj ) {
        result = "window"; //返回构造器名称
      } else if ( obj.nodeType === 9 ) {
        result = "Document";
      } else if ( obj.callee) {
        result = "Arguments";
      } else if ( isFinite(obj.length) && obj.item ) {
        result = "NodeList" //处理节点集合
      } else {
        result = toString.call(obj).slice(8,-1);
      }
    }
    if(str){
      result str === result;
    }
    return result;
  }

Salin selepas log masuk

然后type方法就十分轻松了,用toSring.call(obj)得出值的左键,直接从映射中取得。IE678,我们才费一些周折处理window,document,argument,nodeList等对象。

百度的七巧板基于实用主义,判定也十分严谨。与EXT一样,能想到的写上,并且判定十分严谨。

目前版本2.0.2.5 http://tangram.baidu.com/api#baidu.type()

  baidu.isDate = function( unknow ) {
  return baidu.type(unknow) == "date" && unknow.toString() != 'Invalid Date' && !isNaN(unknow);
  };
  baidu.isNumber = function( unknow ) {
  return baidu.type(unknow) == "number" && isFinite( unknow );
  };
Salin selepas log masuk

5.主流框架的引入机制-domReady

domReady其实是一种名为"DOMContentLoaded"事件的别称,不过由于框架的需要,它与真正的DOMContentLoaded有一点区别,在很多新手和旧的书中,很多人将其写在window.onload回调中,防止dom树还没有建完就开始对节点操作。而对于框架来说,越早越介入dom就越好,如要进行特征侦测之类的。domready还可以满足用户提前绑定事件需求,因为有时页面图片过多等,window.onload事件迟迟不能触发,这时用户操作都没有效果,因此,主流的框架都引入了domReady机制,并且费了很大周折才兼容所有浏览器。具体的策略如下:

对于支持DOMContentLoaded事件使用DOMcontentLoaded事件
旧版本IE使用Diego perini发现的著名Hack

  //by Diego Perini 2007.10.5
   function IEContentLoaded (w, fn) {
   var d = w.document, done = false,
   // 只执行一次用户的回调函数init()
   init = function () {
    if (!done) {
      done = true;
      fn();
    }
   };
  (function () {
    try {
      // DOM树未创建完之前调用doScroll会抛出错误
      d.documentElement.doScroll('left');
    } catch (e) {
      //延迟再试一次~
      setTimeout(arguments.callee, 50);
      return;
    }
    // 没有错误就表示DOM树创建完毕,然后立马执行用户回调
    init();
         })();
  //监听document的加载状态
  d.onreadystatechange = function() {
    // 如果用户是在domReady之后绑定的函数,就立马执行
    if (d.readyState == 'complete') {
      d.onreadystatechange = null;
      init();
    }
       };
  }

Salin selepas log masuk

此外,IE还可以通过script defer hack进行判定

   document.write("<script id=__ie_onload defer src=//0 mce_src=http://0></scr"+"ipt>"); 
    script = document.getElementById("__ie_onload"); 
    script.onreadystatechange = function() { //IE即使是死链也能触发事件 
          if (this.readyState == "complete") 
    init(); // 指定了defer的script在dom树建完才触发
  }; 
Salin selepas log masuk

不过还有个问题,如果我们的种子模块是动态加载的,在它插入dom树时,DOM树是否已经建完呢?这该怎么触发ready回调?jQuery的方案是,连onload也监听了 ,但如果连onload也没赶上,就判定document.readyState等于complete。(完美)可惜ff3.6之前没有这属性,看mass的方案

  var readyList = [];
  mess.ready = function( fn ) {
    if ( readyList ) {
      fn.push( fn );
    } else {
      fn();
    }
  }
  var readyFn ,ready = W3C &#63; "DOMContentLoaded" : "readyStatechange";
  function fireReady() {
    for (var i = 0 , fn; fn = readyList[i++]) {
      fn();
    }
    readyList = null;
    fireReady = $.noop; //惰性函数,防止IE9调用_checkDeps
  }
  function doScrollCheck() {
    try { //IE下通过doScrollCheck检测DOM树是否建设完
      html.doScroll("left");
      fireReady();
    } catch (e){
      setTimeout(doScrollCheck);
    }
  }

  //FF3.6前,没有readyState属性
  if (!document.readyState){
    var readyState = document.readyState = document.body &#63; "complete" : "loading";
    if (document.readyState === "complete") {
      fireReady(); //如果在domReay之外加载
    } else {
      $.bind(document,ready,readyFn = function(){
        if(W3C || document.readyState === "complete") {
          fireReady();
          if(readyState){ //IE下不能该项document.readyState
            document.readyState = "complete";
          }
        }
      });
      if (html.doScroll){
        try {//如果跨域就报错,证明有两个窗口
          if (self.eval === parent.eval) {
            doScrollCheck();
          }
        } catch (e) {
          doScrollCheck();
        }
      }
    }

  }

Salin selepas log masuk

6.无冲突处理

无冲突处理也叫多库共存,$是这个重要的函数名,以至于大家都爱拿它来做自己的命名空间,当jQuery开始发展时,Prototype是主流,jQuery发明了noConflict函数

  var window = this,
  undefined,
  _jQuery = window.jQuery,
  _$ = window.$,
  //将window存入闭包中的同名变量,方便内部函数调用windows不用太麻烦查找它。
  //_jQuery与_$用于以后重写
  jQuery = window.jQuery = window.$ = function(selector, context){
    //用于返回一个jQuery对象
    return new jQuery.fn.init(selector,context);
  }

  jQuery.extend({
    noConflict : function(deep) {
      //引入jQuery类库后,闭包外边的window.$与window.jQuery都储存着一个函数
      //它是用来生成jQuery对象或在domReady后执行里面的函数
      //回顾最上面的代码,在还没有把function赋值给它们时,_jQuery和_$已经被赋值了,因此,它们两的值必然是undefined
      //因此,这种放弃控制权的技术很简单,就是用undefined把window.$里边jQuery函数清除掉。
      //这时,prototype或mootools的$就被拿走了
      window.$ = _$; //相当于window.$ = undefined,如果你有一个叫jQuery的库,也能大方的过渡出去。
      //这时,需要给noConflict添加一个布尔值,true
    
    if (deep)
      //但我们必须使用一个东西接纳jQuery与jQuey的入口函数
      //闭包里边的东西除非被window等宿主引用,否则是不可见的
      //因此,我们把闭包里的jQuery return出去,外面用一个变量接纳就可以
      window.jQuery = _jQuery; //相当window.jQuery = undefined
    return jQuery;
    }
  })

Salin selepas log masuk

使用时,先引入别人的库,然后引入jQuery,使用调用$.noConflict()进行改名,这样就不影响别人的$运行了。

mass的操作方式是在script标签上定义一个nick属性,那么释放出来的命名空间就是你的那个属性值。里面实现了类似jQuery的机制。

<script nike="aaa" src="mass.js"></script>
<script>
  aaa.log("xxxxxx")
</script>
Salin selepas log masuk

以上所述就是本文的全部内容了,希望大家能够喜欢。

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan