PDA

View Full Version : Creating, moving, and deleting DIVs


Sykoi
07-12-2007, 08:19 PM
I need to do the following with javascript and DOM:

Create a new div: I need to create a div, inside or outside of a parent and assign an ID I come up with, based on other code (This part isn't important, obviously - as long as I'm able to change the id while creating it)
Move a div: I need to be able to move a div from one parent, to another... Such as moving it from div id="a" to div id="b"
Delete a div: Completely remove it from memory (If possible), or if not - clear the contents completely, and reset all the style information to default


I'm a bit of a newbie to DOM, so I don't quite understand what its capable of - so if its not capable of all of the above, I need to know what is.

Thanks in advance.

Arbitrator
07-12-2007, 11:27 PM
var element = document.createElement("div"); // create
element.setAttribute("id", "elementId"); // assign id attribute
document.getElementById("a").appendChild(element); // append as child of #a
document.getElementById("a").removeChild(element); // remove
document.getElementById("b").appendChild(element); // append as child of #b
document.getElementById("b").removeChild(element); // remove
delete element; // deletes the element
/* delete doesn’t seem to work in Firefox 2.
element = null; or element = undefined; seem to work.
I don’t how you would tell if it was deleted from memory though. */

Learner Resources:

http://www.quirksmode.org/dom/w3c_core.html (compatibility tables are dated, but still useful for learning)
http://www.webdevout.net/browser-support-dom (also links to every specification)

GJay
07-12-2007, 11:58 PM
once you've added the element to something in the document, you can use

element.parentNode.removeChild(element);

Sykoi
07-13-2007, 02:46 AM
Thanks, I have one more question.... How do I add/modify/remove content from the newly created div?

Edit: Nevermind... innerHTML, right?


I'm having some problems with my code:

<script language="javascript" type="text/javascript">
var element = document.createElement("div"); // create
element.setAttribute("id", "elementId"); // assign id attribute
element.setAttribute("class", "test");
element.setAttribute("background", "#FF0000");
element.setAttribute("height", "400px");
element.setAttribute("width", "400px");
document.getElementById("abc").appendChild(element);

</script>

<div id="abc">ff</div>


Its not working in either IE6 or FF...

Arbitrator
07-13-2007, 03:56 AM
Thanks, I have one more question.... How do I add/modify/remove content from the newly created div?

Edit: Nevermind... innerHTML, right?You can use innerHTML, but know that it’s a technology proprietary to Microsoft (even though other browsers support it). DOM methods are shown in the two resources that I linked to in my previous post. The first resource also shows non‐DOM methods. Even if you opt for the Microsoft method, you should still know how to use the DOM methods.

I'm having some problems with my code:

<script language="javascript" type="text/javascript">
var element = document.createElement("div"); // create
element.setAttribute("id", "elementId"); // assign id attribute
element.setAttribute("class", "test");
element.setAttribute("background", "#FF0000");
element.setAttribute("height", "400px");
element.setAttribute("width", "400px");
document.getElementById("abc").appendChild(element);
It’s not working for three reasons.

The first is probably because the div element doesn’t exist by the time the script is processed. You need to either create an event listener for the load event or call the script after the div element is loaded (e.g., move the script element to the end of the body element). I’ve recently decided that the latter approach is better since the load event is not triggered until everything is loaded, including all images. If you want to listen for the load event anyway, the three methods are shown below:

// function refers to the function to load
document.defaultView.addEventListener("load", function, false); // W3C DOM method
window.attachEvent("onload", function); // Microsoft method
window.onload = function; // the so‐called traditional method

For an good understanding of the three event models, I recommend checking out the the “Events” section of the site QuirksMode (http://www.quirksmode.org/sitemap.html#link9).

The second is that you’re trying to set attributes that don’t exist (background, height, and width). If you want to add presentation, add class names via a class attribute or use the methods of DOM2 Style.

Internet Explorer has a third issue to add to that; it thinks that the class attribute is named className even when called with setAttribute. For that reason, I use the shorthand in the Internet Explorer copies of my scripts: element.className = "test"; I only use the shorthand for that attribute though. When using the shorthand, the representation className is correct; it was changed to that since the word “class” conflicts with something else in JavaScript.

As a side note, you can get rid of the language attribute. No modern browser requires that and it’s formally deprecated anyway.

Sykoi
07-13-2007, 03:08 PM
Thanks again, I got it working in IE but not FF now... It adds the div as a child to abc, changes the className, but the style changes don't show up (In FF, it works fine in IE).

As in, it won't change the background color, height, and width of the newly created div.


<style type="text/css">
.test
{
background:#00FF00;
width: 500px;
height: 500px;
}
</style>

function dom_test() {
var element = document.createElement("div"); // create
element.setAttribute("id", "elementId"); // assign id attribute
element.setAttribute("className", "test");
document.getElementById("abc").appendChild(element);
}

<div id="abc"><a onClick="dom_test();">ff</a></div>




Edit:
I just realized I may have a bit of a problem in the future... The purpose of all this is to be able to create divs using data received from AJAX, and to prevent users from flooding the server with requests if they already have the information in memory... Users will need to be able to call these functions (below) on a regular basis for several different reasons, and thus - spawn several different divs.
The problem I see is - how will I be able to spawn, track, and delete these with a unique ID? (Var element, AND setAttribute id)



function dom_test() {
var element = document.createElement("div"); // create
element.setAttribute("id", "elementId"); // assign id attribute
element.setAttribute("className", "test");
document.getElementById("abc").appendChild(element);
}

function dom_delete() {
document.getElementById("a").removeChild(element); // remove
delete element; // deletes the element
}

(Dom delete was just created as an example of this problem)

I was thinking about the other parts of the script sending the unique id through the function as a var, but I have no idea how to use a variable as a variable name... Like, instead of var element - using var (Var from function()).
Its possible in PHP, but is it possible in JS? Whats the best way to go about doing this?



Edit #2:
Is there a way to move a div before, and after another div? Such as:

<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
<div id="4"></div>
<div id="5"></div>


If I want to move 3 up one on every mouse click of a link, or 1 down every mouse click.
I know I can just make a table, or something along those lines - but it'd be nice if there was another way.

And on a related note, if there IS a way to do this, would the divs switch place (2 and 3 switching places, for instance), or would there be a gap where 3 used to be?

Arbitrator
07-14-2007, 12:12 AM
Thanks again, I got it working in IE but not FF now... It adds the div as a child to abc, changes the className, but the style changes don't show up (In FF, it works fine in IE).The problem is that you’re using the name className via setAttribute in an attempt to reference the attribute class. This works fine in Internet Explorer due to a bug; it will not work in standards‐compliant browsers, however. You have two options here: (A) split the script into standards‐compliant and Internet Explorer‐only versions or (B) use the shorthand, which Internet Explorer handles correctly.

Method A
<!-->-->
<script type="application/ecmascript">
element.setAttribute("class", value);
</script>
<!--<![endif]>-->
<!--[if !IE]>-->
<script type="text/javascript">
// technically correct
element.className = value);
// technically incorrect, but allows use of the setAttribute method
element.setAttribute("className", value);
</script>
<!--<![endif]>-->

Method B
<script type="text/javascript">
element.className = value);
</script>

I, personally, use method A, which utilizes Microsoft conditional comments (http://www.quirksmode.org/css/condcom.html), although it’s a bit wasteful in this particular example.

I just realized I may have a bit of a problem in the future... The purpose of all this is to be able to create divs using data received from AJAX, and to prevent users from flooding the server with requests if they already have the information in memory... Users will need to be able to call these functions (below) on a regular basis for several different reasons, and thus - spawn several different divs.
The problem I see is - how will I be able to spawn, track, and delete these with a unique ID? (Var element, AND setAttribute id)



function dom_test() {
var element = document.createElement("div"); // create
element.setAttribute("id", "elementId"); // assign id attribute
element.setAttribute("className", "test");
document.getElementById("abc").appendChild(element);
}

function dom_delete() {
document.getElementById("a").removeChild(element); // remove
delete element; // deletes the element
}

[i](Dom delete was just created as an example of this problem)

I was thinking about the other parts of the script sending the unique id through the function as a var, but I have no idea how to use a variable as a variable name... Like, instead of var element - using var (Var from function()).
Its possible in PHP, but is it possible in JS? Whats the best way to go about doing this?I know JavaScript and XML, but not AJAX. I’m not sure what you mean, but a guess is shown below.

function dom_test() {
var element = document.createElement("div"); // create
element.setAttribute("id", "elementId"); // assign id attribute
element.setAttribute("class", "test");
document.getElementById("abc").appendChild(element);
}
function dom_delete(elementId) {
var element = document.getElementById(elementId);
element.parentNode.removeChild(element); // remove
delete element; // deletes the element
}
dom_delete("elementId");

Edit #2:
Is there a way to move a div before, and after another div? Such as:

<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
<div id="4"></div>
<div id="5"></div>


If I want to move 3 up one on every mouse click of a link, or 1 down every mouse click.
I know I can just make a table, or something along those lines - but it'd be nice if there was another way.Just FYI, ID names are not allowed to start with a number.

I’ve thought about it some and I’m not sure exactly how one would do it without making the code too specific. I’m thinking that some combinations of some of previousSibling, replaceChild, cloneNode, removeNode, and insertBefore ought to be able to do this. One of the problems is accounting for white‐space text nodes between the div elements. Then again, there should be no such nodes if all of those div elements are dynamically generated; that would make things easier, since one would be able to use previousSibling directly:

if (element.previousSibling) {
var sibling = document.getElementById(element.previousSibling.getAttribute("id"));
sibling.parentNode.insertBefore(sibling.parentNode.removeChild(element), sibling);
}I’m not sure if the above would work though, since sibling might cease to exist the moment you remove element. One could use element.cloneNode(true) and subsequently remove element, but that would temporarily invalidate the document and might cause issues since there would be two elements with the same ID in the document simultaneously.

I guess I’ll have to research this further.

if (element.previousSibling) {
var sibling = document.getElementById(element.previousSibling.getAttribute("id"));
sibling.parentNode.insertBefore(sibling.parentNode.removeChild(element), sibling);
}

And on a related note, if there IS a way to do this, would the divs switch place (2 and 3 switching places, for instance), or would there be a gap where 3 used to be?You could make a script do either.

Sykoi
07-14-2007, 07:59 PM
Thanks for the help so far, its all starting to make sense, however I have to clear up the AJAX part...
I need a way to store the object (Var element), so I can call delete, and other DOM functions with it.

Could I just add it to an (object) array, like:

array['objects']['object1'] = element;

Then call:
array['objects']['object1'].DOM_stuff
or
delete array['objects']['object1']
or
document.getElementById("a").removeChild(array['objects']['object1'])

Arbitrator
07-15-2007, 08:31 AM
Thanks for the help so far, its all starting to make sense, however I have to clear up the AJAX part...
I need a way to store the object (Var element), so I can call delete, and other DOM functions with it.

Could I just add it to an (object) array, like:

array['objects']['object1'] = element;

Then call:
array['objects']['object1'].DOM_stuff
or
delete array['objects']['object1']var elements = [];
function dom_test() {
index = elements.push(document.createElement("div"));
element[index].setAttribute("id", "elementId");
element[index].setAttribute("class", "test");
document.getElementById("abc").appendChild(element[index]);
}
function dom_delete(elementId) {
for (var i = 0; i < elements.length; i++) {
if (elements[i].getAttribute("id") == elementId) {
delete elements[i];
break;
}
}
}
dom_delete("elementId");

As previously mentioned, I was going to research the moving elements issue. [1]

[1] http://www.jsgp.us/demos/CF118628N2.html