2017-07-31 43 views
-1

我想測試一個元素上有一個特定的類。這if語句的工作:如何讓班級名冊到位的className的成功,我如果JavaScript語句?

if (children[i].className === siblingClass) 

然而,只有作品如果children[i]只有一個類,它是完全一樣的siblingClass值。我想使功能多一點一般化,以測試是否children[i]siblingClass即使它還有其他類也是如此。

所以我嘗試了classList.contains function,就像這樣:

if (children[i].classList.contains(siblingClass)) 

但是,當我嘗試它(在Chrome),控制檯日誌說:

Uncaught TypeError: Cannot read property 'contains' of undefined

如何創建一個測試看看是否有children[i]它可能有一個或多個類之列siblingClass

請注意我希望有一個純Javascript的解決方案,如果可能的話,不需要jQuery。

這是出現在if聲明的全部功能:

function getSiblingByClass(currentObject, siblingClass) 
{ 
    var parentofSelected = currentObject.parentNode, 
     children = parentofSelected.childNodes, 
     element, 
     i; 

    for (i = 0; i < children.length; i++) 
    { 
     if (children[i].classList.contains(siblingClass)) 
     { 
      element = children[i]; 
      break; 
     } 
    } 
    return element; 
} 

這個功能是從其他函數中調用時,我想元素兄弟姐妹之間尋找一個具有指定類的元素。它獲取當前元素的父元素,遍歷所有子元素,並返回第一個匹配項。或者,至少這是這個想法。

下面是一些HTML它調用的函數,後者又調用上面的函數:

<div> 
     <span class="fee">hello world</span> 
     <span class="fi">Blah blah blah</span> 
     <button class="foo" onclick="copySiblingDataByClass(this, 'fi');">Click here</button> 
    </div> 

copySiblingDataByClass()將依次調用getSiblingByClass(),並通過自身和類的名稱被選中。

+2

什麼是'孩子[I]'?你使用什麼瀏覽器版本?請創建一個[mcve] –

+2

@Satpal錯誤清楚地表明'children [i]'被定義,'children [i] .classList'是'undefined'。如果'children [i]'是'undefined',那麼錯誤會說**無法讀取undefined **的屬性'classList'。這個問題很可能是因爲'children [i]'不是一個元素節點 –

+2

@評論者::請認真看待OP不是一個白癡,你可能不知道背景的具體細節 - 在跳到結論和作爲這些假設的結果而下調。 – argon

回答

1

然而,在一個字符串或數組上使用Node.contains並不是它的意思,把你的功能,你可以使它的工作方式。

考慮下面的「原型升級」 - 發生在你的JS代碼開頭,它提供的功能在全球範圍:

Object.defineProperty(String.prototype,'contains',{enumerable:false, configurable:false, writable:false, value:function(find) 
{ 
    return ((' '+this+' ').indexOf(' '+find+' ') > -1); 
}}); 


現在,你可以簡單地在任何地方使用它在你的代碼是這樣的:

someNode.className.contains('foo'); // returns a boolean 


..however,如果是我的話我會簡單地使用你的應用功能,所有的元素自動,就像這樣:

Object.defineProperty(Element.prototype,'hasClass',{enumerable:false, configurable:false, writable:false, value:function(name) 
{ 
    return ((' '+this.className+' ').indexOf(' '+name+' ') > -1); 
}}); 


現在只需使用它像:

someNode.hasClass('foo'); 
1

下面有一些方法可以嘗試:

var div = document.getElementById('div'); 
 

 
// classList method 
 
if (div.classList.contains('world')) 
 
    console.log(true); 
 
else 
 
    console.log(false); 
 

 
// RegExp method 
 
if (/\s|^\wworld\s/.test(div.className)) 
 
    console.log(true); 
 
else 
 
    console.log(false); 
 

 
// Converting classname into array to use array method 
 
if (div.className.split(' ').includes('world')) 
 
    console.log(true); 
 
else 
 
    console.log(false); 
 
    
 
// Also using array method, but more compatible 
 
if (div.className.split(' ').indexOf('world') > -1) 
 
    console.log(true); 
 
else 
 
    console.log(false); 
 

 
// Borrowing array method to use on classList 
 
if (Array.prototype.includes.call(div.classList, 'world')) 
 
    console.log(true); 
 
else 
 
    console.log(false);
<div id="div" class="hello world foo bar"></div>

還有很多更多的方式做你變得更有創意。

PS

從你的榜樣,看來你children[i]可能不是一個元素。非元素節點不具有classList,因此undefined

另一種可能性是您的Chrome瀏覽器極其過時和過時。

1

看來,你的代碼是for環路的一部分,所以,考慮以下因素:

var children=[].slice.call(document.getElementById('someID').childNodes); 
var siblingClass = 'someClassName'; // for example 

for(var i in children) 
{ 
    if(!children.hasOwnProperty(i)){continue}; // get rid of "undefined" 
    if(children[i].className.indexOf(siblingClass) > -1) 
    { 
     // you other code here 
    } 
} 
+0

謝謝你的迴應。我在解析如何將'slice.call'和'hasOwnProperty'應用於我的用例時遇到了一些困難。我已經將完整的功能添加到了我的問題中,希望能夠增加我的問題的清晰度。 – Questioner

+0

@Questioner - '[] .slice。call()'部分只是一種確保處理「類似數組」的結果的方法;所以,它只是將childNodes轉換/確保爲可枚舉列表。通過使用這個,你現在可以使用像'childNodes.forEach(function(node){/ *你的代碼在這裏* /});' - 那麼你不需要'hasOwnProperty'。 – argon

0

多的測試後,在這裏提出以下建議,我根本無法推斷爲什麼classList.contains()不會爲我工作。 MDN says it's been supported in Chrome since version 8和我正在運行的版本60.

但是,我需要將我的代碼投入生產,所以我不能再投入更多時間來解釋它的奧祕。幸運的是,我在this answer中找到了一個函數,它將成功地從連接到對象的多個類中選擇一個類。

function hasClass(element, cls) 
{ 
    return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1; 
} 

使用此功能,if語句現在看起來我就像這樣:

if (hasClass(children[i], siblingClass)) 

...和它完美的作品,所以這是我將使用的解決方案。

如果有人能告訴我如何讓classList.contains()工作,或解釋爲什麼它沒有,我很樂意將該答案標記爲正確。