如果 innerHTML 是邪恶的,那么更改链接文本的更好方法是啥?
Posted
技术标签:
【中文标题】如果 innerHTML 是邪恶的,那么更改链接文本的更好方法是啥?【英文标题】:If innerHTML is evil, then what's a better way change the text of a link?如果 innerHTML 是邪恶的,那么更改链接文本的更好方法是什么? 【发布时间】:2010-09-28 13:06:08 【问题描述】:我知道 innerhtml 被认为是邪恶的,但我认为这是更改链接文本的最简单方法。例如:
<a id="mylink" href="">click me</a>
在 JS 中你可以改变文本:
document.getElementById("mylink").innerHTML = new_text;
在 Prototype/jQuery 中:
$("mylink").innerHTML = new_text;
工作正常。否则,您必须先替换所有子节点,然后添加一个文本节点。何必呢?
【问题讨论】:
一些重要信息developer.mozilla.org/En/DOM:element.innerHTML 在jQuery中,可以使用html函数设置其innerHtml:$("#mylink").html('new html'); 【参考方案1】:怎么样
document.getElementById('mylink').firstChild.nodeValue = new_text;
这不会受到 PEZ 描述的问题的影响。
关于 Triptych 的评论和 bobince 的回复,这里有另一个解决方案:
var oldLink = document.getElementById('mylink'),
newLink = oldLink.cloneNode(false);
newLink.appendChild(document.createTextNode(new_text));
oldLink.parentNode.replaceChild(newLink, oldLink);
【讨论】:
如果链接包含内部 元素,这也不起作用。 是的,如果问题不是“有什么更好的方法 [to] 更改链接的文本”,那么您可能有一点... 作为通用版本,如果a元素中可能有其他内容,则清除内容并添加新的文本节点。例如:while (link.firstChild) link.removeChild(link.firstChild); link.appendChild(document.createTextNode('新文本')); 10年后,2018年没有理由不使用DOM标准的textContent
:document.getElementById('some-id').textContent = 'hello'
【参考方案2】:
innerHTML 一点也不邪恶。使用它没有任何问题,只要你知道后果。
【讨论】:
是的,就像 IE 中的错误 ;-)【参考方案3】:对于支持 DOM3 的浏览器,您可以使用 textContent:
document.getElementById("mylink").textContent = new_text;
这适用于 FF(在 3 中测试)、Opera(在 9.6 中测试)和 Chrome(在 1 中测试),但不适用于 MSIE7(尚未在 MSIE8 中测试)
添加示例
它不是很漂亮,但应该可以跨浏览器工作(在 FF3、Opera9.6、Crome1 和 MSIE7 中的 win 中测试)
function replaceTextContent(element,text)
if (typeof element ==="string") element = document.getElementById(element);
if (!element||element.nodeType!==1) return;
if ("textContent" in element)
element.textContent = text; //Standard, DOM3
else if ("innerText" in element)
element.innerText = text; //Proprietary, Micosoft
else
//Older standard, even supported by Microsoft
while (element.childNodes.length) element.removeChild(element.lastChild);
element.appendChild(document.createTextNode(text));
(更新:增加了对微软专有的 innerText 的支持)
【讨论】:
【参考方案4】:innerHTML 有副作用(比如断开现有的 DOM 节点和重新渲染可能很繁重)。人们需要意识到这些影响。任何维护代码的人都需要注意使用了innerHTML,否则他们可能会遇到奇怪的错误。
【讨论】:
无论如何,在大多数情况下,innerHTML 通常比使用 DOM 快得多。 @rob 大陆导弹比 747 快得多,只是它没有为乘客提供着陆序列,所以你想骑一个吗?【参考方案5】:直到一年前,innerHTML 还比通过 DOM 操作事件快得多。我自己还没有检查过所有主流浏览器的最新版本。
例如,Firefox 不能很好地处理这个问题。它有时只更新屏幕以反映更改。如果您在更改后查询 DOM,它仍然具有旧值。
示例:尝试通过 innerHTML 更改文本区域的值,然后发布表单。它会默默地发布 textarea 之前的值。想想这样的事情可能会造成的灾难性后果。
【讨论】:
@Wouter: Textarea 是一个输入字段,它的值应该用 element.value 改变 我知道你也可以这样改。如果您使用innerHTML,它会被默认接受,但不会按照您期望的方式运行。 "由于该属性没有公开的规范,因此实现方式存在很大差异。例如,当在文本输入中输入文本时,IE 会更改输入的 innerHTML 属性的 value 属性,但 Gecko 浏览器会不是。” (续……) TEXTAREA 中应该包含什么 HTML? TextArea 中不应该有 HTML,但是 innerText 也有同样的问题,并且肯定文本应该在 textarea 中,对吧?问题是浏览器允许您设置属性。 FireFox 更新了小部件中的值(所以它看起来像它工作),但不更新 DOM。 IE 同时更新。【参考方案6】:也许只是一些标准的瘾君子拒绝了 innerHTML 的想法。
innerHTML 是实用标准,因为所有浏览器都实现了它,尽管它不是 W3C 标准。
只需使用它。它就像一个魅力。
【讨论】:
“标准瘾君子”? =) 标准有其用途。就像鼓励一个共同的实施。 innerHTML 在大多数浏览器中都有,但它的工作方式不同。我会说,小心使用它。另一种选择是拥有两个 div 并使用 .hide() 和 .show()。
【讨论】:
以上是关于如果 innerHTML 是邪恶的,那么更改链接文本的更好方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
href 链接不适用于带有“onmouseover 更改文本”和 onmouseout 的 innerHTML 脚本
更改 contenteditable 元素的 innerHTML 后,将插入符号放回原来的位置