简体   繁体   English

getElementsByClassName显示正确的长度,但不在第三(最后)结果上执行代码

[英]getElementsByClassName Showing Correct Length, but Not Executing Code on Third (Last) Result

JSFiddle for this issue. JSFiddle针对这个问题。

I've got a function that executes when you change the value of the dropdown. 我有一个函数,当你更改下拉列表的值时执行。 It selects all elements with the class name that corresponds with the value of the select option. 它选择具有与select选项值对应的类名的所有元素。 (ie "Ralph" selects all div elements with the classname "Ralph"). (即“Ralph”选择所有具有类名“Ralph”的div元素)。

From there, I've attemtped to iterate through the class array things (I'm not too great with programming vocabulary). 从那里开始,我已经完成了迭代类数组的事情(我对编程词汇量并不太好)。 I thought it was working great. 我觉得它很棒。 Then I realized, that it will not hide the third "Dan" element. 然后我意识到,它不会隐藏第三个“丹”元素。

It does hide it after I select another value from the select drop down, and then select "Dan" again. 在我从选择下拉列表中选择另一个值后,它会隐藏它,然后再次选择“Dan”。

There is no error in the console that I can see. 我可以看到控制台中没有错误。 I've tried the following: 我尝试过以下方法:

  1. Adding +1 to the x.length of the IF statement to try and force it to do it again. 在IF语句的x.length上添加+1以尝试强制它再次执行。

  2. Setting i = -1 (stupid, I know. Spoiler, it didn't work). 设置i = -1(愚蠢,我知道。捣蛋鬼,它不起作用)。

In the console, you'll note that I log the initial length of the var x (which holds the class names). 在控制台中,您将注意到我记录了var x的初始长度(它包含类名)。 It is correctly identifying that there are 3 "Dan" elements. 它正确地识别出有3个“丹”元素。 I'm stumped as to why it's not hiding the last one. 我很难过为什么它没有隐藏最后一个。

JS: JS:

var x;
function filterName(n) {
    x = document.getElementsByClassName(n);
    console.log(x.length);
    for (i = 0; i < x.length; i++) {
        x[i].setAttribute("class", "hidden");
    }
}

HTML: HTML:

<div class="container">
  <div class="names col-sm-12">
    <form name="filterDB" action="POST">
      <select id="filterName" name="filterName">
        <option value="" disabled="" selected="">Filter by Employee: </option>
        <option id="Ralph" name="name" value="Ralph">Ralph</option>
        <option id="Dan" name="name" value="Dan">Dan</option>
        <option id="Brady" name="name" value="Brady">Brady</option>
        <option id="Abby" name="name" value="Abby">Abby</option>
      </select>
    </form>
  </div>

  <div class="col-md-2 col-md-offset-1">
    <h4 class="titles">Monday</h4>
    <hr>
    <div class="Ralph">Name: Ralph<hr></div>
  </div>
  <div class="col-md-2">
    <h4 class="titles">Tuesday</h4>
    <hr>
    <div class="Dan">Name: Dan<hr></div>
    <div class="Dan">Name: Dan<hr></div>
  </div>
  <div class="col-md-2">
    <h4 class="titles">Wednesday</h4>
    <hr>
    <div class="Brady">Name: Brady<hr></div>
  </div>
  <div class="col-md-2">
    <h4 class="titles">Thursday</h4>
    <hr>
    <div class="Abby">Name: Abby<hr></div>
  </div>
  <div class="col-md-2">
    <h4 class="titles">Friday</h4>
    <hr>
    <div class="Dan">Name: Dan<hr></div>
  </div>
  <div class="clearfix"></div>
</div>   

As I said in my comment... getElementsByClassName returns a Live HTMLCollection meaning that it will change as you change the DOM 正如我在评论中所说的那样... getElementsByClassName返回一个Live HTMLCollection意味着它会随着你改变DOM而改变

Your best option would be to copy the objects into an array before you process them. 您最好的选择是在处理对象之前将对象复制到数组中。 Something like this... 像这样......

function filterName(n) {
    var x = document.getElementsByClassName(n);
    var objs = [];
    for (i = 0; i < x.length; i++) {
        objs.push(x[i]);
    }
    for (i = 0; i < objs.length; i++) {
        objs[i].setAttribute("class", "hidden");
    }
}

Another option could be to go through the elements in reverse... or create a while loop that looks at the first item in the array until there are no more items. 另一个选择可能是反向遍历元素...或创建一个while循环,查看数组中的第一个项目,直到没有更多的项目。 Something like this... 像这样......

function filterName(n) {
    var x = document.getElementsByClassName(n);
    while (x.length > 0) {
        x[0].setAttribute("class", "hidden");
    }
}

Here's another way to a solution utilizing some different APIs. 这是使用一些不同API的解决方案的另一种方法。 The explanations and references are commented in the source. 解释和参考资料在来源中进行了评论。

FIDDLE 小提琴

SNIPPET SNIPPET

 /* Footnotes at the end */ // Alt. var filter = document.querySelector('#filterName');¹ var filter = document.getElementById('filterName'); /* Use the Event Object to in order to determine event.target² || (the element that was clicked) || Event Object----------------------------⇲ */ filter.addEventListener("change", function(event) { // Save event.target's value in the variable 'employee' var employee = event.target.value; // Call filterName and pass in 'employee' filterName(employee); }, false); function filterName(name) { // Alt. nodeNames = document.querySelectorAll('.' + name);³ var nameNodes = document.getElementsByClassName(name); // Convert nodeNames to an array⁴ var nameArray = Array.prototype.slice.call(nameNodes); console.log(nameArray.length); /* Iterate through nameArray and on each iteration || use `classList.add`⁵ to add the .hidden class. */ for (var i = 0; i < nameArray.length; i++) { nameArray[i].classList.add("hidden"); } } /* ¹ https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector || ² https://developer.mozilla.org/en-US/docs/Web/API/EventTarget || ³ https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll || ⁴ https://developer.mozilla.org/en-US/docs/Web/API/NodeList#Converting_a_NodeList_to_an_Array || ⁵ https://developer.mozilla.org/en-US/docs/Web/API/Element/classList */ 
 .hidden { display: none; } 
 <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> <div class="container"> <div class="names col-sm-12"> <form name="filterDB" action="POST"> <select id="filterName" name="filterName"> <option value="" disabled="" selected="">Filter by Employee:</option> <option id="Ralph" name="name" value="Ralph">Ralph</option> <option id="Dan" name="name" value="Dan">Dan</option> <option id="Brady" name="name" value="Brady">Brady</option> <option id="Abby" name="name" value="Abby">Abby</option> </select> </form> </div> <div class="col-md-2 col-md-offset-1"> <h4 class="titles">Monday</h4> <hr> <div class="Ralph">Name: Ralph <hr> </div> </div> <div class="col-md-2"> <h4 class="titles">Tuesday</h4> <hr> <div class="Dan">Name: Dan <hr> </div> <div class="Dan">Name: Dan <hr> </div> </div> <div class="col-md-2"> <h4 class="titles">Wednesday</h4> <hr> <div class="Brady">Name: Brady <hr> </div> </div> <div class="col-md-2"> <h4 class="titles">Thursday</h4> <hr> <div class="Abby">Name: Abby <hr> </div> </div> <div class="col-md-2"> <h4 class="titles">Friday</h4> <hr> <div class="Dan">Name: Dan <hr> </div> </div> <div class="clearfix"></div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> 

REFERENCES 参考

  1. querySelector querySelector
  2. EventTarget 事件目标
  3. querySelectorAll querySelectorAll
  4. Converting a NodeList to an Array 将NodeList转换为数组
  5. classList 班级名册

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM