2016-07-28 22 views
3

Ich versuche, ein Array mit mehreren Werten an eine Funktion übergeben, die überprüft, ob die Werte in einer Liste von divs vorhanden sind, und wenn ja, markieren Sie sie mit roter Hintergrund.Vergleichen meines Arrays funktioniert, bis das Array mehrere Werte enthält

Mein Code funktioniert, wenn ich eine beliebige Zeichenfolge als Parameter übergeben, und es funktioniert, wenn ich ein Array mit nur einem Wert darin haben. Sobald mein Array jedoch zwei oder mehr Werte enthält, scheint es zu brechen, und es gibt keine Informationen in der Konsole, um mich anzuleiten.

Ich glaube, das Problem ist, wie ich die Vergleichsfunktion schrieb, aber es könnte liege auch damit, wie ich das Array passiere.

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>

Antwort

2

Das Problem liegt in der Tatsache, dass Sie ein Array zu String#indexOf() (wie in collection[i].innerText.toLowerCase().indexOf(searchText)) vorbei sind. Diese Funktion erwartet eine Zeichenfolge als Suchbegriff und kein Array.

Was passiert ist, dass Ihr Array in eine Zeichenfolge konvertiert wird. Wenn Ihr Array nur eine einzige Zeichenfolge und keine anderen Elemente enthält, funktioniert es, weil die Zeichenfolgendarstellung dieselbe Zeichenfolge ist. Wenn Ihr Array jedoch mehr als ein Element enthält, ist die Zeichenfolgendarstellung eine durch Kommas getrennte Liste aller Zeichenfolgen, die nicht korrekt verglichen wird.

Sie eine Schleife durch das Array benötigen, um die Einzelteile in Ihrer Sammlung für jeden des Strings in dem Array (I die Parameter deutlich zu machen, umbenannt habe, das Sie vorbei ein Array) zu suchen:

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

Dank! Sehr schwierig, dass es eine 'String.prototype.indexOf()' und eine 'Array.prototype.indexOf()' gibt; das hat meinen Kopf verwirrt. Ich bin es auch nicht gewohnt, für Loops direkt in Schleifen zu verschachteln. – 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

Dieser Ansatz führt eine kleine Regression meiner bestehenden Funktionalität ein, indem sie nicht mehr alle Instanzen einer Zeichenkette anpasst, sondern nur die erste (zB fügt "Religion" der Liste in Ihrem Beispiel nicht mehr alle Einträge hinzu) mit "Religion" in ihnen). +1, um das Problem zu lösen, dass mein mehrwertiges Array nicht funktioniert. – TylerH

+2

Das Problem beim Umkehren der Bedingung ist, dass die Suche nach Teilschlüsseln nicht mehr funktioniert. Zum Beispiel wird die Eingabe von "Hunden" nicht mit "Hotdogs" übereinstimmen, da letztere nicht in ersterer erscheinen können. Dies kann oder kann kein Problem sein, abhängig von den Anforderungen des Fragestellers, aber ich bezweifle sehr, dass der Fragesteller von den Benutzern erwartet, dass "alles mit Religionen drin ist geschraubt" ist. nur um diesen letzten Gegenstand zu finden. – BoltClock

+0

Ja, wenn Sie eine Teilübereinstimmung benötigen, müssen Sie jeden String überprüfen, ich habe den Code ein wenig modifiziert (mit einem funktionelleren Ansatz - Vermeiden der Schleifen innerhalb von Schleifen und Schleifen im Allgemeinen). Es ist besser, die DOM-Knotenliste in ein reales Array umzuwandeln. Auch Sie können Sammlung bei jedem Klick in diesem Fall erhalten, wenn ein neues Element hinzugefügt wurde, wird es auch gefiltert und Sie haben eine weitere weniger globale Variable. – cstuncsik