views:

255

answers:

3

I have HTML page with some HTML element with ID="logo". I need to create JS script (with no external libs calls) that will overwrite that html element with other HTML element like "<div id=logo> stuff inside </div>".

A: 

I'd suggest just taking a look at one of the libraries' implementations: Here's jQuery's and here's Prototype's.

thenduks
Also, at that link, the very next function is `replaceWith` which might also be what you're looking for if you need to fully replace the whole element. If the tag is the same (and even `id` is, it seems) then `html` will do fine.
thenduks
I'm not going to downvote, but he explicitly says "with no external libs calls"! :P
LeguRi
@Richard: thenduks' suggestion (as I read it) was to *look at how those libraries do it*, not to use the libraries. And not a bad idea at all, when you want to do something non-trivial.
T.J. Crowder
@Richard: That's why I said look at their implementation, not include the library in the app and use it. If I meant for the OP to _use_ the library then I would have referred them to the docs, not the source :)
thenduks
@thenduks - Good call! My bad :)
LeguRi
A: 

Do you really need to 'replace' the element or can you just toggle its visibility? This is a technique that's much simpler and will be more efficient. Most importantly it keeps the content (html) separated from the behavior (javascript).

function toggle() {
    document.getElementById("logo").style.display="none";
    document.getElementById("element_to_show").style.display="block";
}

see T.J.'s answer if you actually want to replace the element.

CrazyJugglerDrummer
+6  A: 

Most of the time, it's just the content you want to replace, not the element itself. If you actually replace the element, you'll find that event handlers attached to it are no longer attached (because they were attached to the old one).

Replacing its content

Replacing the element's content is easy:

var element;
element = document.getElementById("logo");
if (element) {
    element.innerHTML = "-new content-";
}

The innerHTML property has only recently been standardized, but is supported by all major browsers (probably most minor ones, too). (See notes below about innerHTML and alternatives.)

Replacing the element iself

Actually replacing the element itself is a little harder, but not much:

var element, newElement, parent;

// Get the original element
element = document.getElementById("logo");

// Assuming it exists...
if (element) {
    // Get its parent
    parent = element.parentNode;

    // Create the new element
    newElement = document.createElement('div');

    // Set its ID and content
    newElement.id = "logo";
    newElement.innerHTML = "-new content here-";

    // Insert the new one in front of the old one (this temporarily
    // creates an invalid DOM tree [two elements with the same ID],
    // but that's harmless because we're about to fix that).
    parent.insertBefore(newElement, element);

    // Remove the original
    parent.removeChild(element);
}

Notes on innerHTML and other DOM manipulation techiques

There are a number of wrinkles around using innerHTML in certain browsers, mostly around tables and forms. If you can possibly use a library like jQuery, Prototype, etc., I'd do so, as they've got workarounds for those issues built-in.

Alternatively, you can use the various other DOM methods rather than innerHTML (the same ones I used for creating the div and adding/removing, above). Note that in most browsers, doing any significant amount of markup by doing a bunch of createElement, appendChild, etc., calls rather than using innerHTML will be dramatically slower. Parsing HTML into their internal structures and displaying it is fundamentally what browsers do, and so they're highly optimized to do that. When you go through the DOM interface, you're going through a layer built on top of their internal structures and not getting the advantage of their optimizations. Sometimes you have to do it that way, but mostly, innerHTML is your friend.

T.J. Crowder
I realized my mistake a second after posting...so deleted it...but you beat me to downvoting it...how unfortunate...good answer though. Never thought of doing this myself. Thanks.
Mussnoon
@Muhammad: You're assuming I was the one downvoting; just because i commented it doesn't mean I downvoted. Normally, I'd comment, then downvote several minutes later if the answer hadn't been corrected or removed. But it happens you're right on this occasion -- for some reason I downvoted right away. I don't know why (and can't undo it now, as the answer's been deleted).
T.J. Crowder
I strongly encourage you to 'actually replace the element itself'. Using `innerHTML` is convenient sometimes, but can also be a vulnerability other times. So if this is your first DOM-adventure, I encourage you to do it the long way at least this once.
LeguRi
Also take note that in IE6, there are certain elements that cannot be modified with innerHTML, most notably tables.
WishCow
@WishCow: I did note that in my answer (*"There are a number of wrinkles..."*)
T.J. Crowder
@Richard: I see what you're saying, but replacing the element or not and using `innerHTML` or not are separate, unrelated issues. You can reuse the element without using `innerHTML`, just modify its set of child nodes (e.g., adding/removing as necessary); and of course you can replace it by using `innerHTML` (on the parent). The big reasons for not replacing it if you can avoid it are 1) It's more work, and 2) It invalidates all references to the old element, including the ones that associate it with its event ahndlers -- the new element will start out with no handlers attached at all.
T.J. Crowder