如何使用Javascript动态更改元素列表的背景?

时间:2018-10-20 17:48:26

标签: javascript html colors

我有一个如下所示的html列表:

<nav id="PageNav">
    <div id="TimeContainer">
        <ul id="TimeList">
            <li>
                <button id="welcome_button" onclick="setWelcome()">
                    <span>Home<span></span>
                </button>
            </li>

            <li>
                <button id="resume_button" onclick="setResume()">
                    <span>Resume<span>
                </button></li>
        </ul>
    </div>

    <script src="static/scripts/page_change.js"></script>

</nav>

当用户单击一个按钮时,我需要调用一个脚本并将这些元素的背景设置为不同的颜色。我正在尝试如下操作:

function setResume() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("MainText").innerHTML =
      this.responseText;

      document.getElementById("resume_button").style.backgroundColor =
        "rgba(25, 129, 190, 0.7)";

      var button_list = document.getElementById("TimeList").getElementsByTagName("li").innerHTML;

      for(element in button_list){
        element.style.backgroundColor = "black";
      }
    }
  };
  xhttp.open("GET", "static/resume.txt", true);
  xhttp.send();
}

但是,这什么都不做,甚至控制台错误也没有。

2 个答案:

答案 0 :(得分:0)

我试图解决此问题的方法是错误的。这似乎是正确的方法:

  var x = document.getElementsByTagName("button");
  var i;
  for (i = 0; i < x.length; i++) {
      x[i].style.backgroundColor = " rgba(0,0,0,0.6)";
  }

答案 1 :(得分:0)

通过JavaScript将RGB / RGBA值设置为字符串可能会出现问题,因为某些系统对字符串中的空格非常挑剔,这就是您遇到的问题。

"rgba(0,0,0,.5)"     // Usually won't work
"rgba(0, 0, 0, .5)"  // Usually will but may require a leading space as well

现在,作为一般规则,您应该首先避免设置内联样式,因为它们更难以阅读/调试,更重要的是,它们会导致代码重复且难以覆盖。取而代之的是,用一块石头杀死两只鸟的解决方案是提前设置CSS类,然后根据需要使用element.classList通过JavaScript添加/删除该类。

function setResume() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("MainText").innerHTML =
      this.responseText;

      // Just apply the appropriate, already declared class
      document.getElementById("resume_button").classList.add("responseStyle");

      var button_list = document.getElementById("TimeList").getElementsByTagName("li").innerHTML;

      for(element in button_list){
        // Again, add/remove classes rather than configuring inline styles with strings:
        element.classList.add("black");
      }
    }
  };
  xhttp.open("GET", "static/resume.txt", true);
  xhttp.send();
}
.responseStyle { background-color:rgba(25, 129, 190, 0.7); }
.buttonListStyle { background-color:black; }
<nav id="PageNav">
    <div id="TimeContainer">
        <ul id="TimeList">
            <li>
                <button id="welcome_button" onclick="setWelcome()">
                    <span>Home<span></span>
                </button>
            </li>

            <li>
                <button id="resume_button" onclick="setResume()">
                    <span>Resume<span>
                </button></li>
        </ul>
    </div>

    <script src="static/scripts/page_change.js"></script>

</nav>

注释:

1)此行:

var button_list = document.getElementById("TimeList").getElementsByTagName("li").innerHTML;

有一些问题。首先,getElementsByTagName()返回一个节点列表,因此它首先没有.innerHTML属性,只有元素会。而且,即使它确实有.innerHTML,也将返回一个字符串,因此,尝试通过button_list循环遍历for/in实际上不会遍历任何HTML元素,它将循环超过该字符串中的字符。

这是您应该执行的操作:

document.getElementById("yourWay").addEventListener("click", yourWay);
document.getElementById("correctWay").addEventListener("click", correctWay);

function yourWay() {
  var button_list = document.getElementById("TimeList").getElementsByTagName("li").innerHTML;

  // This attempts to loop over the string returned by .innerHTML, not the child elements and
  // because you are using a for/in loop, nothing happens because for/in is for looping over objects.
  for(element in button_list){
     element.style.backgroundColor = "black";
     console.log(element);
  }
}


function correctWay() {
  // .getElementsByTagName() returns a "live" node list and has performance implications.
  // Instead, use .querySelectorAll() for better performance.
  
  // If we want to use the .forEach method of an Array, we have to convert the node list
  // returned by .querySelectorAll() to an array for best browser compatibility.
  var button_list = Array.prototype.slice.call(document.getElementById("TimeList").querySelectorAll("li"));

  button_list.forEach(function(el){
     el.style.backgroundColor = "yellow";
  });
}
<nav id="PageNav">
    <div id="TimeContainer">
        <ul id="TimeList">
            <li>Home</li>
            <li>Resume</li>
        </ul>
    </div>
</nav>

<input type="button" id="yourWay" value="Your Way">
<input type="button" id="correctWay" value="Correct Way">

2)JavaScript中的for/in循环意在迭代对象的属性(其中包括其继承的属性以及“自己的”属性)。要枚举数组或类似数组的对象,请使用计数循环或.forEach()