views:

1549

answers:

7

I know innerHTML is supposedly evil, but I think it's the simplest way to change link text. For example:

<a id="mylink" href="">click me</a>

In JS you can change the text with:

document.getElementById("mylink").innerHTML = new_text;

And in Prototype/jQuery:

$("mylink").innerHTML = new_text;

works fine. Otherwise you have to replace all of the child nodes first and then add a text node. Why bother?

+4  A: 

innerHTML has side effects (like disconnecting existing DOM nodes and rerendering that might be heavy). One needs to be aware of these effects. And anyone maintaining the code will need to be alert to that innerHTML is used or they might run into strange bugs.

PEZ
Regardless, in most cases, innerHTML is usually way faster than using the DOM.
Robert C. Barth
@robContinental missiles are way faster than 747 only it doesn't come with a landing sequence for passengers, so you'd like to ride on one?
kavoir.com
+4  A: 

innerHTML is not evil at all. There's nothing wrong with using it, as long as you're aware of the consequences.

Kon
yeah, like the bugs in IE ;-)
scunliffe
+3  A: 

Maybe it's just some standard addicts who reject the idea of innerHTML.

innerHTML is the practical standard because all browsers implement it though it's not a W3C standard.

Just use it. It works like a charm.

kavoir.com
"standard addict"? =) Standards have their uses though. Like encouraging a common implementation. innerHTML is there in most browsers but it works differently. Use it with care, I would say.
PEZ
<layer>s were once a "practical standard" too.
Triptych
<bite>me</bite>!@PEZ All addicts reason for what they are addicted to as something [email protected] Isn't that toy specific to just netscape?
kavoir.com
+4  A: 

Up until a year ago, innerHTML was just a lot faster than manipulating events via the DOM. I haven't checked the latest versions of all major browsers for this myself.

Firefox for example doesn't handle this well. It sometimes only updates the screen to reflect the change. If you query the DOM after the change, it still has the old values.

Example: try to change the value of a textarea via innerHTML, and then post the form. It'll silently post the value that the textarea had before. Think of the catastrophic results that something like that could have.

Wouter van Nifterick
@Wouter: Textarea is an input field and its value should be changed with element.value
some
I know you can also change it like that. If you use innerHTML it is silently accepted, but it doesn't work out the way you expect it to.
Wouter van Nifterick
"silently accepted" - what would you rather have happen?
Greg Dean
"As there is no public specification for this property, implementations differ widely. For example, when text is entered into a text input, IE will change the value attribute of the input's innerHTML property but Gecko browsers do not." (cont..)
some
https://developer.mozilla.org/en/DOM/element.innerHTML
some
What HTML are supposed to be inside a TEXTAREA ?
some
There is no HTML supposed to be in a TextArea, but innerText has the same problem, and for sure text is supposed to be in a textarea, right?The problem is that browsers let you set the property. FireFox updates the value in the widget (so it LOOKS like it worked), but not the DOM. IE updates both.
Wouter van Nifterick
A: 

Another option is to have two divs and use .hide() & .show().

Todd Smith
+8  A: 

How about

document.getElementById('mylink').firstChild.nodeValue = new_text;

This won't suffer from the problems described by PEZ.

Regarding Triptych's comment and bobince's reply, here's another solution:

var oldLink = document.getElementById('mylink'),
    newLink = oldLink.cloneNode(false);
newLink.appendChild(document.createTextNode(new_text));
oldLink.parentNode.replaceChild(newLink, oldLink);
Christoph
This also won't work if the link contains an inner <span> element.
Triptych
Yeah, and if the question wasn't "what’s a better way [to] change the text of a link", you might have had a point...
Christoph
As a generalised version if there might be other content in the a element, clear the content and add a new text node. eg.: while (link.firstChild) link.removeChild(link.firstChild); link.appendChild(document.createTextNode('New text'));
bobince
+3  A: 

For browsers supporting DOM3 you can use textContent:

document.getElementById("mylink").textContent = new_text;

This works in FF(tested in 3), Opera (tested in 9.6) and Chrome (tested in 1) but not in MSIE7 (haven't tested in MSIE8)

Added example

It's not pretty but should work cross browser (tested in win in FF3, Opera9.6, Crome1 and MSIE7)

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));
    }
}

(updated: added support for Microsofts proprietary innerText)

some