嵌套的HTML表无法正确显示

时间:2019-06-07 11:57:33

标签: javascript html css

我正在尝试在HTML表中创建父行和子行的数据。目前该代码可以运行,但是由于我不熟悉JavaScript,所以我并不总是选择正确的元素。在提供的代码中,单击第一个父对象仅显示一个孩子,而不同时显示两个孩子,而单击第二个父对象仅显示第一个孩子的第一个孩子。

我90%确信该错误出在JavaScript中。

var toggler = document.getElementsByClassName("parent");
var i;
for (i = 0; i < toggler.length; i++) {
  toggler[i].addEventListener("click", function() {
    this.parentElement.querySelector(".child").classList.toggle("active");
    this.classList.toggle("parent-down");
    this.parentElement.querySelector(".arrow").classList.toggle("arrow-down ");
  });
}
.parent {
  cursor: pointer;
  user-select: none;
  /* Prevent text selection */
  font-size: 16px;
}

.arrow-down::before {
  -ms-transform: rotate(90deg);
  /* IE 9 */
  -webkit-transform: rotate(90deg);
  /* Safari */
  '
 transform: rotate(90deg);
}

.parent-down {
  border: 2px solid rgb(21, 67, 96);
  font-weight: bold;
}


/* Hide the child list */

.child {
  display: none;
  background-color: rgb(240, 250, 255);
  font-size: 14px;
}

.active {
  display: table-row;
}

.arrow::before {
  content: "\25B6";
  color: black;
  display: inline-block;
  margin-right: 6px;
}
<table>
  <tr>
    <th>Word</th>
    <th>Number of Letters</th>
    <th>Do I like the word?</th>
  </tr>
  <tr class="parent">
    <td class="arrow">Long Words</td>
    <td>-</td>
    <td>-</td>
  </tr>
  <tr class="child">
    <td>Bamboozle</td>
    <td>9</td>
    <td>Yes.</td>
  </tr>
  <tr class="child">
    <td>Peritoneum</td>
    <td>10</td>
    <td>No.</td>
  </tr>
  <tr class="parent">
    <td class="arrow">Short Words</td>
    <td>-</td>
    <td>-</td>
  </tr>
  <tr class="child">
    <td>Squeak</td>
    <td>6</td>
    <td>Yes.</td>
  </tr>
</table>

5 个答案:

答案 0 :(得分:2)

有点困难,因为您的html结构对此并不理想。但是,您可以使用nextElementSibling属性并将其放入while循环中以查找所需的所有元素。您可能想为while循环编写一个紧急出口,以防万一出问题。 如果我们已经得到了最后一个元素,请检查下一个兄弟姐妹是否不为空。

还删除了类切换中的空格,因为这是不允许的。

但是,我建议更改您的html结构并将折叠按钮移到表格外。表格最适合表格数据,而按钮和其他布局功能最适合。对于像盲人一样使用面向文本的浏览器的人来说,这将很烦人。 数据一词可以很好地放入表格中。

有了更好的元素结构,选择属于正确父元素的元素也将变得更加容易,因此您无需在while循环中进行狡猾的事情。

var toggler = document.getElementsByClassName("parent");
var i;
for (i = 0; i < toggler.length; i++) {
  toggler[i].addEventListener("click", function() {
    var nextSibling = this.nextElementSibling;
    while(nextSibling !== null && nextSibling.classList.contains("child")) {
      nextSibling.classList.toggle("active");
      nextSibling = nextSibling.nextElementSibling;
    }
    this.classList.toggle("parent-down");
    this.querySelector(".arrow").classList.toggle("arrow-down");
  });
}
.parent {
  cursor: pointer;
  user-select: none;
  /* Prevent text selection */
  font-size: 16px;
}

.arrow-down::before {
  -ms-transform: rotate(90deg);
  /* IE 9 */
  -webkit-transform: rotate(90deg);
  /* Safari */
  '
 transform: rotate(90deg);
}

.parent-down {
  border: 2px solid rgb(21, 67, 96);
  font-weight: bold;
}


/* Hide the child list */

.child {
  display: none;
  background-color: rgb(240, 250, 255);
  font-size: 14px;
}

.active {
  display: table-row;
}

.arrow::before {
  content: "\25B6";
  color: black;
  display: inline-block;
  margin-right: 6px;
}
<table>
  <tr>
    <th>Word</th>
    <th>Number of Letters</th>
    <th>Do I like the word?</th>
  </tr>
  <tr class="parent">
    <td class="arrow">Long Words</td>
    <td>-</td>
    <td>-</td>
  </tr>
  <tr class="child">
    <td>Bamboozle</td>
    <td>9</td>
    <td>Yes.</td>
  </tr>
  <tr class="child">
    <td>Peritoneum</td>
    <td>10</td>
    <td>No.</td>
  </tr>
  <tr class="parent">
    <td class="arrow">Short Words</td>
    <td>-</td>
    <td>-</td>
  </tr>
  <tr class="child">
    <td>Squeak</td>
    <td>6</td>
    <td>Yes.</td>
  </tr>
</table>

答案 1 :(得分:0)

使用循环,直到nextElementSibling没有.child类。

var toggler = document.getElementsByClassName("parent");
var i;
for (i = 0; i < toggler.length; i++) {
  toggler[i].addEventListener("click", function() {
    this.parentElement.querySelector(".arrow").classList.toggle("arrow-down");
    let next = this.nextElementSibling;
    while(next && next.classList.contains('child')) {
      next.classList.toggle('active');
      this.classList.toggle("parent-down");
      next = next.nextElementSibling;
    }
  })
};
.parent {
  cursor: pointer;
  user-select: none;
  /* Prevent text selection */
  font-size: 16px;
}

.arrow-down::before {
  -ms-transform: rotate(90deg);
  -webkit-transform: rotate(90deg);
  transform: rotate(90deg);
}

.parent-down {
  border: 2px solid rgb(21, 67, 96);
  font-weight: bold;
}


/* Hide the child list */

.child {
  display: none;
  background-color: rgb(240, 250, 255);
  font-size: 14px;
}

.active {
  display: table-row;
}

.arrow::before {
  content: "\25B6";
  color: black;
  display: inline-block;
  margin-right: 6px;
}
<table>
  <tr>
    <th>Word</th>
    <th>Number of Letters</th>
    <th>Do I like the word?</th>
  </tr>
  <tr class="parent">
    <td class="arrow">Long Words</td>
    <td>-</td>
    <td>-</td>
  </tr>
  <tr class="child">
    <td>Bamboozle</td>
    <td>9</td>
    <td>Yes.</td>
  </tr>
  <tr class="child">
    <td>Peritoneum</td>
    <td>10</td>
    <td>No.</td>
  </tr>
  <tr class="parent">
    <td class="arrow">Short Words</td>
    <td>-</td>
    <td>-</td>
  </tr>
  <tr class="child">
    <td>Squeak</td>
    <td>6</td>
    <td>Yes.</td>
  </tr>
</table>

答案 2 :(得分:0)

我所做的主要更改是在父母上设置ID,并在其孩子上设置与班级相同的ID。

var togglers = document.querySelectorAll(".parent");
togglers.forEach(function(toggler) {
  toggler.addEventListener("click", function() {
    document.querySelectorAll("." + this.id).forEach(function (child) {
    	child.classList.toggle("active");
    })
    this.classList.toggle("parent-down");
    this.querySelector(".arrow").classList.toggle("arrow-down");
  })
})
.parent {
 cursor: pointer;
 user-select: none; /* Prevent text selection */
 font-size: 16px;
 }

.arrow-down::before {
  -ms-transform: rotate(90deg); /* IE 9 */
  -webkit-transform: rotate(90deg); /* Safari */
  transform: rotate(90deg);
}

.parent-down {
  border: 2px solid rgb(21, 67, 96);
  font-weight: bold;
}

/* Hide the child list */
.child {
  display: none;
  background-color: rgb(240, 250, 255);
  font-size: 14px;
}

.active {
  display: table-row;
}

.arrow::before {
  content: "\25B6";
  color: black;
  display: inline-block;
  margin-right: 6px;
}
<table>
 <tr>
  <th>Word</th>
   <th>Number of Letters</th> 
   <th>Do I like the word?</th>    
 </tr>
  <tr id="parent01" class = "parent">
   <td class = "arrow">Long Words</td> 
   <td>-</td>
   <td>-</td>
   </tr>
   <tr class = "child parent01">
    <td>Bamboozle</td> 
    <td>9</td>
    <td>Yes.</td>
   </tr>
   <tr class = "child parent01">
    <td>Peritoneum</td> 
    <td>10</td>
    <td>No.</td>
   </tr>      
   <tr id="parent02" class = "parent">
    <td class = "arrow">Short Words</td> 
    <td>-</td>
    <td>-</td>
   </tr>
   <tr class = "child parent02">
    <td>Squeak</td> 
    <td>6</td>
    <td>Yes.</td>
   </tr>                  
</table>

答案 3 :(得分:0)

您还可以使用forEach语法的ES6循环来解决此问题

let toggler = document.querySelectorAll(".parent");

toggler.forEach(element => {
    element.addEventListener("click", function() {
    let nextSibling = this.nextElementSibling;
    while(nextSibling != null && nextSibling.classList.contains("child")) {
      nextSibling.classList.toggle("active");
      nextSibling = nextSibling.nextElementSibling;
    }
    this.classList.toggle("parent-down");
    this.querySelector(".arrow").classList.toggle("arrow-down");
  });
});
.parent {
  cursor: pointer;
  user-select: none;
  /* Prevent text selection */
  font-size: 16px;
}

.arrow-down::before {
  -ms-transform: rotate(90deg);
  /* IE 9 */
  -webkit-transform: rotate(90deg);
  /* Safari */
  '
 transform: rotate(90deg);
}

.parent-down {
  border: 2px solid rgb(21, 67, 96);
  font-weight: bold;
}


/* Hide the child list */

.child {
  display: none;
  background-color: rgb(240, 250, 255);
  font-size: 14px;
}

.active {
  display: table-row;
}

.arrow::before {
  content: "\25B6";
  color: black;
  display: inline-block;
  margin-right: 6px;
}
<table>
  <tr>
    <th>Word</th>
    <th>Number of Letters</th>
    <th>Do I like the word?</th>
  </tr>
  <tr class="parent">
    <td class="arrow">Long Words</td>
    <td>-</td>
    <td>-</td>
  </tr>
  <tr class="child">
    <td>Bamboozle</td>
    <td>9</td>
    <td>Yes.</td>
  </tr>
  <tr class="child">
    <td>Peritoneum</td>
    <td>10</td>
    <td>No.</td>
  </tr>
  <tr class="parent">
    <td class="arrow">Short Words</td>
    <td>-</td>
    <td>-</td>
  </tr>
  <tr class="child">
    <td>Squeak</td>
    <td>6</td>
    <td>Yes.</td>
  </tr>
</table>
 Run code snippet

答案 4 :(得分:0)

var toggler = document.getElementsByClassName("parent");
var i;
for (i = 0; i < toggler.length; i++) {
  toggler[i].addEventListener("click", function() {
    this.classList.toggle("active");
    nextSibling(this);
  });
}

var nextSibling = function(element) {
  if (!element.nextElementSibling || element.nextElementSibling.classList.contains("parent")) return false;
  element.nextElementSibling.classList.toggle("active-row");
  return arguments.callee(element.nextElementSibling);
}
.parent {
  cursor: pointer;
  user-select: none;
  /* Prevent text selection */
  font-size: 16px;
}

.active .arrow::before {
  -ms-transform: rotate(90deg);
  /* IE 9 */
  -webkit-transform: rotate(90deg);
  /* Safari */
  '
 transform: rotate(90deg);
}


/* Hide the child list */

.child {
  background-color: rgb(240, 250, 255);
  font-size: 14px;
  display: none;
}

.active {
  color: red;
}

.active-row {
  display: table-row;
}

.arrow::before {
  content: "\25B6";
  color: black;
  display: inline-block;
  margin-right: 6px;
}
<table>
  <tr>
    <th>Word</th>
    <th>Number of Letters</th>
    <th>Do I like the word?</th>
  </tr>
  <tr class="parent">
    <td class="arrow">Long Words</td>
    <td>-</td>
    <td>-</td>
  </tr>
  <tr class="child">
    <td>Bamboozle</td>
    <td>9</td>
    <td>Yes.</td>
  </tr>
  <tr class="child">
    <td>Peritoneum</td>
    <td>10</td>
    <td>No.</td>
  </tr>
  <tr class="parent">
    <td class="arrow">Short Words</td>
    <td>-</td>
    <td>-</td>
  </tr>
  <tr class="child">
    <td>Squeak</td>
    <td>6</td>
    <td>Yes.</td>
  </tr>
</table>

使用 nextElementSibling 选择连续的兄弟类“ .child”。请查看代码段。