Javascript内联循环通过getElementsByClassName

时间:2017-12-18 00:22:56

标签: javascript html

考虑以下简化的html代码:

<html>
    <head>
        <style>
            .opts {display: none}
        </style>
    </head>

    <body onload = "list = document.getElementsByClassName('opts')">

        <form>
            <ul>
                <li>
                    <label>Show Options?</label>
                    <input type="radio" onclick="list[0].style.display = 'block'; list[1].style.display = 'block'; list[2].style.display = 'block';">yes<br>
                    <input type="radio" onclick="list[0].style.display = 'none'; list[1].style.display = 'none'; list[2].style.display = 'none';">no<br>
                </li>

                <li class="opts">
                    <label>Option 1</label>
                    <input type="text">
                </li>

                <li class="opts">
                    <label>Option 2</label>
                    <input type="text">
                </li>

                <li class="opts">
                    <label>Option 3</label>
                    <input type="text">
                </li>

                ... etc ...

            </ul>
        </form>

    </body>

</html>

基本上,它使用javascript根据用户onclick事件显示或隐藏可选元素。

问题
目前,对于getElementsByClassName中的每个元素,都有一个行设置&#39;手动&#39;显示属性:

list[0].style.display = 'block';
list[1].style.display = 'block';
list[2].style.display = 'block';

有更简单的方法吗?例如,像:

list[All].style.display = 'block';

ps:当然这可以通过一些for loop和一个额外的函数声明来完成,但我正在寻找一个简单的内联js代码(即:没有外部的js文件)

跟进

根据评论,有两种建议的方法可以在没有外部文件的情况下轻松编码内联:

1)传播语法

[...list].forEach(el => el.style.display = 'block')

2)for loop新语法

for (const x of list) x.style.display = "block";

特别是,我决定使用for loop新语法,因为它比传播语法更容易阅读。但是,由于两种方式都是JavaScript的近期功能,因此建议谨慎使用旧版浏览器兼容性。

2 个答案:

答案 0 :(得分:1)

&#13;
&#13;
// setup for the environment
const All = Symbol("All");
const setter = {set: function(fn) {
  for (var i = 0; i < this.length; i++) {
    fn(this[i], i, this);
  }
}};
Object.defineProperty(HTMLCollection.prototype, All, setter);
Object.defineProperty(NodeList.prototype, All, setter);




// Your code
const list = document.getElementsByClassName('opts')

list[All] = x => x.style.fontWeight = "bold";
&#13;
<form>
  <ul>
    <li>
      <label>Show Options?</label>
      <input type="radio" onclick="list[0].style.display = 'block'; list[1].style.display = 'block'; list[2].style.display = 'block';">yes<br>
      <input type="radio" onclick="list[0].style.display = 'none'; list[1].style.display = 'none'; list[2].style.display = 'none';">no<br>
    </li>

    <li class="opts">
      <label>Option 1</label>
      <input type="text">
    </li>

    <li class="opts">
      <label>Option 2</label>
      <input type="text">
    </li>

    <li class="opts">
      <label>Option 3</label>
      <input type="text">
    </li>

    ... etc ...

  </ul>
</form>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

考虑切换类而不是直接设置显示值。另外,对于直接二进制选择,我只使用一个复选框。

使用 forEach 对数组进行迭代并不是很多代码,并且适应旧浏览器也很简单:

function toggleOpts() {
  var opts = Array.from(document.querySelectorAll('.opts'));
  opts.forEach(function(opt) {
    opt.style.display = this.checked ? '' : 'none';
  }, this);
}
window.onload = function() {
  document.getElementById('optToggle').addEventListener('click', toggleOpts, false);
}
<title>Sample</title>
<form>
  <ul>
    <li>
      <label for="optToggle">Show Options?
        <input type="checkbox" id="optToggle" checked>yes
      </label>
    </li>

    <li class="opts">
      <label>Option 1</label>
      <input type="text">
    </li>

    <li class="opts">
      <label>Option 2</label>
      <input type="text">
    </li>

    <li class="opts">
      <label>Option 3</label>
      <input type="text">
    </li>
  </ul>
</form>