【问题标题】:Inserting HTML elements with JavaScript使用 JavaScript 插入 HTML 元素
【发布时间】:2010-10-23 07:24:44
【问题描述】:

使用以下语法时,无需为每种类型的属性和事件繁琐地搜索解决方法:

elem = document.createElement("div");
elem.id = 'myID';
elem.innerHTML = ' my Text '
document.body.insertBefore(elem,document.body.childNodes[0]);

有没有一种方法可以将整个 HTML 元素声明为字符串?喜欢:

elem = document.createElement("<div id='myID'> my Text </div>");
document.body.insertBefore(elem,document.body.childNodes[0]);

【问题讨论】:

    标签: javascript html


    【解决方案1】:

    正如其他人所说,可以模拟方便的 jQuery prepend 功能:

    var html = '<div>Hello prepended</div>';
    document.body.innerHTML = html + document.body.innerHTML;
    

    虽然有人说最好不要“弄乱”innerHTML,但如果您知道这一点,它在许多用例中都是可靠的:

    如果 &lt;div&gt;&lt;span&gt;&lt;noembed&gt; 节点具有包含字符 (&amp;)、(&lt;) 或 (&gt;) 的子文本节点,innerHTML 将返回这些字符分别为&amp;amp&amp;lt&amp;gt。使用Node.textContent 获取这些文本节点内容的正确副本。

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

    或者:

    var html = '<div>Hello prepended</div>';
    document.body.insertAdjacentHTML('afterbegin', html)
    

    insertAdjacentHTML 可能是一个不错的选择:https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML

    【讨论】:

      【解决方案2】:

      看看insertAdjacentHTML

      var element = document.getElementById("one");
      var newElement = '<div id="two">two</div>'
      element.insertAdjacentHTML( 'afterend', newElement )
      // new DOM structure: <div id="one">one</div><div id="two">two</div>
      

      位置是相对于您要插入的相邻元素的位置:

      '开始之前' 在元素本身之前

      '之后' 就在元素内部,在它的第一个子元素之前

      '结束前' 就在元素内部,在其最后一个子元素之后

      '事后' 在元素本身之后

      【讨论】:

        【解决方案3】:

        如果您想在现有页面的标签中插入 HTML 代码,请使用 Jnerator。这个工具是专门为此目的而创建的。

        而不是编写下一个代码

            var htmlCode = '<ul class=\'menu-countries\'><li
                class=\'item\'><img src=\'au.png\'></img><span>Australia </span></li><li
                class=\'item\'><img src=\'br.png\'> </img><span>Brazil</span></li><li
                class=\'item\'> <img src=\'ca.png\'></img><span>Canada</span></li></ul>';
            var element = document.getElementById('myTag');
            element.innerHTML = htmlCode;
        

        你可以写出更容易理解的结构

            var jtag = $j.ul({
                class: 'menu-countries',
                child: [
                    $j.li({ class: 'item', child: [
                        $j.img({ src: 'au.png' }),
                        $j.span({ child: 'Australia' })
                    ]}),
                    $j.li({ class: 'item', child: [
                        $j.img({ src: 'br.png' }),
                        $j.span({ child: 'Brazil' })
                    ]}),
                    $j.li({ class: 'item', child: [
                        $j.img({ src: 'ca.png' }),
                        $j.span({ child: 'Canada' })
                    ]})
                ]
            });
            var htmlCode = jtag.html();
            var element = document.getElementById('myTag');
            element.innerHTML = htmlCode;
        

        【讨论】:

          【解决方案4】:

          你想要这个

          document.body.insertAdjacentHTML( 'afterbegin', '<div id="myID">...</div>' );
          

          【讨论】:

          • @JonnyLeeds 这似乎不适用于 body 元素,但适用于任何其他元素。
          • @Phill 当然它适用于&lt;body&gt;。事实上,在&lt;body&gt; 上运行它是我通过控制台将样式表等内容注入网页的标准方法。你有什么问题?
          • @ŠimeVidas 可能是因为在执行时未定义 body 元素...我将您的行与 window.onload = function() { ... } 配对以防止该问题
          • @Grandy Phill 写道,它适用于其他元素。如果&lt;body&gt; 未定义,那么所有其他元素也是如此,所以这可能不是 Phill 的问题。
          • @ŠimeVidas 嗯,你说得对......如果它适用于任何东西,它也应该适用于身体
          【解决方案5】:

          据我所知,公平地说,这是相当新的和有限的,这种技术的唯一潜在问题是您无法动态创建某些表格元素。

          我通过将“模板”元素添加到隐藏的 DIV,然后使用 cloneNode(true) 创建一个克隆并根据需要附加它来使用表单进行模板化。请注意,您确实需要确保根据需要重新分配 id 以防止重复。

          【讨论】:

            【解决方案6】:

            在老式 JavaScript 中,您可以这样做:

            document.body.innerHTML = '<p id="foo">Some HTML</p>' + document.body.innerHTML;
            

            回应您的评论:

            [...] 我感兴趣的是声明新元素的属性和事件的来源,而不是元素的 innerHTML

            不过,您需要将新的 HTML 注入 DOM;这就是为什么 innerHTML 在老式 JavaScript 示例中使用的原因。 BODY 元素的 innerHTML 以新的 HTML 开头。我们并没有真正触及 BODY 中的现有 HTML。

            我将重写上述示例以澄清这一点:

            var newElement = '<p id="foo">This is some dynamically added HTML. Yay!</p>';
            var bodyElement = document.body;
            bodyElement.innerHTML = newElement + bodyElement.innerHTML;
            // note that += cannot be used here; this would result in 'NaN'
            

            使用 JavaScript 框架可以减少代码的冗长并提高可读性。例如,jQuery 允许您执行以下操作:

            $('body').prepend('<p id="foo">Some HTML</p>');
            

            【讨论】:

            • 相当不错。但我感兴趣的是声明新元素的属性和事件的来源,而不是元素的 innerHTML。
            • document.getElementsByTagName('body')[0] 确实可以替换为document.body,好点。但是,如果您想将新的 HTML 添加到另一个现有元素而不是 BODY,则必须使用 document.getElementById() 和/或 document.getElementsByTagName();这就是我在示例中使用它的原因。
            • 另外,如果您直接添加/插入“innerHTML”,您的代码很快就会变得非常混乱
            • @JimmyP:什么垃圾!这个问题的真正目的是能够直接将 HTML 作为字符串插入,而不是玩弄构造它的函数,逐个属性,逐个节点,逐个元素。
            • 这会分离所有事件处理程序,并可能导致大量内存泄漏。
            【解决方案7】:

            与其直接弄乱 innerHTML,不如创建一个片段然后插入它:

            function create(htmlStr) {
                var frag = document.createDocumentFragment(),
                    temp = document.createElement('div');
                temp.innerHTML = htmlStr;
                while (temp.firstChild) {
                    frag.appendChild(temp.firstChild);
                }
                return frag;
            }
            
            var fragment = create('<div>Hello!</div><p>...</p>');
            // You can use native DOM methods to insert the fragment:
            document.body.insertBefore(fragment, document.body.childNodes[0]);
            

            好处:

            1. 您可以使用本机 DOM 方法进行插入,例如 insertBefore、appendChild 等。
            2. 您可以在插入之前访问实际的 DOM 节点;您可以访问片段的 childNodes 对象。
            3. 使用文档片段非常快;比在 DOM 之外创建元素要快,在某些情况下比 innerHTML 还要快。

            虽然 innerHTML 在函数中使用,但它都发生在 DOM 之外,所以它比你想象的要快得多......

            【讨论】:

            • 我敢打赌这个 createDocumentFragment() 不会像“遗留”的 innerHTML 那样好。
            • 我真的很想向后兼容,所以我怎么能把它和innerHTML一起使用,就像我检查这个方法是否不为空一样,也许?
            • 此方法适用于所有现代浏览器。对于 IE 5.5 及以下版本,您可以执行如下检查:: if (document.createDocumentFragment) { create('...'); } else { /* 可能使用 innerHTML */ }
            • crescentfresh,我帮助 SO 因为我喜欢帮助别人;如果解决方案不是在所有情况下都 100% 可操作,我很抱歉。如果您如此担心,为什么不提供自己的解决方案,而不是不必要地批评已经提供的答案?任何抽象都会有边缘情况!这是一个学习环境——我们不是来给人们一个盘子里的解决方案——我们来这里是为了帮助彼此在我们所做的事情上做得更好!抱歉,有人在哪里提到“AJAX”?
            • 很公平。我很抱歉。我只是觉得这里有很多抽象,提到了零警告。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-07-06
            • 1970-01-01
            • 2013-06-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多