【问题标题】:Create a DOM document from string, without JQuery从字符串创建 DOM 文档,不使用 JQuery
【发布时间】:2012-03-24 19:44:02
【问题描述】:

我们正在寻找在 JavaScript 中从字符串创建 DOM 文档 的方法,但不使用 Jquery。 有没有办法这样做? [我会这么认为,因为 Jquery 可以做到!]

对于那些好奇的人,我们不能使用 Jquery,因为我们是在 Chrome 应用程序的内容脚本的上下文中执行此操作的,而使用 Jquery 只会使我们的内容脚本过于繁重。

【问题讨论】:

    标签: javascript document


    【解决方案1】:

    DOM 元素具有属性innerHTML,允许完全更改其内容。因此,您可以创建一个容器并用新的 HTML 内容填充它。

    function createElementFromStr(htmlContent) {
      var wrapperElm = document.createElement("div");
      wrapperElm.innerHTML = htmlContent; // Ex: "<p id='example'>HTML string</p>"
      console.assert(wrapperElm.children.length == 1); //Only one child at first level.
      return wrapperElm.children[0];
    }
    

    * 我知道这是一个老问题,但我希望能帮助别人。

    【讨论】:

      【解决方案2】:
      fetch("index.html", {  // or any valid URL
          method: "get"
      }).then(function(e) {
          return e.text().then(e => {
              var t = document.implementation.createHTMLDocument("");
              t.open();
              t.write(e);
              t.close();
              return t;
          });
      }).then(e => {
          //  e will contain the document fetched and parsed.
          console.log(e);
      });
      

      【讨论】:

        【解决方案3】:

        我可以通过在 iframe 上编写 html 字符串来做到这一点

        const html = `<!DOCTYPE html>
        <html lang="en">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <meta http-equiv="X-UA-Compatible" content="ie=edge">
          <title>Document</title>
        </head>
        <body>
        
        </body>
        </html>`
        
        const iframe = document.createElement('iframe')
        iframe.contentDocument.open()
        iframe.contentDocument.write(html)
        iframe.contentDocument.close()
        iframe.addEventListener('load', () => {
          myDocumentObject = iframe.contentDocument
        })
        

        【讨论】:

          【解决方案4】:

          我在这里尝试了其他一些方法,但是在创建脚本元素时出现问题,例如 Chrome 拒绝加载 src 属性指向的实际 .js 文件。以下是最适合我的。

          它比 jQuery 快 3 倍,比使用 DOMParser 快 3.5 倍,但比以编程方式创建元素慢 2 倍。
          https://www.measurethat.net/Benchmarks/Show/2149/0

          Object.defineProperty(HTMLElement, 'From', { 
              enumerable: false,
              value: (function (document) {
                  //https://www.measurethat.net/Benchmarks/Show/2149/0/element-creation-speed
                  var rgx = /(\S+)=(["'])(.*?)(?:\2)|(\w+)/g;
                  return function CreateElementFromHTML(html) {
                      html = html.trim();
                      var bodystart = html.indexOf('>') + 1, bodyend = html.lastIndexOf('<');
                      var elemStart = html.substr(0, bodystart);
                      var innerHTML = html.substr(bodystart, bodyend - bodystart);
                      rgx.lastIndex = 0;
                      var elem = document.createElement(rgx.exec(elemStart)[4]);
                      var match; while ((match = rgx.exec(elemStart))) {
                          if (match[1] === undefined) {
                              elem.setAttribute(match[4], "");
                          } else {
                              elem.setAttribute(match[1], match[3]);
                          }
                      }
                      elem.innerHTML = innerHTML;
                      return elem;
                  };
              }(window.document))
          });
          

          用法示例:

          HTMLElement.From(`<div id='elem with quotes' title='Here is "double quotes" in single quotes' data-alt="Here is 'single quotes' in double quotes"><span /></div>`);
          HTMLElement.From(`<link id="reddit_css" type="text/css" rel="stylesheet" async href="https://localhost/.js/sites/reddit/zinject.reddit.css">`);
          HTMLElement.From(`<script id="reddit_js" type="text/javascript" async defer src="https://localhost/.js/sites/reddit/zinject.reddit.js"></script>`);
          HTMLElement.From(`<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">`);
          HTMLElement.From(`<div id='Sidebar' class='sidebar' display=""><div class='sb-handle'></div><div class='sb-track'></div></div>`);
          

          【讨论】:

            【解决方案5】:

            https://developer.mozilla.org/en-US/docs/Web/API/DOMParser

            var parser = new DOMParser();
            var doc = parser.parseFromString("<html_string>", "text/html");
            

            (生成的doc 变量是一个documentFragment 对象)。

            【讨论】:

              【解决方案6】:

              如果您仍在寻找答案,并且其他任何人遇到它,我只是一直在尝试自己做同样的事情。看来您想查看 javascript 的 DOMImplementation:

              http://reference.sitepoint.com/javascript/DOMImplementation

              这里也很少提到兼容性,但它得到了很好的支持。

              本质上,要创建要操作的新文档,您需要创建一个新的 Doctype 对象(如果您要输出一些基于标准的东西),然后使用新创建的 Doctype 变量创建新的 Document。

              在文档类型和文档中都有多个选项,但如果您正在创建 HTML5 文档,您似乎希望将其中大部分保留为空白字符串。

              示例(新的 HTML5 DOM 文档):

              var doctype = document.implementation.createDocumentType( 'html', '', '');
              
              var dom = document.implementation.createDocument('', 'html', doctype);
              

              新文档现在看起来像这样:

              <!DOCTYPE html>
              <html>
              </html>
              

              示例(新的 XHTML DOM 文档):

              var doctype = document.implementation.createDocumentType(
                  'html',
                  '-//W3C//DTD XHTML 1.0 Strict//EN',
                  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
              );
              
              var dom = document.implementation.createDocument(
                  'http://www.w3.org/1999/xhtml',
                  'html',
                  doctype
              );
              

              因此,其余部分由您决定。你可以像改变一样简单地做到这一点

              dom.documentElement.innerHTML = '<head></head><body></body>';
              

              或者选择更严格的:

              var head = dom.createElement( 'head' );
              var body = dom.createElement( 'body' );
              dom.documentElement.appendChild(head);
              dom.documentElement.appendChild(body);
              

              都是你的。

              【讨论】:

              • 经过数小时的 JS + Adob​​e AIR 吃掉我的 &lt;head&gt; 标签和 document.implementation.createHTMLDocument,这解决了我的问题!非常感谢!!
              • 我的 document.body 为空。但是使用 createHTMLDocument 没有 head 标签。 :(
              【解决方案7】:

              createDocumentFragment 可以帮到你。

              https://developer.mozilla.org/En/DOM/DocumentFragment

              浏览器总是自己创建带有空白页面的文档(关于:空白)。 或许,Chrome 应用程序中有一些可用的功能(如 FF 中的 XUL),但在普通的 javascript 中没有这样的功能。

              【讨论】:

              • 所以这看起来很有希望,但不幸的是,无法从字符串中填充 DocumentFragment,这不符合我的需要:(
              【解决方案8】:

              HTML 会这样:

              <html>
              <head></head>
              <body>
                  <div id="toolbar_wrapper"></div>
              </body>
              </html>
              

              JS 看起来像这样:

              var data = '<div class="toolbar">'+
                              '<button type="button" class="new">New</button>'+
                              '<button type="button" class="upload">Upload</button>'+
                              '<button type="button" class="undo disabled">Undo</button>'+
                              '<button type="button" class="redo disabled">Redo</button>'+
                              '<button type="button" class="save disabled">Save</button>'+
                          '</div>';
              document.getElementById("toolbar_wrapper").innerHTML = data;
              

              【讨论】:

                【解决方案9】:
                var dom = '<html><head>....</head><body>...</body></html>';
                
                document.write(dom);
                document.close();
                

                【讨论】:

                • 这不会覆盖文档的当前内容吗?
                • 不,我只是希望能够创建一个新文档并对其进行操作,但肯定不会摆脱以前的:(
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-12-09
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多