2016-07-28 26 views
3

我試圖將多個值的數組傳遞給函數,該函數將檢查值是否存在於div列表中,如果是,則用紅色背景。比較我的數組作品,直到數組中有多個值

我的代碼工作時,我傳遞一個任意字符串作爲參數,它有效,當我有一個數組只有一個值。然而,一旦我的陣列有兩個或更多的值,它似乎打破了,並沒有在控制檯中的信息來暗示我。

我相信問題是與我如何編寫比較函數,但它可以還與我如何通過陣列說謊。

var postList = document.getElementsByClassName("post"); 
 
var userList = new Array(); 
 

 
//compares the user's keyword entries to the text in the divs, and marks "matching" divs with a red background 
 
function listComparison(collection, searchText) { 
 
    for (var i = 0; i < collection.length; i++) { 
 
     if (collection[i].innerText.toLowerCase().indexOf(searchText) > -1) { 
 
      collection[i].style.backgroundColor = "red"; 
 
     } 
 
    } 
 
} 
 

 
//adds user entries to an array on click and clears out the textarea 
 
document.getElementById("save").addEventListener("click", function() { 
 
    var listEntry = document.getElementById("listEntries").value; 
 
    userList.push(listEntry); 
 
    document.getElementById("listEntries").value = ""; 
 
    console.log(userList); 
 
}) 
 

 
//event listener for the button that runs the collectionContains function above 
 
document.getElementById("run").addEventListener("click", function() { 
 
    listComparison(postList, userList); 
 
});
div { 
 
    background: #d0dbe6; 
 
    margin: 5px; 
 
    width: 50%; 
 
} 
 

 
#list { 
 
    width: 300px; 
 
    height: 100px; 
 
}
<textarea placeholder="Enter words here one at a time and click 'Add to Filter'" id="listEntries"></textarea> 
 
<br> 
 
<button id="save" for="listEntries">Add to Filter</button> 
 
<button id="run">Run Filter</button> 
 

 
<div class="post">religion</div> 
 
<div class="post">cats</div> 
 
<div class="post">hotdogs</div> 
 
<div class="post">babies</div> 
 
<div class="post">test me please</div> 
 
<div class="post">filler</div> 
 
<div class="post">lorem ipsum</div> 
 
<div class="post">your mom</div> 
 
<div class="post">religion again</div> 
 
<div class="post">build a wall</div> 
 
<div class="post">no it's becky</div> 
 
<div class="post">anything with religions in it is screwed!</div>

回答

2

的問題在於,你傳遞一個數組String#indexOf()(如collection[i].innerText.toLowerCase().indexOf(searchText))的事實。該函數需要一個字符串作爲搜索項,而不是數組。

發生什麼事是你的數組正在轉換成一個字符串。當你的數組只包含一個字符串而沒有其他元素時,它的工作原理是因爲它的字符串表示形式是同一個字符串。但是,當數組包含多個元素時,其字符串表示形式就是所有這些字符串的逗號分隔列表,並且這不會進行正確的比較。

您將需要循環訪問數組,以便在數組中爲每個字符串搜索集合中的項目(我已將參數重命名爲使其清楚地表明您正在傳遞數組):

var postList = document.getElementsByClassName("post"); 
 
var userList = new Array(); 
 

 
//compares the user's keyword entries to the text in the divs, and marks "matching" divs with a red background 
 
function listComparison(collection, searchList) { 
 
    for (var i = 0; i < searchList.length; i++) { 
 
     for (var j = 0; j < collection.length; j++) { 
 
      if (collection[j].innerText.toLowerCase().indexOf(searchList[i]) > -1) { 
 
       collection[j].style.backgroundColor = "red"; 
 
      } 
 
     } 
 
    } 
 
} 
 

 
//adds user entries to an array on click and clears out the textarea 
 
document.getElementById("save").addEventListener("click", function() { 
 
    var listEntry = document.getElementById("listEntries").value; 
 
    userList.push(listEntry); 
 
    document.getElementById("listEntries").value = ""; 
 
    console.log(userList); 
 
}) 
 

 
//event listener for the button that runs the collectionContains function above 
 
document.getElementById("run").addEventListener("click", function() { 
 
    listComparison(postList, userList); 
 
});
div { 
 
    background: #d0dbe6; 
 
    margin: 5px; 
 
    width: 50%; 
 
} 
 

 
#list { 
 
    width: 300px; 
 
    height: 100px; 
 
}
<textarea placeholder="Enter words here one at a time and click 'Add to Filter'" id="listEntries"></textarea> 
 
<br> 
 
<button id="save" for="listEntries">Add to Filter</button> 
 
<button id="run">Run Filter</button> 
 

 
<div class="post">religion</div> 
 
<div class="post">cats</div> 
 
<div class="post">hotdogs</div> 
 
<div class="post">babies</div> 
 
<div class="post">test me please</div> 
 
<div class="post">filler</div> 
 
<div class="post">lorem ipsum</div> 
 
<div class="post">your mom</div> 
 
<div class="post">religion again</div> 
 
<div class="post">build a wall</div> 
 
<div class="post">no it's becky</div> 
 
<div class="post">anything with religions in it is screwed!</div>

+0

謝謝!非常棘手的是有一個'String.prototype.indexOf()'和'Array.prototype.indexOf()';那與我頭腦混爲一談。我也不習慣在for循環內直接嵌套循環。 – TylerH

0

var userList = new Array(); 
 

 
//compares the user's keyword entries to the text in the divs, and marks "matching" divs with a red background 
 
function listComparison(collection, searchText) { 
 
    collection.filter(function(elem) { 
 
    return !!searchText.filter(function(text) { 
 
     return elem.innerText.toLowerCase().indexOf(text) > -1; 
 
    }).length; 
 
    }).forEach(function(elem) { 
 
    elem.style.backgroundColor = "red"; 
 
    }); 
 
} 
 

 
//adds user entries to an array on click and clears out the textarea 
 
document.getElementById("save").addEventListener("click", function() { 
 
    var listEntry = document.getElementById("listEntries"); 
 
    userList.push(listEntry.value); 
 
    listEntry.value = ""; 
 
    console.log(userList); 
 
}) 
 

 
//event listener for the button that runs the collectionContains function above 
 
document.getElementById("run").addEventListener("click", function() { 
 
    var collection = Array.prototype.slice.call(document.getElementsByClassName("post")); 
 
    listComparison(collection, userList); 
 
});
div { 
 
    background: #d0dbe6; 
 
    margin: 5px; 
 
    width: 50%; 
 
} 
 
#list { 
 
    width: 300px; 
 
    height: 100px; 
 
}
<textarea placeholder="Enter words here one at a time and click 'Add to Filter'" id="listEntries"></textarea> 
 
<br> 
 
<button id="save" for="listEntries">Add to Filter</button> 
 
<button id="run">Run Filter</button> 
 

 
<div class="post">religion</div> 
 
<div class="post">cats</div> 
 
<div class="post">hotdogs</div> 
 
<div class="post">babies</div> 
 
<div class="post">test me please</div> 
 
<div class="post">filler</div> 
 
<div class="post">lorem ipsum</div> 
 
<div class="post">your mom</div> 
 
<div class="post">religion again</div> 
 
<div class="post">build a wall</div> 
 
<div class="post">no it's becky</div> 
 
<div class="post">anything with religions in it is screwed!</div>

+0

該方法引入了一些迴歸我現有的功能,因爲它不再將匹配應用於字符串的所有實例,但只有第一個(例如,在示例中向列表中添加「宗教」不再突出顯示所有條目與他們的「宗教」)。 +1雖然,技術上解決了我的多值數組無法正常工作的問題。 – TylerH

+2

翻轉這種情況的問題是搜索部分關鍵字不再有效。例如,輸入「狗」不符合「熱狗」,因爲後者不可能出現在前者中。這取決於提問者的要求,可能會也可能不是問題,但我高度懷疑提問者希望用戶輸入「任何帶有宗教信仰的東西都被搞砸了!」只是爲了匹配最後一個項目。 – BoltClock

+0

是的,如果你需要部分匹配,你需要檢查每一個字符串,我只是修改了一些代碼(使用更多功能的方法 - 避免循環內的循環,以及一般循環)。最好將DOM節點列表轉換爲真實數組。 此外,如果有新的elem添加它也會被過濾,並且您將會減少一個全局變量,您也可以在每次點擊中獲得收集。 – cstuncsik