Swap DOM objects in / out to object variables?

S

sneill

I know its possible to dynamically remove elements from the DOM, but
rather than deleting them forever, is it possible to 'capture' them and
save them as an object variable so they can be reused elsewhere?

Consider this...

There are 2 DIV tags with the same ID value.

Wouldn't it be a neat trick if you could move one of the DIV tags out
to an object variable so that a getElementById() would return a result
for DIV tag that remained? Swapping the first DIV tag object back and
repeating the process on the second would return the first DIV tag on a
getElementById().

I tried cloning a DOM element by creating a clone() prototype function
on the Object object, but that didn't work.

Any ideas anyone?

Steve
 
J

Jeff North

On 26 Jan 2005 19:08:29 -0800, in comp.lang.javascript
| I know its possible to dynamically remove elements from the DOM, but
| rather than deleting them forever, is it possible to 'capture' them and
| save them as an object variable so they can be reused elsewhere?
|
| Consider this...
|
| There are 2 DIV tags with the same ID value.
|
| Wouldn't it be a neat trick if you could move one of the DIV tags out
| to an object variable so that a getElementById() would return a result
| for DIV tag that remained? Swapping the first DIV tag object back and
| repeating the process on the second would return the first DIV tag on a
| getElementById().
|
| I tried cloning a DOM element by creating a clone() prototype function
| on the Object object, but that didn't work.
|
| Any ideas anyone?

The fact that you have 2 IDs the same is going to cause the
application logic problems. When you tell the program to manipulate
the ID which ID is it supposed to manipulate, the first or the second?
How will the application 'know' which of the 2 identical IDs are
active or which one to clone?

You'd be better off giving the DIVs unique IDs and NAME attributes.
Then in your code store the 'active' element within a variable and
then do further processing.
 
J

John Doe

I don't guarantee this for standards or cross-browser compatibility, but
on latest IE it works:
<head>
<title>
Test of Div Replacement using Cloning and removeNode will swap the divs
three times thus leaving them in reverse order
</title>
<script>
function swapem() {
var mydiv=document.getElementById("my1").cloneNode(true);
document.getElementById("my1").removeNode(true);
alert(document.getElementById("my1").innerHTML);
document.getElementById("my1").insertAdjacentElement("afterEnd",mydiv);
}
</script>
</head>
<body
onload="alert(document.getElementById('my1').innerHTML);swapem();swapem();swapem();">
<DIV id=my1>
This is div1
</div>
<div id=my1>
This is div1.1
</div>
</body>
 
M

Martin Honnen

I know its possible to dynamically remove elements from the DOM, but
rather than deleting them forever, is it possible to 'capture' them and
save them as an object variable so they can be reused elsewhere?

Sure, a node can be detached from the document and stored in a variable
or attached to a document fragment and later on reinserted or moved
elsewhere.

I tried cloning a DOM element by creating a clone() prototype function
on the Object object, but that didn't work.

DOM nodes are host objects so a method on the Object prototype doesn't
help but you can call cloneNode(true) for a deep clone and
cloneNode(false) for a shallow clone on DOM nodes.
 
M

Martin Honnen

John said:
my example above (which only works in IE) can you tell me how I
would convert it to be standards compliant? W3C doesn't appear to
define a removeNode(), only removeChild(), but I got bogged down once I
reached that point, trying to point a document.removeChild to the right
element, and just settled for the IE way.

Your example seems to start with two elements in one document with the
same id attribute value and what happens with document.getElementById is
left open.
As for removing a node in the W3C DOM
if (node.parentNode) {
node.parentNode.removeChild(node);
}
 
J

John Doe

Martin,
RE my example above (which only works in IE) can you tell me how I
would convert it to be standards compliant? W3C doesn't appear to
define a removeNode(), only removeChild(), but I got bogged down once I
reached that point, trying to point a document.removeChild to the right
element, and just settled for the IE way.
 
J

John Doe

Actually W3C specifies that getElementById returns the first element
with the supplied id, so the functionality of that part should be
standard (Although giving multiple elements the same id is certainly bad
programming practice); I was just giving the original poster what they
wanted, a way to do that silly little trick. Thanks for the info, makes
sense. What about the insertAdjacent? Also not in the official DOM
methinks.
 
Z

Zifud

John said:
Actually W3C specifies that getElementById returns the first element
with the supplied id,

Rubbish.

"ID
This attribute assigns a name to an element. This name must be
unique in a document.

"...The id attribute assigns a unique identifier to an
element...

"...Note that the French "msg1" and the English "msg1" may not
appear in the same document since they share the same id
value."

<URL:http://www.w3.org/TR/html4/struct/global.html#adef-id>

You will also find a number of references in the anchors section
highlighting that *ID must be unique*


<URL:http://www.w3.org/TR/html4/struct/links.html#anchors-with-id>


The specification absolutely unequivocal: ID must be unique.

Furthermore, ID and NAME share the same namespace so the only
way to have an identical name and id in the same document is for
them to be on the same element (either A, APPLET, FORM, FRAME,
IFRAME, IMG, or MAP), and in that case they *must* be
identical. Name need not be unique, but when used as an anchor
it must be.

Most browsers will return the first element if two have
identical IDs - but it is not part of the W3C standard.

so the functionality of that part should be
standard

No, it's not. It's just that the major browsers do it that way
to play nice and not barf if you make a mistake.
 
R

RobG

John said:
Actually W3C specifies that getElementById returns the first element
with the supplied id,

Rubbish.

The W3C DOM Level 1 spec says:

"getElementById
Returns the Element whose id is given by elementId. If no such
element exists, returns null. Behavior is not defined if more
than one element has this id.

"Parameters
elementId
The unique id value for an element."

<URL:http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-36113835>

In other words, it must be unique and if not, the behavior is
not defined. Quite a bit different from your guess - got a
reference?

Further more, the HTML specification is even more explicit:

"ID
This attribute assigns a name to an element. This name must be
unique in a document.

"...The id attribute assigns a unique identifier to an
element...

"...Note that the French "msg1" and the English "msg1" may not
appear in the same document since they share the same id
value."

<URL:http://www.w3.org/TR/html4/struct/global.html#adef-id>

You will also find a number of references in the anchors section
highlighting that *ID must be unique*


<URL:http://www.w3.org/TR/html4/struct/links.html#anchors-with-id>


The specification absolutely unequivocal: ID must be unique.

Furthermore, ID and NAME share the same namespace so the only
way to have an identical name and id in the same document is for
them to be on the same element (either A, APPLET, FORM, FRAME,
IFRAME, IMG, or MAP), and in that case they *must* be
identical. Name need not be unique, but when used as an anchor
it must be.

Most browsers will return the first element if two have
identical IDs - but it is not part of the W3C standard.
so the functionality of that part should be standard

Not at all. The "functionality" is undefined.
standard (Although giving multiple elements the same id is certainly bad
programming practice);

Not just bad, but it will create invalid HTML.
 
Z

Zifud

John said:
Actually W3C specifies that getElementById returns the first element
with the supplied id...

Rubbish.

The W3C DOM 1 and 3 specs say the same thing:

"getElementById
"Returns the Element that has an ID attribute with the given
value. If no such element exists, this returns null. If more
than one element has an ID attribute with that value, *what is
returned is undefined.*" (my emphasis)

<URL:http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-getElBId>

The W3C specification actually says to return undefined. Most
browsers don't, being somewhat sympathetic they tend to return
the first element that matches. However, it is *not* the
behaviour specified by the W3C.

The HTML specification is unwavering in its insistence that id
be unique in a document:

"ID
This attribute assigns a name to an element. This name must be
unique in a document.

"...The id attribute assigns a unique identifier to an
element...

"...Note that the French "msg1" and the English "msg1" may not
appear in the same document since they share the same id
value."

<URL:http://www.w3.org/TR/html4/struct/global.html#adef-id>

You will also find a number of references in the anchors section
highlighting that *ID must be unique*


<URL:http://www.w3.org/TR/html4/struct/links.html#anchors-with-id>

The specification is absolutely unequivocal: ID must be unique.

Furthermore, ID and NAME share the same namespace so the only
way to have an identical name and id in the same document is for
them to be on the same element (either A, APPLET, FORM, FRAME,
IFRAME, IMG, or MAP) and in that case they *must* be
identical. Name need not always be unique, but when used as an
anchor, it must be.

Most browsers will return the first element if two have
identical IDs - but it is not part of the W3C standard.
...so the functionality of that part should be
standard...

The functionality is common, but not standard.

Browsers that return the first element with the duplicate ID do
so for the sake of tolerance of invalid markup, not because they
are compelled to do so for standards compliance. Making the
operation of pages dependent on this "feature" is like refusing
...(Although giving multiple elements the same id is certainly bad
programming practice)

Not just bad practice, it creates invalid HTML and depends on
the successful operation of an unspecified "feature".
 
M

Martin Honnen

John said:
Actually W3C specifies that getElementById returns the first element
with the supplied id, so the functionality of that part should be
standard

No idea where you think the W3C states that but the current DOM Level 2
Core in
<http://www.w3.org/TR/DOM-Level-2-Core/core.html#i-Document>
clearly says about getElementById on the document node:
"Behavior is not defined if more than one element has this ID."
What about the insertAdjacent? Also not in the official DOM
methinks.

insertAdjacentHTML in IE's DOM cannot be done with DOM Level 1 and 2 API
as it requires parsing of markup obviously, with Mozilla however it
can be emulated as Mozilla has an extension to parse HTML.
insertAdjacentElement can be done but while in IE's DOM you call that
method on one node and then the argument e.g. 'afterEnd' decides on the
actual parent the node is inserted in in the W3C DOM you will need to
have your code find the right place to insert so
element.insertAdjacentElement('beforeEnd', newElement)
would translate to
element.appendChild(newElement)
and
element.insertAdjacentElement('afterBegin', newElement)
to
element.insertBefore(newElement, element.firstChild)
while for
element.insertAdjacentElement('beforeBegin', newElement);
you need
var parentNode = element.parentNode;
if (parentNode) {
parentNode.insertBefore(newElement, element);
}
and for
element.insertAdjacentElement('afterEnd', newElement)
should be
var parentNode = element.parentNode;
if (parentNode) {
parentNode.insertBefore(newElement, element.nextSibling);
}

All written down from memory and not tested at all so don't rely blindly
on that.
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Fri, 28
Jan 2005 05:14:00, seen in Zifud
The W3C DOM 1 and 3 specs say the same thing:

"getElementById
"Returns the Element that has an ID attribute with the given
value. If no such element exists, this returns null. If more
than one element has an ID attribute with that value, *what is
returned is undefined.*" (my emphasis)

<URL:http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-
getElBId>

The W3C specification actually says to return undefined.


I don't know what W3C intended to mean.

But the quoted words mean that what is returned is nor defined,
uncertain, unreliable, etc.; not that the special state _undefined_ is
required to be returned.

However, if the quoted "undefined" was textually distinguished, it might
stand for the special value.

Tip to W3C and others : when defining a language in which a special
value called "undefined" exists, never use the word "undefined" where
"not defined" would do.
 
J

John Doe

No idea where you think the W3C states that but the current DOM Level 2
Core in
<http://www.w3.org/TR/DOM-Level-2-Core/core.html#i-Document>
clearly says about getElementById on the document node:
"Behavior is not defined if more than one element has this ID."
You are right of course. I feel both sheepish and chastened. Don't
know where I got that. It wasn't from M$ and it (obviously) wasn't from
the W3C. I'll be more careful about who I'm relying on in the future.
Thanks for the tip on the alternative to adjacentelement code.
 
R

Richard Cornford

Dr John Stockton wrote:
Tip to W3C and others : when defining a language in which
a special value called "undefined" exists, never use the
word "undefined" where "not defined" would do.

The W3C DOM specifications are intended to be programming language
neutral, expressing their interface definitions in IDL (rather than any
of the languages for which they explicitly provide binding documents).
As a result the term 'undefined' should have no meaning other than its
common English usage in that context. Within the DOM binding documents
specifically aimed at ECMAScript the term might be more ambiguous.

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top