Как использовать Javascript для динамического изменения фона списка элементов? - PullRequest
0 голосов
/ 20 октября 2018

У меня есть список 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 голосов
/ 20 октября 2018

Установка значений RGB / RGBA в виде строк с помощью JavaScript может быть проблематичной, поскольку некоторые системы очень разборчивы в отношении места в строке, и это проблема, с которой вы столкнулись.

"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 и просто добавить / удалить этот класс с помощью JavaScript по мере необходимости, используя element.classList.

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) Цикл for/in в JavaScript предназначен для итерации свойств объекта (который будет включать его унаследованные свойства, а также его «собственные» свойства),Для перечисления массива или объекта, подобного массиву, используйте счетный цикл или .forEach().

0 голосов
/ 20 октября 2018

То, как я пытался это решить, неверно.кажется, это правильный способ сделать это:

  var x = document.getElementsByTagName("button");
  var i;
  for (i = 0; i < x.length; i++) {
      x[i].style.backgroundColor = " rgba(0,0,0,0.6)";
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...