【问题标题】:Target all the label inside a table using javascript使用javascript定位表内的所有标签
【发布时间】:2018-09-10 12:21:38
【问题描述】:

我有以下设置。在这里我正在尝试添加自定义单选和复选框。

Array.from(document.querySelectorAll("tr")).forEach((tr,index)=>{
  var mark=document.createElement("span");
  Array.from(tr.querySelectorAll("input")).forEach((inp,index1)=>{
    if(inp.type=="radio"){
      mark.classList.add("dotmark");
      inp.parentNode.appendChild(mark);
    }
    else{
      mark.classList.add("checkmark");
      inp.parentNode.appendChild(mark);//instead append in to the next td's label tag
    }
  })
})
span{
width:20px;
height:20px;
background:#ccc;
display:inline-block;
}
<table id="tab1" class="table labelCustom">
   <tbody>
        <tr><td><input type='radio' id='one' name='name'></td><td><label for='one'>example</label></td></tr>
        <tr><td><input type='radio' id='two' name='name'></td><td><label for='two'>example</label></td></tr>
        <tr><td><input type='radio' id='three' name='name'></td><td><label for='three'>example</label></td></tr>
   </tbody>
</table>

我希望将动态创建的 span 元素插入到标签标签中。现在它把它插入到输入 td 中。

注意:span 元素的类取决于输入类型。

【问题讨论】:

  • inp.parentNodetd。也许试试inp.closest('tr').querySelector('label')
  • 我希望将 span 元素插入到下一个 td 的标签标签中
  • 对 connexo 的进一步评论:inp.parentNode.nextElementSibling.querySelector('label').appendChild('mark');您发布的脚本表明您似乎非常了解 JavaScript,所以我在您的问题中遗漏了什么吗?你需要什么帮助?此外,您的评论意味着如果input 不是type=radio,您只希望将&lt;span&gt; 附加到&lt;label&gt;
  • @DavidThomas,谢谢,我尝试了“nextSibling”,但它不起作用,但 nextSiblingElement 起作用了。

标签: javascript html css dom-traversal


【解决方案1】:

其中一种方法如下:

Array.from(document.querySelectorAll("tr")).forEach((tr, index) => {
  var mark = document.createElement("span");
  Array.from(tr.querySelectorAll("input")).forEach((inp, index1) => {

    // caching the <label> element for readability:
    let label = inp.parentNode.nextElementSibling.querySelector('label');

    // adding the class-name based on the result of the ternary operator,
    // if the input.type is equal to 'radio' we return the class-name of
    // 'dotmark', otherwise we return 'checkmark':
    mark.classList.add(inp.type === 'radio' ? 'dotmark' : 'checkmark');

    // appending the element held within the 'mark' variable:
    label.appendChild(mark);
  })
})
span {
  width: 20px;
  height: 20px;
  background: #ccc;
  display: inline-block;
}

span.dotmark {
  background-color: limegreen;
}

span.checkmark {
  background-color: #f90;
}
<table id="tab1" class="table labelCustom">
  <tbody>
    <tr>
      <td><input type='radio' id='one' name='name'></td>
      <td><label for='one'>example</label></td>
    </tr>
    <tr>
      <td><input type='radio' id='two' name='name'></td>
      <td><label for='two'>example</label></td>
    </tr>
    <tr>
      <td><input type='radio' id='three' name='name'></td>
      <td><label for='three'>example</label></td>
    </tr>
    <tr>
      <td><input type='checkbox' id='four' name='differentName'></td>
      <td><label for='four'>example</label></td>
    </tr>
  </tbody>
</table>

作为附录,从 OP 的评论到问题:

我尝试了nextSibling,但它不起作用,但nextSiblingElement 起作用了。

两者的区别在于nextSibling返回任何兄弟节点,无论是文本节点、元素节点还是其他节点,而nextElementSibling,顾名思义,返回也是元素的下一个兄弟节点-节点。

参考资料:

【讨论】:

  • 无论是文本节点、元素节点还是其他节点 除了TextNodeElementNode 之外还有哪些节点类型?
  • 哦,有quite a few,不过nextSibling可能会返回,我真的不知道。
【解决方案2】:

使用

inp.parentNode.nextElementSibling.querySelector('label')

而不仅仅是

inp.parentNode

Array.from(document.querySelectorAll("tr")).forEach((tr,index)=>{
  var mark=document.createElement("span");
  Array.from(tr.querySelectorAll("input")).forEach((inp,index1)=>{
    if(inp.type=="radio"){
      mark.classList.add("dotmark");
      inp.parentNode.nextElementSibling.querySelector('label').appendChild(mark);
    }
    else{
      mark.classList.add("checkmark");
      inp.parentNode.nextElementSibling.querySelector('label').appendChild(mark);
    }
  })
})
span{
width:20px;
height:20px;
background:#ccc;
display:inline-block;
}
<table id="tab1" class="table labelCustom">
   <tbody>
        <tr><td><input type='radio' id='one' name='name'></td><td><label for='one'>example</label></td></tr>
        <tr><td><input type='radio' id='two' name='name'></td><td><label for='two'>example</label></td></tr>
        <tr><td><input type='radio' id='three' name='name'></td><td><label for='three'>example</label></td></tr>
   </tbody>
</table>

【讨论】:

    【解决方案3】:

    您不需要嵌套循环,一次在 tr 上,然后在输入上,因为每个 tr 内只有一个输入和标签,因此您可以将它们组合成单个查询,如 tr input。而且,您不需要使用Array.from,因为querySelectorAll 返回的NodeList 已经具有forEach 函数。

    document.querySelectorAll('tr input').forEach(input => {
        const span = document.createElement('span')
        span.classList.add(input.type === 'radio' ? 'dotmark' : 'checkmark')
        input.parentNode.nextElementSibling.appendChild(span)
    })
    

    【讨论】:

      猜你喜欢
      • 2020-12-02
      • 2016-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多