如果 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 在大多数浏览器中都有,但它的工作方式不同。我会说,小心使用它。 也曾是“实用标准”。 ! @PEZ所有上瘾者都认为他们上瘾的东西是有用的。 @Trip...whatever 那个玩具不是网景特有的吗?【参考方案7】:

另一种选择是拥有两个 div 并使用 .hide() 和 .show()。

【讨论】:

以上是关于如果 innerHTML 是邪恶的,那么更改链接文本的更好方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

href 链接不适用于带有“onmouseover 更改文本”和 onmouseout 的 innerHTML 脚本

更改 contenteditable 元素的 innerHTML 后,将插入符号放回原来的位置

从外部 php 文件更改 innerHTML

为啥 cmake 文件 GLOB 是邪恶的?

如果文本已经输入,JavaScript 不会复制 innerHTML

如果某些子节点没有标签,如何更改子节点的 innerHTML?