【问题标题】:Convert DOM to HTML via JavaScript?通过 JavaScript 将 DOM 转换为 HTML?
【发布时间】:2016-11-12 00:32:58
【问题描述】:

好的,我已经知道我可以使用以下方法获取整个 HTML 文档的标记(减去 DOCTYPE):

document.documentElement.outerHTML

但是,这只会让我得到原始源标记,而不是 DOM 的当前状态,而这正是我正在寻找的。对于我的即时需求,我真的只想在文档中保留表单的状态(将其视为自动保存)。

  • 请注意,这不是用于标准网站/webapp 格式的,因此不能进行发布、提交等操作。我需要一种纯 JavaScript 方式来获取当前 DOM 树的 HTML 字符串表示,因此外部调用者可以将其保存到磁盘以供以后使用。

现在我知道我可以手动遍历所有表单元素,获取每个值,并对上述 outerHTML 的结果进行字符串替换(通过正则表达式),以构建反映当前 DOM 的 HTML 字符串,但我希望有一种更简单的方法来做到这一点(也许是内置的)。就像一个 DOM 到 HTML 解析器/编写器。

但是到目前为止,我还没有找到一种内置的方法来做到这一点。只是想伸出手,看看是否有其他人需要这样做。并在我开始实施之前询问我上面提出的方法是否是解决这个特定问题的最佳方法。

【问题讨论】:

  • Afaik,你错了,调用 outerHTMLinnerHTML 确实在调用时得到了标记原样,而不是原始来源。但是,它并没有为您提供属性,无论如何您都不需要这样做。
  • [...]however that will only get me the original source markup, and not the current state of the DOM[...] 这不是真的,outerHTML 将返回当前源标记。您的问题是表单元素持有的当前值作为属性存储在 html 元素中,而不是作为属性。并且只有属性是 html 代码的一部分。
  • 好的,是的,我弄错了(它只是在我正在使用的示例中出现)。所以我应该可以用JS来更新DOM,在必要的地方添加合适的value属性(基于value属性),然后用outerHTML把文档作为字符串获取。让我试一试。
  • 这里的要点是,不应该有任何理由存储页面的整个 HTML 来记住某些状态。将表单序列化为有用的格式,例如对象。

标签: javascript html dom


【解决方案1】:

这是一个示例 HTML 页面,我在其中尝试了提供的函数:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <script type="text/javascript">

      function getFormState() {
        // this could be set outside this function if calling multiple times
        var theForm = document.forms[0];
        console.log(theForm);
        
        var theData = new FormData(theForm);
        console.log(theData);
        
        // get the state of the form as an iterator of key/value pairs
        var state = theData.entries();
        console.log(state);
        
        // convert the iterator into an array of key/value pairs
        var stateArray = Array.from(state);
        console.log(stateArray);
        
        // Use JSON.stringify to change the key/value pair array state into a string
        var stateString = JSON.stringify(stateArray);
        console.log(stateString);
        
        return stateString;
      }
         
    </script>
    <style>

      #header {
          background: #ffffff;
          position: fixed;
          width: 100%;
          height: 30px;
          padding: 5px 0px 0px 0px;
          top: 0;
          z-index: 1;
      }
      
      #content{ 
          margin-top: 40px;
      }

      body, input, select, textarea  {
        font-family: monospace;
        font-size: 10pt;
        font-weight: bold;
      }

      td {
        padding: 8px 8px 8px 8px;
      }

      input:not([type="button"]):not([type="checkbox"]):not([type="color"]):not([type="file"]):not([type="image"]):not([type="radio"]):not([type="range"]):not([type="reset"]):not([type="submit"]), select, textarea {
        -webkit-transition: all 0.30s ease-in-out;
        -moz-transition: all 0.30s ease-in-out;
        -ms-transition: all 0.30s ease-in-out;
        -o-transition: all 0.30s ease-in-out;
        outline: none;
        padding: 3px 0px 3px 3px;
        margin: 5px 1px 3px 0px;
        border: 1px solid #DDDDDD;
      }

      input:not([type="button"]):not([type="checkbox"]):not([type="color"]):not([type="file"]):not([type="image"]):not([type="radio"]):not([type="range"]):not([type="reset"]):not([type="submit"]):focus, select:focus, textarea:focus {
        box-shadow: 0 0 5px rgba(81, 203, 238, 1);
        padding: 3px 0px 3px 3px;
        margin: 5px 1px 3px 0px;
        border: 1px solid rgba(81, 203, 238, 1);
      }
      
    </style>
    <title>HTML5 FormData Test</title>
  </head>
  <body>
    <form id="frmForm">
      <div id="header">
        <button type="button" onclick="getFormState()">getFormState</button>
        <hr>
      </div>
      <div id="content">
        <table border="1">
          <tr>
            <td>Button</td>
            <td><input id="btnButton" type="button" value="Button"></td>
          </tr>
          <tr>
            <td>Checkbox</td>
            <td><input id="chkCheckbox" type="checkbox"></td>
          </tr>
          <tr>
            <td>Color</td>
            <td><input id="clrColor" type="color" value="#000000"></td>
          </tr>
          <tr>
            <td>Datalist</td>
            <td>
              <input id="txtDatalist" type="text" list="choices" value="">
              <datalist id="choices">
                <option value="One"></option>
                <option value="Two"></option>
                <option value="Three"></option>
              </datalist>
            </td>
          </tr>
          <tr>
            <td>Date</td>
            <td><input id="calDate" type="date" value=""></td>
          </tr>
          <tr>
            <td>Datetime (Deprecated)</td>
            <td><input id="calDateTime" type="datetime" value=""></td>
          </tr>
          <tr>
            <td>Datetime (Local)</td>
            <td><input id="calDateTimeLocal" type="datetime-local" value=""></td>
          </tr>
          <tr>
            <td>Disabled</td>
            <td><input id="txtDisabled" type="text" value="Disabled" disabled=""></td>
          </tr>
          <tr>
            <td>E-Mail</td>
            <td><input id="txtEMail" type="email" value=""></td>
          </tr>
          <tr>
            <td>File</td>
            <td><input id="binFile" type="file" value=""></td>
          </tr>
          <tr>
            <td>Hidden</td>
            <td><input id="txtHidden" type="hidden" value="HIDDEN"></td>
          </tr>
          <tr>
            <td>Image (Submit)</td>
            <td><input id="btnImage" type="image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADUAAAAVCAIAAABpKDERAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAJcSURBVEhLzZVNTxpBGMcHvkEjbZFkT3BoUmNSsSc/QXdBLL23IRyQmkhjzNbGO4nUbUwQ15geeiC9QDct3V3itSdE7YuSniBRGynQ8BXcPs/s4HLYAk2q3d+Bed7zn5md4KpUKo1GgzgSv9/vyufz0WiUBRyGoihuw9mgvgunwvQ5GTdcMzOdB2hzs6N0KgPOr7p+o5/HhXOWuDbw/Jhpw/RSt9vdXYWi1V2w3jwaZ4nrZOj7xU1YFVVpLCZJsTFAeinhEiu0MLFHHcaTIo0BUN8PK24V6ASKtEcLbWH6BkGovstPAMxS2kh29Ock/Z2rfZWF0ukpJqafdRi1bUFNiEX8GPZfPUgL2zUzSMgL/XX0JkTX784TGaOdmjyb5uPFNk6w5y/PD92VmXt0vcN58BM5OjnHROtd7BZlYl7DFtpjNVtW9dMaIaXkBK1NlnqldjB9A4G5OKJHz7uMmr8HG5NJbUX9CXzb4nsNwRmRaMlJr9dLs6kgjWKr+BFLTXYewqH+iaH66Mb7AA98vHa6IobRPjsihOfwAR28faqbQaOpyBk+d9g0WZyi/QbHhQnJyErTdIcw4H73N3w+Xxgug6yFwYorcI9UHybZikph9cwmRKIvBKFsi9sUUR0kb0cSy2bQhE648ETkL5shKx5X2jjQDtDmkmU5FArhjv85n7Nc5Dhb3ZkbB+cwy81llt//SAXN5CioqnqF/2+ds2NreLPfGRXocOVyOUGAx38V/PqwcD+Fr5mypJwsTjF7NDRNQ308Dy/Oiei6Pvz9/l9c5XK5Xq8zwQ4jEAj8BmbeP4OPzU0kAAAAAElFTkSuQmCC"></td>
          </tr>
          <tr>
            <td>Month</td>
            <td><input id="calMonth" type="month" value=""></td>
          </tr>
          <tr>
            <td>Number</td>
            <td><input id="numNumber" type="number" min="0" max="10" step="1" required="" value=""></td>
          </tr>
          <tr>
            <td>Password</td>
            <td><input id="txtPassword" type="password" value=""></td>
          </tr>
          <tr>
            <td>Radio</td>
            <td>
              <input id="radRadio1" type="radio" name="radRadio" value="1">One<br>
              <input id="radRadio2" type="radio" name="radRadio" value="2">Two<br>
              <input id="radRadio3" type="radio" name="radRadio" value="3">Three
            </td>
          </tr>
          <tr>
            <td>Range</td>
            <td><input id="numRange" type="range" min="0" max="10" value="5"></td>
          </tr>
          <tr>
            <td>Readonly</td>
            <td><input id="txtReadonly" type="text" value="Readonly" readonly=""></td>
          </tr>          
          <tr>
            <td>Reset</td>
            <td><input id="btnReset" type="reset"></td>
          </tr>
          <tr>
            <td>Search</td>
            <td><input id="txtSearch" type="search" placeholder="search text" value=""></td>
          </tr>
          <tr>
            <td>Select</td>
            <td>
              <select id="sltSelect">
                <option value="" disabled="" selected="">&lt;Select&gt;</option>
                <option value="1">One</option>
                <option value="2">Two</option>
                <option value="3">Three</option>
              </select>
            </td>
          </tr>
          <tr>
            <td>Select (Multiple)</td>
            <td>
              <select id="sltMultiSelect" multiple="">
                <option value="1">One</option>
                <option value="2">Two</option>
                <option value="3">Three</option>
              </select>
            </td>
          </tr>
          <tr>
            <td>Submit</td>
            <td><input id="btnSubmit" type="submit"></td>
          </tr>
          <tr>
            <td>Telephone</td>
            <td><input id="txtTelephone" type="tel" value=""></td>
          </tr>
          <tr>
            <td>Textbox</td>
            <td><input id="txtTextbox" type="text" value=""></td>
          </tr>
          <tr>
            <td>Textarea</td>
            <td><textarea id="txtTextarea"></textarea></td>
          </tr>
          <tr>
            <td>Time</td>
            <td><input id="calTime" type="time" value=""></td>
          </tr>
          <tr>
            <td>URL</td>
            <td><input id="txtURL" type="url" value=""></td>
          </tr>
          <tr>
            <td>Week</td>
            <td><input id="calWeek" type="week" value=""></td>
          </tr>
        </table>
      </div>
    </form>
  </body>
</html>

返回以下内容:

我能够手动迭代所有输入以获得我需要的东西,事实上这是我当前的解决方案,但 FormData 解决方案似乎是一种更简洁的方法,它只是没有返回预期的数据。

事实上,唯一似乎填充的输入是 RadioButton。

【讨论】:

  • 啊啊啊……这是因为输入元素没有名字!此 HTML 文档在本机应用程序的 Web 视图中与互操作语言一起使用(因此我不需要名称,因为它们不需要提交)。只要存在名称属性,FormData 似乎就可以工作。
猜你喜欢
  • 2012-04-12
  • 2011-01-12
  • 2019-02-24
  • 1970-01-01
  • 2014-10-11
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 2011-12-21
相关资源
最近更新 更多