日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
如何理解與簡(jiǎn)化jQuery的closest函數(shù)

在實(shí)現(xiàn)delegate方法中,有一個(gè)很重要的輔助函數(shù)叫closest,雖然現(xiàn)在它歸類(lèi)為遍歷節(jié)點(diǎn)這個(gè)模塊中。這個(gè)函數(shù)實(shí)現(xiàn)得非常復(fù)雜,洋洋灑灑近50行,完全不符合極限編程的規(guī)矩。

成都創(chuàng)新互聯(lián)-專(zhuān)業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性?xún)r(jià)比臺(tái)江網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式臺(tái)江網(wǎng)站制作公司更省心,省錢(qián),快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋臺(tái)江地區(qū)。費(fèi)用合理售后完善,十年實(shí)體公司更值得信賴(lài)。

 
 
 
  1. closest: function( selectors, context ) {     
  2.     var ret = [], i, l, cur = this[0];    
  3.     // Array    
  4.     if ( jQuery.isArray( selectors ) ) {//這分支的過(guò)濾邏輯基本與下面的一致  
  5.         var match, selector,  
  6.             matches = {},    
  7.             level = 1;    
  8.         if ( cur && selectors.length ) {    
  9.             for ( i = 0, l = selectors.length; i < l; i++ ) {    
  10.                 selector = selectors[i];    
  11.                 if ( !matches[ selector ] ) {    
  12.                     matches[ selector ] = POS.test( selector ) ?    
  13.                         jQuery( selector, context || this.context ) :    
  14.                       selector;    
  15.                 }    
  16.             }    
  17.             while ( cur && cur.ownerDocument && cur !== context ) {  
  18.                 for ( selector in matches ) {    
  19.                     match = matches[ selector ];//這里頻繁創(chuàng)建新的jQuery對(duì)象與使用is這樣復(fù)雜的方法,我不覺(jué)得其高效到哪里去    
  20.                     if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {    
  21.                         ret.push({ selector: selector, elem: cur, level: level });    
  22.                     }    
  23.                 }    
  24.                 cur = cur.parentNode;    
  25.                 level++;    
  26.             }    
  27.         }    
  28.         return ret;    
  29.     }  
  30.     // String     
  31.     var pos = POS.test( selectors ) || typeof selectors !== "string" ?    
  32.             jQuery( selectors, context || this.context ) :    
  33.             0;    
  34.     for ( i = 0, l = this.length; i < l; i++ ) {    
  35.         cur = this[i];    
  36.         while ( cur ) {    
  37.             if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {    
  38.                 ret.push( cur );    
  39.                 break;  
  40.             } else {    
  41.                 cur = cur.parentNode;    
  42.                 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {    
  43.                    break;    
  44.                 }    
  45.             }    
  46.         }     
  47.     }  
  48.     ret = ret.length > 1 ? jQuery.unique( ret ) : ret;    
  49.     return this.pushStack( ret, "closest", selectors );    
  50. },   

恰逢我也想造個(gè)輪子,便去研究它一翻,發(fā)現(xiàn)其***個(gè)可以是字符串,元素節(jié)點(diǎn)或jQuery對(duì)象,還有一個(gè)可選參數(shù),上下文??丛创a前幾句,發(fā)現(xiàn)有個(gè)分支是判斷是否是Array,估計(jì)是供內(nèi)部調(diào)用的優(yōu)化代碼,可以無(wú)視之。于是其方法簡(jiǎn)化為:

 
 
 
  1. closest: function( selectors, context ) {    
  2.     var ret = [], i, l, cur = this[0];    
  3.     // 如果字符串包含位置偽類(lèi)或者是個(gè)元素節(jié)點(diǎn),則封裝為一個(gè)jQuery對(duì)象,否則為0(即false的簡(jiǎn)寫(xiě),用于快速跳過(guò)分支)    
  4.     var pos = POS.test( selectors ) || typeof selectors !== "string" ?    
  5.         jQuery( selectors, context || this.context ) :    
  6.         0;    
  7.     //遍歷原jQuery對(duì)象的節(jié)點(diǎn)    
  8.     for ( i = 0, l = this.length; i < l; i++ ) {    
  9.         cur = this[i];    
  10.         while ( cur ) {    
  11.             //如果是jQuery對(duì)象,則判定其是否包含當(dāng)前節(jié)點(diǎn),否則使用matchesSelector方法判定這個(gè)節(jié)點(diǎn)是否匹配給定的表達(dá)式selectors    
  12.             if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {    
  13.               //是則放入選擇器中    
  14.                 ret.push( cur );    
  15.                 break;   
  16.             } else {    
  17.                 //  否則把當(dāng)前節(jié)點(diǎn)變?yōu)槠涓腹?jié)點(diǎn)    
  18.                 cur = cur.parentNode;    
  19.                 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {    
  20.                     break;    
  21.                 }    
  22.             }    
  23.         }    
  24.     }    
  25.     //如果大于1,進(jìn)行唯一化操作    
  26.     ret = ret.length > 1 ? jQuery.unique( ret ) : ret;    
  27.     //將節(jié)點(diǎn)集合重新包裝成一個(gè)新jQuery對(duì)象返回    
  28.     return this.pushStack( ret, "closest", selectors );    
  29. },  

由于本人很反感位置偽類(lèi),認(rèn)為其違反選擇器的法則之一(由關(guān)系選擇器隔開(kāi)的各選擇器分組內(nèi)部,它們的位置是隨意的),因此有關(guān)位置偽類(lèi)的邏輯我也去掉了。

 
 
 
  1. closest: function( selectors ) {    
  2.     var ret = [], i, l, cur = this[0];    
  3.     // 如果字符串包含位置偽類(lèi)或者是個(gè)元素節(jié)點(diǎn),則封裝為一個(gè)jQuery對(duì)象,否則為0(即false的簡(jiǎn)寫(xiě),用于快速跳過(guò)分支)    
  4.     var node =  selectors.nodeType ? selectors :false;    
  5.     var nodes = [].slice.call(this);//將jQuery對(duì)象轉(zhuǎn)換為純數(shù)組    
  6.     //遍歷原jQuery對(duì)象的節(jié)點(diǎn)    
  7.     for ( i = 0, l = this.length; i < l; i++ ) {    
  8.         cur = this[i];   
  9.         while ( cur ) {    
  10.             //如果是jQuery對(duì)象,則判定其是否包含當(dāng)前節(jié)點(diǎn),否則使用matchesSelector方法判定這個(gè)節(jié)點(diǎn)是否匹配給定的表達(dá)式selectors    
  11.             if ( obj ? nodes.indexOf(node) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {    
  12.                 //indexOf方法在某些瀏覽器需要自行實(shí)現(xiàn)    
  13.                 //是則放入選擇器中    
  14.                 ret.push( cur );    
  15.                 break;    
  16.             } else {    
  17.                 //  否則把當(dāng)前節(jié)點(diǎn)變?yōu)槠涓腹?jié)點(diǎn)    
  18.                 cur = cur.parentNode;    
  19.                 //如果沒(méi)有父節(jié)點(diǎn)(說(shuō)明其還沒(méi)有插入DOM樹(shù)),或不是元素節(jié)點(diǎn),或是文檔碎片(說(shuō)明其剛被移出DOM樹(shù))    
  20.                 if ( !cur || !cur.ownerDocument || cur.nodeType === 11 ) {    
  21.                     break;    
  22.                 }    
  23.             }    
  24.         }    
  25.     }    
  26.     //如果大于1,進(jìn)行唯一化操作    
  27.     ret = ret.length > 1 ? jQuery.unique( ret ) : ret;    
  28.     //將節(jié)點(diǎn)集合重新包裝成一個(gè)新jQuery對(duì)象返回    
  29.     return $(ret);//本人覺(jué)得pushStack真是個(gè)邪惡的方法,讓菜鳥(niǎo)不籽有鏈下去的欲望,殊不知這是維護(hù)的大敵    
  30. },  

注意,jquery1.6中closest方法不再是返回包含一個(gè)或零個(gè)節(jié)點(diǎn)的jQuery對(duì)象了,再是對(duì)應(yīng)多個(gè)了(因此jQuery官網(wǎng)文檔是錯(cuò)誤的,沒(méi)有即時(shí)同步這變化.)

 
 
 
  1.     
  2.  
  3.     
  4.       
  5.     closest在jquery1.6的改變 by 司徒正美    
  6.         
  7.         
  8.       
  9.       
  10.     

        

  11.       使用事件代理1    
  12.     

        
  13.     

        

  14.      使用事件代理2    
  15.     

        
  16.     

        

  17.       使用事件代理3    
  18.     

        
  19.       
  20.   

下面是我的實(shí)現(xiàn):

 
 
 
  1. closest: function( expr ) {    
  2.     // 如果字符串包含位置偽類(lèi)或者是個(gè)元素節(jié)點(diǎn),則封裝為一個(gè)dom對(duì)象,否則為0(即false的簡(jiǎn)寫(xiě),用于快速跳過(guò)分支)    
  3.     var node =  expr.nodeType ? expr : 0, nodes = dom.slice(this);//將它轉(zhuǎn)換為純數(shù)組    
  4.     //遍歷原dom對(duì)象的節(jié)點(diǎn)    
  5.     for (var i = 0, ret = [], cur; cur = this[i++];) {//由于肯定里面都是節(jié)點(diǎn),因此可以使用這種循環(huán)    
  6.         while (cur && cur.nodeType === 1 ) {    
  7.             //如果是dom對(duì)象,則判定其是否包含當(dāng)前節(jié)點(diǎn),否則使用matchesSelector方法判定這個(gè)節(jié)點(diǎn)是否匹配給定的表達(dá)式expr    
  8.             if ( node ? nodes.indexOf(node) > -1 : matchElement( cur, expr ) ){    
  9.                 //indexOf方法在某些瀏覽器需要自行實(shí)現(xiàn)    
  10.                 //是則放入選擇器中    
  11.                 ret.push( cur );    
  12.                 break;    
  13.             } else {    
  14.                 // 否則把當(dāng)前節(jié)點(diǎn)變?yōu)槠涓腹?jié)點(diǎn)    
  15.                 cur = cur.parentNode;    
  16.             }    
  17.         }    
  18.     }    
  19.     //如果大于1,進(jìn)行唯一化操作    
  20.     ret = ret.length > 1 ? dom.unique( ret ) : ret;    
  21.     //將節(jié)點(diǎn)集合重新包裝成一個(gè)新dom對(duì)象返回    
  22.     return this.labor(ret);    
  23. },  

原文鏈接:http://www.cnblogs.com/rubylouvre/archive/2011/05/12/2043854.html

【編輯推薦】

  1. 詳解jQuery構(gòu)造器的實(shí)現(xiàn)
  2. jQuery調(diào)用WCF開(kāi)發(fā)實(shí)例經(jīng)驗(yàn)分享
  3. 5月***超有趣的免費(fèi)jQuery插件推薦
  4. 手把手教你使用jQuery操作元素的屬性與樣式
  5. jQuery性能指標(biāo)和調(diào)優(yōu)

分享名稱(chēng):如何理解與簡(jiǎn)化jQuery的closest函數(shù)
新聞來(lái)源:http://m.5511xx.com/article/dhccoie.html