【问题标题】:Dynamically creating HTML elements using Javascript?使用 Javascript 动态创建 HTML 元素?
【发布时间】:2011-07-29 00:57:27
【问题描述】:

我想动态创建一些 HTML 元素(3 个 html 元素),然后将此 html 代码作为字符串返回到变量中。我不想将以下函数中的 HTML 代码写入某个 div,但是,我想将其返回为 var。

function createMyElements(id1,id2,id3){

   //create anchor with id1
   //create div with id 2
   //create xyz with id3

  //now return the html code of above created just now

}

我该怎么做?

【问题讨论】:

标签: javascript html dom


【解决方案1】:

[编辑 2021/10] 这个答案现在 > 10 年了。这是一个包含多种创建和/或注入元素的方法的 sn-p。问题的答案(创建一些元素并检索它们的 html 代码)可以在 sn-p 的底部找到。

// The classic createElement
// -------------------------
// create a paragraph element using document.createElement
const elem = document.createElement(`p`);
elem.id = `myBrandnewDiv1`;

// put in some text
elem.appendChild(document.createTextNode(`My brand new div #1`));

// append some html (for demo, preferrably don't use innerHTML)
elem.innerHTML += ` => created using 
  <code>document.createElement</code>`;

// append a new paragraph within #myBrandNewDiv1
const nested = elem.appendChild(document.createElement(`p`));
nested.classList.add(`nested`);
// add some text to that
nested.textContent = `I am nested!`;
// the elements are still in memory, now add the 
// whole enchillada to the document
document.body.appendChild(elem);

// insertAdjacentHTML
// ------------------
// nest an element within the nested div
nested.insertAdjacentHTML(`afterbegin`, 
  `<div id="nestedWithin#nested">
    This text will appear <i>above</i> the text of 
    my parent, that being div#nested.
    Someone had the nerve to insert me using 
    <code>insertAdjacentHTML</code>
   </div>`);

// Object.assign
// -------------
// Use Object.assign to create an element and
// assign properties/html to it in one go
const newElem = Object.assign(
  document.createElement(`div`), 
  { id: `myBrandnewDiv2`, 
    innerHTML: `div#myBrandnewDiv2 signing in. 
      I was <i>assigned</i> using <code>Object.assign</code>&hellip;`});
document.body.appendChild(newElem);

// insertAdjacentElement combined with Object.assign
// -------------------------------------------------
// use the above technique combined with insertAdjacentElement
newElem.insertAdjacentElement(
  `beforeend`,
    Object.assign(document.createElement(`span`), 
      { id: `myBrandnewnested2_nested`, 
        innerHTML: `<br>Me too! And appended I was 
          with <code>insertAdjacentElement</code>` })
);

// createDocumentFragment
// ----------------------
// Use a document fragment to create/inject html
const fragment = document.createDocumentFragment();
const mdnLnk = `https://developer.mozilla.org/en-US/` +
    `docs/Web/API/Document/createDocumentFragment`;
fragment.appendChild(
  Object.assign(
    document.createElement(`p`), 
    {innerHTML: `Regards from <code>createDocumentFragment</code> 
    (see <a href="${mdnLnk}">MDN</a>)`})
);
document.querySelector(`#myBrandnewDiv2`).appendChild(fragment);

// Create, but don't inject
// ------------------------
const virtual = Object.assign(
      document.createElement(`p`), 
      { innerHTML: `       
        <a href="#id1">id1</a>
        <div id="id2">Hi!</div>
        <p id="id3">Hi 2!</p>`,
        classList: [`xyz`], } );

const prepareHtml4Reporting = html => 
  html.replace(/</g, `&lt;`)
    .replace(/\n\s+/g, `\n`)
    .replace(/\n\n/g, `\n`);
    
document.body.insertAdjacentHTML(
  `beforeend`,
  `<h3>html only</h3><pre>${
     prepareHtml4Reporting(virtual.innerHTML)}</pre>`);
body {
  font: normal 12px/15px verdana, arial, sans-serif;
  margin: 2rem;
}

code {
  background-color: #eee;
}

.nested {
  margin-left: 0.7rem;
  max-width: 450px;
  padding: 5px;
  border: 1px solid #ccc;
}

我在这个library(参见/src/DOM.js)中使用了其中的一些方法,以及在注入之前对html 进行清理的机制。

【讨论】:

    【解决方案2】:

    HTML:

    <div id="main"></div>
    

    JavaScript:

    var tree = document.createDocumentFragment();
    var link = document.createElement("a");
    link.setAttribute("id", "id1");
    link.setAttribute("href", "http://site.com");
    link.appendChild(document.createTextNode("linkText"));
    
    var div = document.createElement("div");
    div.setAttribute("id", "id2");
    div.appendChild(document.createTextNode("divText"));
    
    tree.appendChild(link);
    tree.appendChild(div);
    document.getElementById("main").appendChild(tree);
    

    使用 documentFragment 而不是直接添加元素的主要原因是执行速度。

    在这个大小上没关系,但是当你开始添加数百个元素时,你会喜欢先在内存中做这件事:-)

    使用 documentFragment,您可以在内存中构建一整棵 DOM 元素树,并且直到最后一刻才会影响浏览器 DOM。

    否则,它会强制浏览器针对每个元素进行更新,这有时会让人很痛苦。

    【讨论】:

    • 我记得在 SO 上讨论过这个问题:使用内存中的 div 不应该比使用 documentFragment 有缺点。可以在@stackoverflow.com/questions/4538093/… 找到讨论。我认为 Tim Down 说得有道理。
    • 此外,您可能还想阅读 Raziel 的评论(2008 年 7 月 30 日下午 1:10)@ejohn.org/blog/dom-documentfragments/#postcomment
    • @Kooilnc 感谢您的指点。尤其是后者。要点仍然是在内存中创建元素的优势,而不是在您进行时将它们添加到 DOM。但我们对此表示同意。我会说,就像你做的那样,将元素添加到 documentFragment 或任何其他内存节点都无关紧要。我仍然更喜欢 documentFragment 的一个原因是为了可读性,因为很明显片段不是 DOM 的一部分。但在我尝过之前,这只是一个口味问题 :-)
    • 我实际上做了一些简单的测试:jsfiddle.net/6WEHc/5。似乎使用 document.createElement('div');比 document.createDocumentFragment() 快一点;希望这对某人有帮助:)
    【解决方案3】:

    您可以将 html 构造为一个变量中的字符串,例如

    var html = "";
    html += "<a id='" + id1 +"'>link</a>";
    html += "<div id='" + id1 +"'>div</div>";
    // ... and so on
    

    然后你返回变量 html

    return html;
    

    【讨论】:

    • JavaScript 有一些可爱的 DOM 方法可以为你处理转义和诸如此类的事情,同时提供比这种容易出错的字符串混搭更易读的语法。
    • 是的,我知道,您甚至可以使用 jquery 做得更好,更不容易出错。
    • 这是错误的方式,不要写这样的代码。您可以快速实施它,但稍后您会感到愚蠢。
    【解决方案4】:

    如果您重复执行此操作(动态创建 HTML),您可能需要使用更通用的方法。

    如果你想创建三个不相关的元素,你可以这样做:

    var anchor = elem("a", {"id":"id1"});
    var div    = elem("div", {"id":"id2"});
    var xyz    = elem("div", {"id":"id3"});
    

    现在,您拥有三个元素。如果您想获取这些的 HTML(作为字符串),只需执行以下操作:

    var html = anchor.outerHTML + div.outerHTML + xyz.outerHTML;
    

    如果你想在一个元素(比如 div)中包含这三个,请执行以下操作:

    var div = elem("div", null, [
        elem("a", {"id":"id1"}),
        elem("div", {"id":"id2"}),
        elem("div", {"id":"id3"}),
    ]);
    

    您可以使用div.outerHTML 获取 HTML,或者您可以将其附加到任何您想要的位置。

    要了解更多关于elem()的信息,请访问element.js (GitHub)


    我添加这个答案不是为了 8 岁的问题,而是为了未来的访客。希望,它有帮助。

    【讨论】:

      【解决方案5】:

      这是将 html 页面(静态)转换为基于 javascript 的 html 页面(动态)的简单说明。

      假设您将 html-page 作为“index.html”(此处调用 index_static.html)。

      index_static.html

      <!DOCTYPE HTML>
      <html>
          <head>
              <title>Test</title>
          </head>
          <body>
              <h1> Hello !!! </h1>
          </body>
      </html>
      

      您可以在浏览器中打开此文件,以查看所需的输出。

      现在,让我们创建一个与此等效的 javascript。 使用online-tool,生成javascript源(通过将上面的html文件源粘贴到它)。因此,如下:

      dynamic.js

      document.write("<!DOCTYPE HTML>");
      document.write("<html>");
      document.write("    <head>");
      document.write("        <title>Test<\/title>");
      document.write("    <\/head>");
      document.write("    <body>");
      document.write("        <h1> Hello !!! <\/h1>");
      document.write("    <\/body>");
      document.write("<\/html>");
      

      现在,您的 static_index.html 的动态版本如下:

      index_dynamic.html

      <script language="JavaScript" src="dynamic.js"></script>
      

      在浏览器上打开 index_dynamic.html 以验证网页(虽然是动态的,但实际上是动态的)。

      more info

      【讨论】:

        猜你喜欢
        • 2012-08-30
        • 2013-12-30
        • 2015-11-05
        • 1970-01-01
        • 2019-04-03
        • 1970-01-01
        • 2020-02-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多