Как я могу написать HTML-код в своем теге script?

Я изо всех сил пытаюсь записать определенные части моего html-кода в свой файл в середине моего тега сценария.

У меня есть document.Write в настоящее время, но он не проходит через мой валидатор, и мне нужно решение, которое бы это сделало. Я пытался создать текстовый узел и добавить его, а также innerHTML, но, похоже, ни один из них не работает, какая-нибудь помощь?

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<!-- 
   New Perspectives on JavaScript, 2nd Edition
   Tutorial 3
   Case Problem 2

   Congressional Election Results
   Author: 
   Date:   

   Filename:         election.htm
   Supporting files: back.jpg, logo.jpg, results.css, votes.js

-->
   <head>
   <title>Congressional Races</title>
   <link href="results.css" rel="stylesheet" type="text/css" />
   <script src="votes.js" type="text/javascript"></script>
   <script src="barchart.js" type="text/javascript"></script>

   <script>
      function totalVotes(votes) {
         var total=0;
         for (var i=0; i<votes.length; i++) total+=votes[i];
         return total;
      }
      function calcPercent(item, sum) {
         return Math.round(100*item/sum);
      }

      function createBar(partyType, percent) {
         switch (partyType) {
            case "D": barText="<td class='dem'> </td>";break;
            case "R": barText="<td class='rep'> </td>";break;
            case "I": barText="<td class='ind'> </td>";break;
            case "G": barText="<td class='green'> </td>";break;
            case "L": barText="<td class='lib'> </td>";break;
         }

         for (var j=1; j <= percent; j++) document.write(barText);
      }

      function showResults(race, name, party, votes) {

         var totalV=totalVotes(votes);

         document.write("<h2>"+race+"</h2>");
         document.write("<table>");
         document.write("<tr><th>Candidate</th><th class='num'>Votes</th><th class='num'>%</th></tr>");

         for (var i=0; i < name.length; i++) {
            document.write("<tr>");
            document.write("<td>"+name[i]+" ("+party[i]+")</td>");
            document.write("<td class='num'>"+votes[i]+"</td>");

            var percent = calcPercent(votes[i],totalV);
            document.write("<td class='num'>("+percent+"%)</td>");
            createBar(party[i], percent);
            document.write("</tr>");
         }

         document.write("</table>");
      }
   </script>
</head>

<body>

   <div id="intro">
      <p><img src="logo.jpg" alt="Election Day Results" /></p>
      <a href="#">Election Home Page</a>
      <a href="#">President</a>
      <a href="#">Senate Races</a>
      <a href="#">Congressional Races</a>
      <a href="#">State Senate</a>
      <a href="#">State House</a>
      <a href="#">Local Races</a>
      <a href="#">Judicial</a>
      <a href="#">Referendums</a>
   </div>

   <div id="results">
      <h1>Congressional Races</h1>
      <script type="text/javascript">
            showResults(race[0],name1,party1,votes1);
            showResults(race[1],name2,party2,votes2);
            showResults(race[2],name3,party3,votes3);
            showResults(race[3],name4,party4,votes4);
            showResults(race[4],name5,party5,votes5);
         </script>

   </div>

</body>
</html>

person uhhuh    schedule 03.09.2019    source источник
comment
Примечание. Журналу New Perspectives on JavaScript, 2-е издание исполнилось 10 лет. Вам лучше найти более современный ресурс, так как за эти 10 лет javascript сильно изменился.   -  person Jon P    schedule 04.09.2019
comment
Вы говорите, что innerHTML [не] работает, можете ли вы уточнить? Это очень расплывчатое описание проблемы.   -  person Mr Lister    schedule 04.09.2019


Ответы (3)


Я бы посоветовал вам не использовать document.write, так как каждый последующий document.write перезаписывает предыдущий. Вместо этого я предлагаю вам изучить литералы шаблонов: https://www.youtube.com/watch?v=NgF9-pdTDGs и document.body.innerHTML.

const variableExample = 'Heading content';
document.body.innerHTML = `
<div>
  <h1>${variableExample}</h1>
  <p>I am some content!!</p>
</div>
`;
person Devin Olsen    schedule 04.09.2019

Вы сказали синтаксическому анализатору: «Это XML-документ, в частности тот, который следует правилам XHTML; пожалуйста, относитесь к нему как к таковому», включив шаблон в верхней части документа:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

Но затем вы переключаетесь на совершенно другой язык, который не является допустимым XML:

<script>
  function totalVotes(votes) {
    var total=0;
    for (var i=0; i<votes.length; i++) total+=votes[i];

Синтаксический анализатор XML гудит (заметив, что вам не хватает обязательного атрибута type в теге <script>), пока не увидит i<votes.length;. Он думает, что <votes.length — это начало тега, сильно путается и начинает выбрасывать ошибки направо и налево. Чтобы сказать синтаксическому анализатору «просто игнорируйте эту часть, это не для вас», добавьте Теги CDATA (и закомментируйте их, если ваша страница будет отображаться как HTML вместо XHTML):

<script type="text/javascript">
  /*<![CDATA[*/
  function totalVotes(votes) {
    var total=0;
    for (var i=0; i<votes.length; i++) total+=votes[i];
    return total;
  }
  /*]]>*/
</script>

(Это подтвердится, но не сработает, потому что document.write не работает в XML из соображений соответствия< /a> Это нормально, потому что вам действительно не следует использовать document.write для начала. Просто используйте свое решение innerHTML.)


Лучший способ

Работа с XML и XHTML — это головная боль, и если вам это особо не нужно (чего у вас нет), вам лучше использовать современный HTML5. Шаблон становится намного короче:

<!doctype html>

<html>

Вот и все. Без DTD, без пространств имен, без CDATA. Это просто работает.

person AuxTaco    schedule 04.09.2019
comment
Обратите внимание, что только изменение объявления doctype не превращает HTML-файл в XML-файл или наоборот. Это может изменить только тип файла (тип MIME). Теперь проблемы валидатора, с которыми сталкивается OP, заключаются в том, что валидатор не видит тип MIME, а только контент (из которого он делает вывод, что он должен быть XML). - person Mr Lister; 04.09.2019
comment
@MrLister Если вы можете отредактировать это, чтобы оно было более технически правильным, сделайте это. Я отказался от попыток разобраться в этом семь лет назад, и погрузиться в него было... менее чем приятно. - person AuxTaco; 04.09.2019
comment
Что ж, все правильно вы сказали, за исключением того, что немного о парсере происходит только на стороне валидатора W3C. Браузеры будут воспринимать его как HTML (я в этом почти уверен, иначе он бы ничего не отображал!), и у них не было бы проблем с document.write, который устарел, но все еще находится в рабочем состоянии, но основной OP проблема заключается в том, чтобы обойти валидатор, и для этого ваше решение работает. - person Mr Lister; 04.09.2019

Если вы не пишете полноценный веб-компонент javascript, сохраняйте свой HTML как HTML. Когда вы хотите изменить макет, проще работать с HTML в редакторе HTML, когда он не скрыт в javascript.

Я буду использовать элемент <template>. Обратите внимание, что если вам нужна поддержка IE, вам нужно будет использовать polyfill или <script type="text/template>, что требует небольшой дополнительной работы.

function showResults(race, name, party, votes) {
  //Clone the template
  var clone = document.importNode(document.getElementById("templateRace").content, true);
  //To update the clone we need to move it to a temporary item
  var holder = document.createElement('div');
  holder.appendChild(clone);
  //replace the simple data
  holder.innerHTML = holder.innerHTML
    .replace(/{{race}}/g, race);  
  var totalVotes = votes.reduce(function(acc, curr) {
    return acc + curr
  });
  
  //Add Rows
  for (var i = 0; i < name.length; i++) {
    //Clone the row template
    var rowClone = document.importNode(document.getElementById("templateRow").content, true);
    var percent = 100 * votes[i]/totalVotes;
    var partyClasses = {
      "D": "dem",
      "R": "rep",
      "I": "ind",
      "G": "green",
      "L": "lib"
    }
    //To update the clone we need to move it to a temporary item
    var rowHolder = document.createElement('tbody');
    
    rowHolder.appendChild(rowClone);
    //replace the simple data
    rowHolder.innerHTML = rowHolder.innerHTML
      .replace(/{{name}}/g, name[i])
      .replace(/{{party}}/g, party[i])
      .replace(/{{votes}}/g, votes[i])
      .replace(/{{percent}}/g, percent)
      .replace(/{{percWidth}}/g, parseInt(percent * 2, 10))
      .replace(/{{partyClass}}/g, partyClasses[party[i]]);
      
      //Add the row to the tbody
      holder.querySelector("tbody").appendChild(rowHolder.querySelector("tr"));
  }

  //Add the full details
  document.getElementById("res").appendChild(holder.querySelector("section"));
  
}


showResults("Race 1", ["Bill", "Ben", "Brian", "Betty"], ["D", "R", "I", "G"], [15, 25, 10, 50]);
//showResults(race[0],name1,party1,votes1);
/*showResults(race[1],name2,party2,votes2);
showResults(race[2],name3,party3,votes3);
showResults(race[3],name4,party4,votes4);
showResults(race[4],name5,party5,votes5);*/
.dem {background-color: red;}
.rep {background-color: blue;}
.ind {background-color: yellow;}
.green {background-color: green;}
.lib {background-color: black;}
.party {display:inline-block;}
<body>

  <div id="intro">
    <p><img src="logo.jpg" alt="Election Day Results" /></p>
    <a href="#">Election Home Page</a>
    <a href="#">President</a>
    <a href="#">Senate Races</a>
    <a href="#">Congressional Races</a>
    <a href="#">State Senate</a>
    <a href="#">State House</a>
    <a href="#">Local Races</a>
    <a href="#">Judicial</a>
    <a href="#">Referendums</a>
  </div>

  <div id="results">
    <h1>Congressional Races</h1>
    <div id="res">
    </div>

    <template id="templateRace">
        <section>
        <h2>{{race}}</h2>
        <table>
          <thead>
            <tr>
            <th>Candidate</th><th class='num'>Votes</th><th class='num'>%</th>
            </tr>
          </thead>
          <tbody>            
          </tbody>
        </table>
        </section>
      </template>
    <template id="templateRow">      
        <tr>
          <td>{{name}} ({{party}})</td>
          <td class="num">{{votes}}</td>
          <td class="num">{{percent}}</td>
          <td class="party {{partyClass}}"><div style="width:{{percWidth}}px; height:100%"> </div> </td>
        </tr>
      </template>


  </div>

person Jon P    schedule 04.09.2019