<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【你的jQuery?是你的jQuery】(三)——jQuery的選擇器

      目的:

       

      了解jQuery實例對象的組成方式,并打造出形如 $(".class tag #id") 這種路徑組合似的查找

       

      解析:

      上代碼之前,先介紹一下$(oo)或者$(xx)什么的,其實就是一個含有l(wèi)ength屬性的類數(shù)組,其中包含的是符合規(guī)則的DOM元素,通過$(oo)[0]、$(oo)[1]、$(oo)[2]……這種形式,但又不是數(shù)組,因為沒有Array的原型方法(push,slice等)。

      所以我們

       

      1   var jQuery = window.jQuery = window.$ = function (selector, context) {
      2         return new jQuery.fn.init(selector, context);
      3   }

      new出來的是一個類數(shù)組,也就是實例對象的組成方式。在調(diào)用.css()、.attr()等方法時候,也就是遍歷這個類數(shù)組,然后分別操作。

      所以在介紹選擇器前我們先了解兩個靜態(tài)方法:

      一、$.each( )

      jQuery中有一個靜態(tài)方法是$.each( ),它可以遍歷對象或者數(shù)組進行callback

       1  jQuery.extend({
       2      each: function (object, callback) {
       3             var isObject = Object.prototype.toString.apply(object)=="[object Object]", i = 0, length = object.length;
       4             if (isObject && !length) { //obj
       5                 for (name in object)
       6                     if (callback.call(object[name], name, object[name]) === false)
       7                         break;
       8             }
       9             else {  //array
      10                 for (var value = object[0]; i < length && callback.call(value, i, value) !== false; value = object[++i]) { }
      11             }
      12             return this;
      13         }
      14 
      15 })

      說明:

      此方法參照jQuery源碼,只是給出了遍歷時候,沒有額外參數(shù)的情況。此方法支持形如$.each(obj,callback(key,vlaue){...})和$.each(array,callback(key,vlaue){...})這兩種情況,即遍歷對象和數(shù)組。

      1、采用Object的原型方法toString,此方法可以判斷出任何數(shù)據(jù)類型,包括null、undefined等,建議用此方法,因為typeof有的數(shù)據(jù)類型判斷不準(zhǔn),例如typeof [] 和typeof {}結(jié)果都為“object”

      2、循環(huán)的中斷條件為callback中,你設(shè)置了返回fasle

      3、第二個for寫的實在是浪啊... ,執(zhí)行語句也在了條件語句里。拿出來就能理解了:

      1 for (var value = object[0]; i < length ;i++) {
      2   if(callback.call(value, i, value) === false){
      3       break;
      4   }
      5    value = object[i];
      6  }

      二、$.getElementByClassName( )

      因為IE等老一輩瀏覽器不支持按類查找(不含API:querySelectorAll),屬于兼容處理,自己寫一個

       1 jQuery.extend({
       2     getElementByClassName: function (selector, context) {
       3             var ret = [], context = context || document;
       4             if (document.querySelectorAll) {
       5                 ret = context.querySelectorAll(selector);
       6             }
       7             else {
       8                 var elems = context.getElementsByTagName("*"),
       9                 className = document.all ? "className" : "class",
      10                 selector = selector.replace(".", ""),
      11                 reg = new RegExp("\\b" + selector + "\\b");
      12                 for (var i = 0, len = elems.length; i < len; i++) {
      13                     if (elems[i].nodeType == 1 && reg.test(elems[i].getAttribute(className))) {
      14                         ret.push(elems[i]);
      15                     }
      16                 }
      17             }
      18             return ret;
      19         }
      20 })

      說明:

      此方法,很簡單,是遍歷DOM樹,正則判斷是否其樣式類名為選擇類名,符合要求壓入數(shù)組,最后一并返回。

       

      好,至此,選擇器前的準(zhǔn)備工作就剩一個了,了解Sizzle (jQuery的選擇器引擎) 的思路組成。

      思路:也就是“從右至左”的查找,形如 $(".class1 .class2 .class3"),正常思路是查找 .class1下的所有 .class2,然后再查找 .class3這樣進行了3次DOM查找,而換成“從右至左”也就是查找所有的.class3,然后得到的節(jié)點遍歷其父節(jié)點,符合.class2 的節(jié)點再遍歷判斷是否其父節(jié)點是否符合.class1,這樣只遍歷一遍DOM,遍歷節(jié)點屬性,要比遍歷DOM要節(jié)省的多。

      組成選擇器(select)過濾器(filter),即實現(xiàn)上述思路中的查找和判斷。

      三、原型方法 init

       1 jQuery.fn = jQuery.prototype = {
       2             init: function (selector, context) {
       3                 var elems, _this = this;
       4                 this.contexts = []; //上下文,用于存放符合條件節(jié)點的上下文,為以后若再次查找留個依據(jù),例如$(oo).find(xx),find時候用
       5                 if (Object.prototype.toString.apply(selector)) { //str情況
       6                     selector = selector.replace(/^\s+|\s+$/,"");//出去選擇字符串前后空格
       7                     elems = this.select(selector, context); //返回符合要求的節(jié)點
       8                     if (elems[0]) {  //如果此類型節(jié)點存在的話
       9                         jQuery.each(elems, function (k, v) {//遍歷構(gòu)造出this[0],this[1]...這種類數(shù)組
      10                             _this.contexts[k] = v;
      11                             _this[k] = v;
      12                         })
      13                         this.length = elems.length;
      14                         this.selector = selector;
      15                         return this;
      16                     }
      17                 }
      18             }

      說明:

      此篇僅考慮傳入正確字符串的情況,其中還有傳入節(jié)點、函數(shù)、節(jié)點數(shù)組、類數(shù)組(jQuery實例)等情況,后續(xù)篇會進行添加。

      為了方便理解,說明部分至于代碼注釋處。

      四、原型方法 select

       1 jQuery.fn = jQuery.prototype = {
       2             select: function (selector, context) {
       3                 var aQuery = selector.split(/\s+/), context = context || document, match = [], elem, result, ret = [], _this = this;
       4                 match = _reg.match_id_class_tag.exec(aQuery[aQuery.length - 1]);
       5                 if (match[1] == "#") { //選擇#id
       6                     elem = [context.getElementById(match[2])];
       7                 }
       8                 else if (match[1] == ".") { //選擇.class
       9                     elem = jQuery.getElementByClassName(match[0], context);
      10                 }
      11                 else if (!match[1]) {  //選擇 tag
      12                     elem = context.getElementsByTagName(match[2]);
      13                 }
      14                 //分割線----------------------------------------------
      15                 if (elem[0]) {
      16                     jQuery.each(elem, function (k, v) {
      17                         result = _this.filter(v, aQuery, context); //遍歷過濾
      18                         if (result != null) {
      19                             ret.push(result);
      20                         }
      21                     })
      22                 }
      23                 return ret;
      24             }
      25         }

      說明:

      1、分割線以上:按照上述思路,將傳入?yún)?shù)處理,直接選取最后一個參數(shù),選擇符合其要求的節(jié)點

      2、分割線一下:進行過濾操作,將符合要求的節(jié)點壓入數(shù)組

      五、原型方法 filter

       1 jQuery.fn = jQuery.prototype = {
       2        filter: function (elem, aQuery, context) {
       3        var match = [],isMatch = [],i = aQuery.length - 1,context = context || document.body,result,parentNode,matchParentNode=elem;
       4                 if (i == 0) { return elem; } //如果就一個選擇條件
       5                 parentNode = elem.parentNode;
       6                 while (i--) {//倒序循環(huán)選擇條件
       7                     match = /(#|\.)?(\w+)/.exec(aQuery[i]); //匹配id class tag
       8                     while (parentNode != context) {
       9                         if (match[1] == "#") { //選擇#id
      10                             if (parentNode.getAttribute("id") == match[2]) {
      11                                 isMatch[i] = true;
      12                                 matchParentNode = parentNode;
      13                             }
      14                         }
      15                         else if (match[1] == ".") { //選擇.class
      16                             var className = document.all ? "className" : "class";
      17                             if (parentNode.getAttribute(className) == match[2]) {
      18                                 isMatch[i] = true;
      19                                 matchParentNode = parentNode;
      20                             }
      21                         }
      22                         else if (!match[1]) {  //選擇 tag
      23                             if (parentNode.nodeName == match[2].toUpperCase()) {
      24                                 isMatch[i] = true;
      25                                 matchParentNode = parentNode;
      26                             }
      27                         }
      28                         parentNode = (parentNode == matchParentNode) ? matchParentNode.parentNode : parentNode.parentNode;
      29                     }
      30                     parentNode = matchParentNode;
      31                 }
      32                 //isMatch為判定標(biāo)志位,其長度應(yīng)該等于父選擇條件的個數(shù),且每一項都為true才能判定為選中
      33                 result = (isMatch.length == aQuery.length - 1) && !(/,,/.test(("," + isMatch.join(',') + ","))) ? elem : null;
      34                 return result;
      35             }
      36   }

      說明:

      為了方便理解,說明部分至于代碼注釋處。

       

      讀到這里,如果你還是沒太了解代碼的意圖,這里再給你說下流程,方便你看代碼

      五部分代碼:簡稱為a、b、c、d、e

      a和b是一塊,其為靜態(tài)方法,也就是輔助用的函數(shù),a目的是遍歷作用,b為兼容得到按類查找節(jié)點

      c、d、e為一塊,其為原型方法,仿照Sizzle的思路,例如:$(".class1 .class2 .class3")

      第一步:利用select方法查找所有的樣式類名為class3的元素集合

      第二部:然后將集合丟給filter方法,進行".class1 .class2“的判定查找其父節(jié)點符合的類名是否為class2,若有則設(shè)在isMacth[1]=true,負責(zé)繼續(xù)查找上層父節(jié)點,直到body節(jié)點,最后將結(jié)果集join(","),如果全滿足條件的話會得到”,true,true,“這種字符串,所以利用”,,“這種連續(xù)逗號的方式判定,有的標(biāo)志位沒有true

      第三部:返回init中得到滿足條件的元素集合,創(chuàng)造類數(shù)組并返回。

       

      自此,成功構(gòu)造出支持id、類名、標(biāo)簽的路徑CSS查找器。

       

       

      (本篇至此,其他內(nèi)容未完,待續(xù)……)

       

      下一節(jié)提示:

      趁熱打鐵,打造find原型方法,并完整擴展init方法

      posted on 2013-05-19 16:26  _xiaoMo_  閱讀(500)  評論(0)    收藏  舉報

      導(dǎo)航

      主站蜘蛛池模板: 综合欧美视频一区二区三区| 人人妻人人澡人人爽不卡视频| 宜都市| 久久夜色撩人国产综合av| 日本一高清二区视频久二区| 国产精品尤物午夜福利| 成人精品一区二区三区四| 天天综合亚洲色在线精品| 国精一二二产品无人区免费应用| 亚洲另类激情专区小说图片| 国产亚洲欧洲av综合一区二区三区| 亚洲精品一区二区动漫| 日韩一区二区三区在线视频| 久久人人97超碰精品| 久久综合精品成人一本| 亚洲av成人一区二区三区| 国产一级r片内射免费视频| 亚洲欧美日韩综合久久| 中文在线天堂中文在线天堂| 色综合久久久久综合体桃花网| 亚洲国产在一区二区三区| 怡红院一区二区三区在线| 国产成人一区二区三区免费| 国产精品爆乳奶水无码视频免费| 亚洲福利精品一区二区三区| 红安县| 精品视频福利| 亚洲国产午夜精品福利| 亚洲精品漫画一二三区| 国产精品伦人一久二久三久| 综合欧美视频一区二区三区| 欧美偷窥清纯综合图区| 中文字幕有码高清日韩| 日韩精品中文字幕人妻| 日韩精品二区三区四区| 乱人伦无码中文视频在线| 亚洲精品宾馆在线精品酒店| 久久精品国产99精品亚洲| 亚洲精品国产自在久久| 悠悠人体艺术视频在线播放| 乱人伦中文字幕成人网站在线|