appendChild(), remove Child()

K

Ken

I am trying to create one image using JavaScript; then later in the script
remove the image - not just remove the src.
The following creates the image, but I have been unable to remove it.

How do I structure
document.getElementById('num1').removeChild(image_display); ?

<input type=file name="picture1" onChange="image(this.value, 'num1');"
Id="pt1">
<div id='num1'></div>

<script type="text/javascript">
function image_size(field, num){
image_display=document.createElement('img');
image_display.src=field;
document.getElementById('num1').appendChild(image_display);
..
..
..
document.getElementById('num1').removeChild(image_display);
}
</script>

Thanks for help.

Ken
 
R

RobG

Ken said:
I am trying to create one image using JavaScript; then later in the script
remove the image - not just remove the src.
The following creates the image, but I have been unable to remove it.

How do I structure
document.getElementById('num1').removeChild(image_display); ?

<input type=file name="picture1" onChange="image(this.value, 'num1');"
Id="pt1">
<div id='num1'></div>

<script type="text/javascript">
function image_size(field, num){
image_display=document.createElement('img');

You should at least test if "field" has a value:

if (field != '') {
....

If the user has entered some text, then cleared the text box, you will
add a broken image tag. You could test to see if it is valid file
path, but you can't determine if the file itself actually exists. You
should add a reset button so at least the user can clear the box
without creating a broken tag.

image_display.src=field;

This only works in IE (AFAIK). To make it work in other browsers (and
still keeping it working in IE), use:

image_display.src='file://' + field;
document.getElementById('num1').appendChild(image_display);

You have created image_display as a global variable. If the user adds
multiple images, each one gets the same variable name. "image_display"
will only refer to the last image added (or the last image object
created, even if the file path was invalid).
document.getElementById('num1').removeChild(image_display);

So your remove will only remove the last one and "image_display" will
reference a non-existent object. I'm not sure why the above doesn't
work (I'm sure one of the lurking experts will fill us in) but the
below code does:

image_display.parentNode.removeChild(image_display);

Note that the above tips just get your code to work (more or less),
there are lots of usability issues to deal with, such as:

- how will a user remove a specific image, not just the last one added?
- how to prevent adding a new image every time the field changes?
(hint: add a button to add the image, don't use onchange)
- if the file doesn't exist, how will you avoid a broken img tag?
- how will you control how many images a user adds to a page?

Cheers, Rob.
 
R

RobG

RobG wrote:
[snip]
add a broken image tag. You could test to see if it is valid file
path, but you can't determine if the file itself actually exists. You
[snip]

What I meant is that you can check the syntax using regex, but not
whether the path or file actually exists.

Cheers, Rob.
 
J

J. J. Cale

Ken said:
I am trying to create one image using JavaScript; then later in the script
remove the image - not just remove the src.
The following creates the image, but I have been unable to remove it.

How do I structure
document.getElementById('num1').removeChild(image_display); ?

You can use a DOM reference which will no longer be valid after you use it.
In the example below the first click deletes the img the next the btn.

<HTML><HEAD><TITLE></TITLE></HEAD>
<BODY>
<img id="num1" src="my.gif">
<button
onclick="document.body.removeChild(document.body.childNodes[0])">Click to
remove image</button>
</BODY></HTML>

any reference that the browser can use is fine in place of
document.body.childNodes[0]
e.g. MS
document.body.removeChild(num1);
document.body.removeChild(document.all.num1);
e.g. MS6 and others
document.body.removeChild(document.getElementById('num1');
and also the tags collection but I don't remember the syntax offhand
my preference
document.body.removeChild(window['num1']);
I think bracket reference is supported all UA's but I'm sure someone will
correct me if not.
Hope this helps.
Jimbo
 
K

Ken

Ken said:
I am trying to create one image using JavaScript; then later in the script
remove the image - not just remove the src.
The following creates the image, but I have been unable to remove it.

How do I structure
document.getElementById('num1').removeChild(image_display); ?

<input type=file name="picture1" onChange="image(this.value, 'num1');"
Id="pt1">
<div id='num1'></div>

<script type="text/javascript">
function image_size(field, num){
image_display=document.createElement('img');
image_display.src=field;
document.getElementById('num1').appendChild(image_display);
.
.
.
document.getElementById('num1').removeChild(image_display);
}
</script>

Thanks for help.

Ken
I have been experimenting with both approaches. The results have been
inconsistent. Sometime the approach works and other times it does not.
I have tried to display the tree associated with Id=num1 with little
results. I keep getting either undefined or [object].

How can I display the tree (parent, children, etc...tags)?
i.e.the tag <img src=field name=?? >

Ken
 
R

RobG

Ken said:
I have been experimenting with both approaches. The results have been
inconsistent. Sometime the approach works and other times it does not.
I have tried to display the tree associated with Id=num1 with little
results. I keep getting either undefined or [object].

How can I display the tree (parent, children, etc...tags)?
i.e.the tag <img src=field name=?? >

The solution I provided works with any browser that supports the
DOM. Your problem is reliably identifying the image the user wants to
delete. I suggest that when you add the image, add a DIV and a remove
button, then the user just clicks on the remove button next to or below
the image to remove it. You can use then use this.form.parentNode to
get the DIV that the image is in rather than trying to remember the
name of specific images.

My method would be to use a DOM method to create a new DIV and make it
a child of your num1 div. Then I'd use innnerHTML to add the image and
remove button. The remove button would look something like:

<form action="">
<input type="button" value="Remove this image"
onclick="removeImage(this.form.parentNode)";>
</form>


The removeImage function therefore gets a reference to the div to
remove. You can then just use theDiv.parentNode.removeChild(theDiv).

Here is a simple DOM walk that you can use. It would be much better to
use a browser that has a DOM viewer (nearly any browser other than IE),
but if you are really stuck, use the one below.

Cheers, Rob.

<html>
<head>
<title> DOM Tree </title>

<script type="text/javascript">
// shows the DOM with index
function showDOM() {
var msg = "";
function listNodes(n,x) {
msg += x + ' ' + n.nodeName
if (n.name) msg += ' name is: ' + n.name;
if (n.value) msg += ' value is: ' + n.value;
if (n.src) msg += ' src is: ' + n.src;
msg += '\n';
for (var i=0; i<n.childNodes.length; i++) {
listNodes(n.childNodes,x + '.' + i);
}
}
listNodes(document.getElementsByTagName("body")[0],'0');
alert(msg);
}
</script>

</head>
<body>
<form action="" name="theForm">
<input type="button" value="Show DOM" name="theButton"
onclick="showDOM();">
</form>
<p>below is a broken img tag</p>
<img src="blah.gif">
</body>
</html>
 
R

RobG

Ken said:
Ken said:
I am trying to create one image using JavaScript; then later in the script
remove the image - not just remove the src.
The following creates the image, but I have been unable to remove it.
[snip]

I have been experimenting with both approaches. The results have been
inconsistent. Sometime the approach works and other times it does not.
I have tried to display the tree associated with Id=num1 with little
results. I keep getting either undefined or [object].

Below is some code to add and remove images to a page from a local file
system. Tested in IE 6 and Firefox, modify for your purpose.

If you are trying to add an image, then remove it within the one
script, I suggest you split the add and remove bits to separate
functions and call them from your main script. IE and other browsers
seem a little finicky about adding/removing items within the one script,
putting them into separate functions makes them work perfectly for me.

Rob.


<html>
<head><title>Add your images...</title>
<style type="text/css">
body
{font-family: arial, sans-serif;}
p
{font-size: 80%;}
div
{border-bottom: thin solid blue;
padding: 10 0 10 0;
}
</style>

<script type="text/javascript">
function addImage(p,d){
// alert(p);
if (p == '') {
alert('Please enter file path to your image,'
+ ' or use the \'Browse...\' button'
+ '\nto locate an image to add to the page, then '
+ 'click the "Add image" button');
return;
} else {
if (document.getElementById) {
newDiv = document.createElement('div');
document.getElementById(d).appendChild(newDiv)
var tagText = ''
+ '<img src="' + 'file://' + p
+ '" alt="' + p + '"><br>'
+ '<form action="">'
+ '<h3>Image path: ' + p
+ '<input type="button" style="margin-left: 20;"'
+ ' value="Click to remove image"'
+ ' onclick="removeImage(this.form.parentNode);">'
+ '</h3>'
+ '</form>'
;
newDiv.innerHTML = tagText;
} else {
alert('No support for getElementById.\n'
+ 'Use another method');
} } }

function removeImage(x) {
// alert(x);
x.parentNode.removeChild(x);
}
</script>
</head>
<body>
<h2>Add images to this page</h2>
<form action="">
<p>
<label title="Choose an image to upload" for="filePath">
<span style="color: 336699;">&nbsp;File path....</span>
<br>
<input type="file" id="filePath"
name="filePath" size="60"></label>
<label title="Add an image to this page">
<input type="button" value="Add image"
onclick="addImage(this.form.filePath.value,'imageDiv');">
</label>
<label title="Clear the file path">
<input type="reset" value="Reset"></label>
</p>
</form>
<div id="imageDiv"
style="border-top: thin solid blue; border-bottom: none;"></div>
</body>
</html>
 
K

Ken

RobG said:
Ken said:
I have been experimenting with both approaches. The results have been
inconsistent. Sometime the approach works and other times it does not.
I have tried to display the tree associated with Id=num1 with little
results. I keep getting either undefined or [object].

How can I display the tree (parent, children, etc...tags)?
i.e.the tag <img src=field name=?? >

The solution I provided works with any browser that supports the
DOM. Your problem is reliably identifying the image the user wants to
delete. I suggest that when you add the image, add a DIV and a remove
button, then the user just clicks on the remove button next to or below
the image to remove it. You can use then use this.form.parentNode to
get the DIV that the image is in rather than trying to remember the
name of specific images.

My method would be to use a DOM method to create a new DIV and make it
a child of your num1 div. Then I'd use innnerHTML to add the image and
remove button. The remove button would look something like:

<form action="">
<input type="button" value="Remove this image"
onclick="removeImage(this.form.parentNode)";>
</form>


The removeImage function therefore gets a reference to the div to
remove. You can then just use theDiv.parentNode.removeChild(theDiv).

Here is a simple DOM walk that you can use. It would be much better to
use a browser that has a DOM viewer (nearly any browser other than IE),
but if you are really stuck, use the one below.

Cheers, Rob.

<html>
<head>
<title> DOM Tree </title>

<script type="text/javascript">
// shows the DOM with index
function showDOM() {
var msg = "";
function listNodes(n,x) {
msg += x + ' ' + n.nodeName
if (n.name) msg += ' name is: ' + n.name;
if (n.value) msg += ' value is: ' + n.value;
if (n.src) msg += ' src is: ' + n.src;
msg += '\n';
for (var i=0; i<n.childNodes.length; i++) {
listNodes(n.childNodes,x + '.' + i);
}
}
listNodes(document.getElementsByTagName("body")[0],'0');
alert(msg);
}
</script>

</head>
<body>
<form action="" name="theForm">
<input type="button" value="Show DOM" name="theButton"
onclick="showDOM();">
</form>
<p>below is a broken img tag</p>
<img src="blah.gif">
</body>

Rob,
Thanks for the DOM tree script. It is a big help to see the parent, child,
etc relationsionships.

I now have the add and remove image working. I would appreciate your
comments on three questions:
1. Over the various browsers, is it better to use:
document.getElementById('num1').removeChild(image_display);
or
image_display.parentNode.removeChild(image_display);

2. Do most of the newer version browsers (Mozilla, IE, Firefox, etc)
accept the above scripts?

3. I would like to measure the fileSize of the image. I use:
var size_pic = document.getElementById('num1').childNodes[0].fileSize;
alert("size = " + size_pic);
which works with one exception.

With a first time displayed image, the first time the script displays a size
= -1 The image is displayed on the first pass. The fileSize script is
after the image is img script.
The second pass is correct. size = 11479

Is this a cache problem? The first pass caches the file, the second pass
reads the file?
I tried running - var size_pic =
document.getElementById('num1').childNodes[0].fileSize; - twice but that
made no difference.

Is there a work around for this problem.

Is there a better way to measure filesize in JavaScript?

Have a good day!

Ken
 
R

RobG

Ken wrote:
[snip]
I now have the add and remove image working. I would appreciate your
comments on three questions:
1. Over the various browsers, is it better to use:
document.getElementById('num1').removeChild(image_display);
or
image_display.parentNode.removeChild(image_display);

I'm certainly no expert on either JavaScript or the DOM, so if Mike
Winter or one of the other gurus is lurking, I'd love to hear their
opinion. If they don't post in a day or so, create a new post and ask
the question there.

My opinion is that if you pass a reference to the object (as I've done
in the working example) you don't need to use getElementById, which is
reasonably new, and therefore likely to be more widely compatible. So
I guess that makes the parentNode method 'better'. It also means you
aren't using a hard coded reference to an element ID ('num1') - though
you are using it to add the image in the first place, so perhaps it's a
moot point.

Since you already have a reference in 'image_display', I don't see the
point in using getElementById a second time.
2. Do most of the newer version browsers (Mozilla, IE, Firefox, etc)
accept the above scripts?

Yes. I usually test in IE 6, Mozilla, Firefox, Netscape, Safari and
don't have any issues with DOM or document node stuff. BUT I don't
develop for the web like many here do so my opinion is not particularly
useful. I develop intranet applications and my interest in
cross-platform compatibility is more for philosophical motives than
practical necessity.

Generally speaking, if you work in Firefox and test in IE you will do
OK. Mozilla, Netscape and Firefox are so similar as to be nearly the
same (but not quite), Safari is pretty similar too but it is a tad
immature (particularly as you have to buy OS X upgrades to get the
latest version, so many Mac users don't have it).
3. I would like to measure the fileSize of the image. I use:
var size_pic = document.getElementById('num1').childNodes[0].fileSize;
alert("size = " + size_pic);
which works with one exception.

Beyond my knowledge, I'm afraid. If you don't get an answer in a day
or so, post it as a new thread.

Cheers, Rob.
 
R

RobG

Ken wrote:
[snip]
Is there a better way to measure filesize in JavaScript?

I decided to have a play, and found the following:

1.
On Windows -
When adding a file using an input type="file", you must add "file://"
to the front of the path returned by the file dialog or Firefox on
Windows will not find the path. Prepending "file://" works in IE on
Windows too, but is not needed, you can just use the path returned by
the dialog.

On Mac -
"file://" works with Safari, Camino, Firefox but not IE

"" (don't add anything) works with all the above but not IE

"file:/" (just one slash) works in IE only - go figure. IE kept
crashing too, not a good sign.

This may be a legitimate excuse for browser detection - I'd probably go
for "file://" and try to detect IE on Mac and do "file:/".

2.
When adding the image, IE adds a full set of attributes but doesn't
give them values unless you add them yourself. All the other browsers
only add the attributes that you give the image yourself, so IE has a
big list of empty attributes (even height and width are empty) and the
others have a short list of just the ones you added (src + alt in my
example).

So there is no way of getting the file size or height/width in any
browser I tested - you can likely do it in IE on Windows only (there
was a recent thread on this and I think that was the consensus).

Cheers, Rob.
 

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

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,196
Latest member
ScottChare

Latest Threads

Top