Странное поведение при расширении шаблона и включении HTML

#w3.css

#w3.css

Вопрос:

Я играю с w3.css и хочу расширить шаблон и включить немного HTML. Пример выглядит следующим образом:

 <!DOCTYPE html>
<html>
  <title>BUG</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css"/>
<script src="http://www.w3schools.com/lib/w3data.js"></script>

<body>

  <div class="w3-container">

    <div id="id03">
      <div w3-repeat="customers">
    <p>Here: img = {{CustomerName}} text={{City}} country={{Country}}</p>
      </div>
    </div>


    <div w3-include-html="include.html"></div>

  </div>
  <script>
    w3IncludeHTML();

    var myObject = {"customers":[
      {"CustomerName":"Alfreds Futterkiste","City":"Berlin","Country":"Germany"},
      {"CustomerName":"Around the Horn","City":"London","Country":"UK"},
      {"CustomerName":"Chop-suey Chinese","City":"Bern","Country":"Switzerland"}
      ]};

      w3DisplayData("id03", myObject);

  </script>

</body>

  </html>
  

и включенный файл (include.html ) является

  <div>
   <h1>I am included</h1>
   <button class="w3-btn w3-white w3-border">Button</button>
 </div>
  

Если я закомментирую строку w3IncludeHTML, программа будет работать так, как я ожидал
, но при включении этой строки расширение будет неправильным, и файл
будет включен дважды.

И идеи, что не так?

Ответ №1:

w3IncludeHTML() выглядит следующим образом

    function w3IncludeHTML() {
       var z, i, a, file, xhttp;
       z = document.getElementsByTagName("*");
       for (i = 0; i < z.length; i  ) {
          if (z[i].getAttribute("w3-include-html")) {
                a = z[i].cloneNode(false);
                file = z[i].getAttribute("w3-include-html");
                xhttp = new XMLHttpRequest();

                xhttp.onreadystatechange = function() {

                if (this.readyState == 4 amp;amp; this.status == 200) {
                     a.removeAttribute("w3-include-html");
                     a.innerHTML = this.responseText;          
                     z[i].parentNode.replaceChild(a, z[i]);
                     w3IncludeHTML();
                 }
            }
            xhttp.open("GET", file, true);
            xhttp.send();
            return;
        }
     }
  }
  

До того, как XMLHttpRequest(XHR) получит успешный ответ, наш элемент <div w3-include-html="include.html"></div> находится в позиции i . Поскольку запросы XHR являются асинхронными, w3DisplayData("id03", myObject) выполняется перед обратным вызовом onreadystatechange .

w3DisplayData манипулирует DOM, поэтому наша позиция занята другим элементом DOM.

После получения успешного ответа XHR i снова использовался для ссылки на элемент <div w3-include-html="include.html"></div> . Из-за манипуляций с DOM i позиция th занята другим элементом, поэтому содержимое include.html становится ребенком , чтобы <div id="id03">

Повторяющаяся вставка происходит из <div w3-include-html="include.html"></div> -за вызова обратного вызова w3IncludeHTML() onreadystatechange.

Это поведение можно исправить, заменив w3IncludeHtml код следующим образом

      function w3IncludeHTML() {
         var z, i, a, file, xhttp;
         z = document.getElementsByTagName("*");
         for (i = 0; i < z.length; i  ) {
            if (z[i].getAttribute("w3-include-html")) {
                  a = z[i].cloneNode(false);
                  file = z[i].getAttribute("w3-include-html");
                  xhttp = new XMLHttpRequest();
                  nodeToReplace = z[i]
                  xhttp.onreadystatechange = function() {
                      if (this.readyState == 4 amp;amp; this.status == 200) {
                           a.removeAttribute("w3-include-html");
                           a.innerHTML = this.responseText;
                           nodeToReplace.parentNode.replaceChild(a, nodeToReplace);
                           w3IncludeHTML();
                     }
                 }
                 xhttp.open("GET", file, true);
                 xhttp.send();
                 return;
           }
     }
  }
  

Комментарии:

1. Отлично — большое вам спасибо. Я думал, что это что-то вроде этого. Интересно, как можно сообщить об ошибке в W3Schools?