使用 javascript 注入 html 的最佳方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3762385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:02:51  来源:igfitidea点击:

best way to inject html using javascript

javascript

提问by Mike Rifgin

I'm hoping that this isn't too subjective. I feel there is a definitive answer so here goes.

我希望这不是太主观。我觉得有一个明确的答案,所以在这里。

I want to create this html on the fly using JS (no libraries):

我想使用 JS(没有库)动态创建这个 html:

<a href="#" id="playButton">Play</a>
<a href="javascript: void(0)" id="muteUnmute">Mute</a>
<div id="progressBarOuter"> 
  <div id="bytesLoaded"></div>
    <div id="progressBar"></div>
</div>
<div id="currentTime">0:00</div>
<div id="totalTime">0:00</div>

using javascript. I know I can do this using createElement etc but it seems extremely long winded to do this for each element. Can anyone suggest a way to do this with more brevity.

使用javascript。我知道我可以使用 createElement 等来做到这一点,但为每个元素做到这一点似乎非常冗长。任何人都可以提出一种更简洁的方法来做到这一点。

I do not have access to a library in this project....so no jquery etc.

我无权访问这个项目中的库……所以没有 jquery 等。

采纳答案by Ryan Ternier

Shove the entire thing into a JS variable:

把整个东西塞进一个 JS 变量中:

var html = '<a href="#" id="playButton">Play</a>';
html += '<a href="javascript: void(0)" id="muteUnmute">Mute</a>';
html += '<div id="progressBarOuter"><div id="bytesLoaded"></div><div id="progressBar"></div></div>';
html += '<div id="currentTime">0:00</div>';
html += '<div id="totalTime">0:00</div>';

Then:

然后:

document.getElementById("parentElement").innerHTML = html;

if you want theN:

如果你想要N:

document.getElementById("totalTime").innerHTML = "5:00";

回答by Ates Goral

Keep your markup separate from your code:

将标记与代码分开:

You can embed the HTML snippets that you'll be using as hidden templates inside your HTML page and clone them on demand:

您可以在 HTML 页面中嵌入将用作隐藏模板的 HTML 片段,并根据需要克隆它们:

<style type="text/css">
#templates { display: none }
</style>
...
<script type="text/javascript">
var node = document.getElementById("tmp_audio").cloneNode(true);
node.id = ""; // Don't forget :)
// modify node contents with DOM manipulation
container.appendChild(node);
</script>
...
<div id="templates">
    <div id="tmp_audio">
        <a href="#" class="playButton">Play</a>
        <a href="#" class="muteUnmute">Mute</a>
        <div class="progressBarOuter"> 
            <div class="bytesLoaded"></div>
            <div class="progressBar"></div>
        </div>
        <div class="currentTime">0:00</div>
        <div class="totalTime">0:00</div>
    </div>
</div>

Update: Note that I've converted the idattributes in the template to classattributes. This is to avoid having multiple elements on your page with the same ids. You probably don't even need the classes. You can access elements with:

更新:请注意,我已将id模板中的class属性转换为属性。这是为了避免您的页面上有多个具有相同 ID 的元素。您可能甚至不需要这些课程。您可以通过以下方式访问元素:

node.getElementsByTagName("div")[4].innerHTML =
    format(data.currentTime);

Alternatively, you can act on the HTML of the template:

或者,您可以对模板的 HTML 进行操作:

<script type="text/javascript">
var tmp = document.getElementById("tmp_audio").innerHTML;
// modify template HTML with token replacement
container.innerHTML += tmp;
</script>

回答by yorick

You can use

您可以使用

<script type="text/javascript">
    function appendHTML() {
        var wrapper = document.createElement("div");
        wrapper.innerHTML = '\
<a href="#" id="playButton">Play</a>\
<a href="javascript: void(0)" id="muteUnmute">Mute</a>\
<div id="progressBarOuter"> \
<div id="bytesLoaded"></div>\
    <div id="progressBar"></div>\
</div>\
<div id="currentTime">0:00</div>\
<div id="totalTime">0:00</div>\
';
        document.body.appendChild(wrapper);
    }
</script>

回答by Marcelo Lazaroni

edit: HTML import is now deprecated.

编辑:HTML 导入现已弃用

Now with Web Componentsyou can inject HTML using an HTML import.

现在,Web Components您可以使用HTML 导入来注入 HTML 。

The syntax looks like this:

语法如下所示:

<link rel="import" href="component.html" >

This will just load the content of the html file in the hrefattribute inline in the order it appears. You can any valid html in the loaded file, so you can even load other scripts if you want.

这将仅href按照其出现的顺序加载内联属性中的 html 文件的内容。您可以在加载的文件中使用任何有效的 html,因此您甚至可以根据需要加载其他脚本。

To inject that from JavaScript you could do something of the likes of:

要从 JavaScript 注入它,您可以执行以下操作:

var importTag = document.createElement('link');
importTag.setAttribute('rel', 'import');
importTag.setAttribute('href', 'component.html');
document.body.appendChild(importTag);

At the time I am writing this, Chrome and Opera support HTML imports. You can see an up to date compatibility table here http://caniuse.com/#feat=imports

在我写这篇文章的时候,Chrome 和 Opera 支持 HTML 导入。您可以在此处查看最新的兼容性表http://caniuse.com/#feat=imports

But don't worry about browsers not supporting it, you can use it in them anyway with the webcomponentsjspolyfill.

但是不要担心浏览器不支持它,无论如何你都可以通过webcomponentsjs polyfill在它们中使用它。

For more info about HTML imports check http://webcomponents.org/articles/introduction-to-html-imports/

有关 HTML 导入的更多信息,请查看http://webcomponents.org/articles/introduction-to-html-imports/

回答by ii iml0sto1

If you live in 2019 and beyond read here.

如果您生活在 2019 年及以后,请在此处阅读。

With JavaScript es6 you can use string literals to create templates.

使用 JavaScript es6,您可以使用字符串文字来创建模板。

create a function that returns a string/template literal

创建一个返回字符串/模板文字的函数

function videoPlayerTemplate(data) {
    return `
        <h1>${data.header}</h1>
        <p>${data.subheader}</p>
        <a href="#" id="playButton">Play</a>
        <a href="javascript: void(0)" id="muteUnmute">Mute</a>
        <div id="progressBarOuter"> 
            <div id="bytesLoaded"></div>
            <div id="progressBar"></div>
        </div>
        <time id="currentTime">0:00</time>
        <time id="totalTime">0:00</time>
    `
}

Create a JSON object containing the data you want to display

创建一个包含要显示的数据的 JSON 对象

var data = {
     header: 'My video player',
     subheader: 'Version 2 coming soon'
}

add that to whatever element you like

将其添加到您喜欢的任何元素中

const videoplayer = videoPlayerTemplate(data);
document.getElementById('myRandomElement').insertAdjacentHTML("afterbegin", videoplayer);

You can read more about string literals here

您可以在此处阅读有关字符串文字的更多信息

回答by Justin Niessner

If you don't need any validation for your syntax (which is what makes createElement()so nice) then you could always default to simply setting the innerHTMLproperty of the element you want to insert your markup inside of.

如果您不需要对语法进行任何验证(这就是createElement()很好的原因),那么您可以始终默认设置innerHTML要在其中插入标记的元素的属性。

Personally, I would stick with using createElement(). It is more verbose but there are far less things to worry about that way.

就个人而言,我会坚持使用createElement(). 它更冗长,但要担心的事情要少得多。

回答by Tim Medora

If performance is a concern, stay away from innerHTML. You should create the whole object tree using document.createElement()as many times as needed, including for nested elements.

如果性能是一个问题,请远离innerHTML。您应该document.createElement()根据需要多次创建整个对象树,包括嵌套元素。

Finally, append it to the document with one statement, not many statements.

最后,用一个语句将其附加到文档中,而不是许多语句。

In my informal testing over the years, this will give you the best performance (some browsers may differ).

在我多年来的非正式测试中,这将为您提供最佳性能(某些浏览器可能有所不同)。

If HTML is ever declared in a variable, it should be simple and for a very specific purpose. Usually, this is not the right approach.

如果 HTML 曾经在一个变量中声明过,它应该是简单的并且用于非常特定的目的。通常,这不是正确的方法。

回答by SLaks

You can concatenate raw HTML strings (being careful to escape text and prevent XSS holes), or you can rewrite jQuery (or something similar)

您可以连接原始 HTML 字符串(小心转义文本并防止 XSS 漏洞),或者您可以重写 jQuery(或类似的东西)

回答by Gavin van Gent

I have a situation where I pass text into a third party library, but if my model isPrivate, I'd like to add an element to the text.

我有一种情况,我将文本传递到第三方库,但如果我的模型是私有的,我想向文本添加一个元素。

return { id: item.id, text: (item.isPrivate == true) ? "<i class=\"icon-lock\" title=\"Private group.\"></i> " + item.label : item.label };

This creates issues with the way the third party library builds up its markup.

这会在第三方库构建其标记的方式上产生问题。

This is never a good idea, but third party libraries are there so that we don't have to write everything ourselves. In a situation like this, you have to rely on passing markup though javascript.

这绝不是一个好主意,但第三方库在那里,所以我们不必自己编写所有内容。在这种情况下,您必须依靠通过 javascript 传递标记。

When i find a proper solution to this, I will give you an update

当我找到合适的解决方案时,我会给你一个更新