簡體   English   中英

getElementsByClassName顯示正確的長度,但不在第三(最后)結果上執行代碼

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

JSFiddle針對這個問題。

我有一個函數,當你更改下拉列表的值時執行。 它選擇具有與select選項值對應的類名的所有元素。 (即“Ralph”選擇所有具有類名“Ralph”的div元素)。

從那里開始,我已經完成了迭代類數組的事情(我對編程詞匯量並不太好)。 我覺得它很棒。 然后我意識到,它不會隱藏第三個“丹”元素。

在我從選擇下拉列表中選擇另一個值后,它會隱藏它,然后再次選擇“Dan”。

我可以看到控制台中沒有錯誤。 我嘗試過以下方法:

  1. 在IF語句的x.length上添加+1以嘗試強制它再次執行。

  2. 設置i = -1(愚蠢,我知道。搗蛋鬼,它不起作用)。

在控制台中,您將注意到我記錄了var x的初始長度(它包含類名)。 它正確地識別出有3個“丹”元素。 我很難過為什么它沒有隱藏最后一個。

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:

<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>   

正如我在評論中所說的那樣... getElementsByClassName返回一個Live HTMLCollection意味着它會隨着你改變DOM而改變

您最好的選擇是在處理對象之前將對象復制到數組中。 像這樣......

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");
    }
}

另一個選擇可能是反向遍歷元素...或創建一個while循環,查看數組中的第一個項目,直到沒有更多的項目。 像這樣......

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

這是使用一些不同API的解決方案的另一種方法。 解釋和參考資料在來源中進行了評論。

小提琴

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> 

參考

  1. querySelector
  2. 事件目標
  3. querySelectorAll
  4. 將NodeList轉換為數組
  5. 班級名冊

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM