Alternative for innerHTML?
我想知道是否有一种方法可以在不使用innerHTML的情况下更改HTML中任何文本。
我问的原因是因为它对W3C有点皱眉。
我知道这很挑剔,但我只想知道,有办法吗?
编辑:人们似乎误解了我在这里要问的问题:我想找到一种有效地更改所显示文本的方法。
如果我有:
1 | One |
innerHTML允许我执行以下操作:
1 2 | var text = document.getElementsById("one"); text.innerHTML ="Two"; |
而且我屏幕上的文字也会更改。
我不想添加更多文本,我希望更改所有现成的文本。
推荐的方法是通过DOM操作,但是可能很冗长。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // <p> Hello, World! </p> var para = document.createElement('p'); para.appendChild(document.createTextNode('Hello, ')); // var b = document.createElement('b'); b.appendChild(document.createTextNode('World'); para.appendChild(b); para.appendChild(document.createTextNode('!')); // Do something with the para element, add it to the document, etc. |
编辑
响应您的编辑,为了替换当前内容,您只需删除现有内容,然后使用上面的代码填写新内容。例如:
1 2 3 4 | var someDiv = document.getElementById('someID'); var children = someDiv.childNodes; for(var i = 0; i < children.length; i++) someDiv.removeChild(children[i]); |
但是正如其他人所说,我建议改用jQuery之类的东西,因为并非所有浏览器都完全支持DOM,并且那些浏览器确实具有怪异现象,这些怪异现象由JavaScript库内部处理。例如,jQuery看起来像这样:
1 2 3 | $('#someID').html("<p> Hello, World! </p>"); |
更好的方法是使用
您可以通过操作DOM来获得相同的效果。更改文本的最安全方法是删除元素的所有子节点,然后用新的文本节点替换它们。
1 2 3 4 5 | var node = document.getElementById("one"); while( node.firstChild ) node.removeChild( node.firstChild ); node.appendChild( document.createTextNode("Two") ); |
删除子节点会删除元素的文本内容,然后再将其替换为新文本。
大多数开发人员避免使用innerHTML的原因是,通过DOM访问元素符合标准。
如果只想更改纯文本,那么有一种更快的解决方案依赖于标准:
1 | document.getElementById("one").firstChild.data ="two"; |
无论如何,请注意,innerHTML将成为即将到来的HTML 5标准的一部分。
简单。
将
1 2 3 | var who=document.getElementById('one'), txt='new text'; if(who.innerText) who.innerText=txt; else if(who.textContent) who.textContent= txt; |
这可能与innerHTML一样令人反感,但它的优点是可以在某些情况下(IE)使用innerHTML或appendChild不起作用的情况,例如某些表节点,样式和脚本元素的文本以及表单字段的值
我还在寻找绕过
1 2 3 4 5 6 7 8 | HTMLElement.prototype.htmlContent = function(html) { var dom = new DOMParser().parseFromString('<template>'+html+'</template>', 'text/html').head; this.appendChild(dom.firstElementChild.content); } //-- document.getElementById('my-id').innerHTML = string_of_html; document.getElementById('my-id').htmlContent(string_of_html); |
没有标签,而是循环的另一种选择:
1 2 3 4 5 | HTMLElement.prototype.htmlContent = function(html) { var dom = new DOMParser().parseFromString(html, 'text/html').body; while (dom.hasChildNodes()) this.appendChild(dom.firstChild); } |
请记住,当innerHTML"替换"内容时,此方法实际上是"添加"内容...
这可能会有所帮助:
1 2 3 4 5 6 7 | HTMLElement.prototype.clearContent = function() { while (this.hasChildNodes()) this.removeChild(this.lastChild); } //-- document.getElementById('my-id').innerHTML = ''; document.getElementById('my-id').clearContent(); |
doc:https://github.com/swannty/escaping-innerHTML
性能:https://jsperf.com/escaping-innerhtml
好吧,如果我能正确理解您的问题,这应该是一个答案。
1 2 3 | var text = document.getElementById("one"); //text.innerHTML ="Two"; text.childNodes[0].nodeValue="two"; |
在我看来,CSS + HTML + JS组合应该可以达到预期的效果:
1 2 3 4 5 6 7 8 9 10 11 | .myelement:before { content: attr(alt); } ... <span class='myelement' alt='initial value'></span> ... element.setAttribute('alt', 'new value'); |
有人知道这是否行得通吗?
您可以按以下方式使用DOM:
1 2 3 4 5 6 7 8 9 10 11 | <html> <body> before <script type="text/javascript"> var element = document.getElementsByTagName("div")[0]; alert(element.firstChild.nodeValue); element.removeChild(element.firstChild); element.appendChild(document.createTextNode('after')); alert(element.firstChild.nodeValue); </body> |
但是我认为没有人会这样做,而是使用jQuery或Prototype之类的框架或其他任何JavaScript框架代替。这是jquery的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"> </head> <body> before <script type="text/javascript"> var element = $("div"); alert(element.text()); element.text("after"); alert(element.text()); </body> |
insertAdjacentHTML()是必经之路。阅读更多:
点击获取文档
如果我要定期更新文本节点,有时会发现存储对文本节点的直接引用很有用。我做这样的事情:
1 | var dynamicText = myDiv.appendChild(document.createTextNode("the initial text")); |
然后每当我需要更新它时,我就这样做:
1 | dynamicText.nodeValue ="the updated text"; |
这样可以避免遍历DOM或添加或删除任何子代。