getElementById problem with Firefox

R

Robi

I have the following problem:
I populate a page with a specific amount of <div id="MyTest"> containers inside another <div> container.

for (i=0; i < MyString.length; i++)
document.write('<div id="MyTest"
style="position:absolute;top:0px;left:0;height:12;width:12;text-align:center">'+MyString+'</div>');

Now if MyString contains 6 characters, I end up with 6 <div id="MyTest"> containers.

With IE I am able to access these containers as follows:

for (i=0; i < MyString.length; i++) {
var Obj=MyTest.style;
Obj.top=NewPositionTop;
Obj.left=NewPositionLeft+i;
}

Now with Firefox this didn't work
Javascript Error: file:///c:/test/mytest.js, line 209: MyTest has no properties

and the Javascript Console suggests:
Warning: Element referenced by ID/NAME in the global scope. Use W3C standard document.getElementById() instead.

so I decided to use getElementById(), but keep getting errors.
I tried:
Obj1=document.getElementById("MyTest");
and then access Obj1.style.top/left but

Javascript Error: file:///c:/test/mytest.js, line 210: Obj1 has no properties

I also tried Obj=document.getElementById("MyTest").style;

with the same result.

What is it that keeps me from accessing a specific entry in the getElementById("MyTest") list/array?

can anyone point me in the right direction?

Thanks, Robi
 
M

Michael Winter

I have the following problem:
I populate a page with a specific amount of <div id="MyTest"> containers inside another <div> container.

You cannot do that. An id attribute value must be unique throughout an
entire document.
for (i=0; i < MyString.length; i++)
document.write('<div id="MyTest" [...]

As you're writing each element, you can append the value of i to produce
unique values.

[snip]
With IE I am able to access these containers [using a global variable with the same name]

Yes, you can. However, this is a terrible feature in my opinion, and you
shouldn't use it.

[snip]
Obj1=document.getElementById("MyTest");
and then access Obj1.style.top/left but


The getElementById method returns a single element, not a collection,
because there should only ever be one element with a matching value. If
you do have multiple potential matchs, the most common result is that
first (in source order) will always be returned.

Continuing the suggestion above, you can alter your code to:

var obj = document.getElementById('MyTest' + i);

if(obj && obj.style) {
/* ... */
}

[snip]

Mike
 
A

ASM

Robi said:
I have the following problem:
I populate a page with a specific amount of <div id="MyTest"> containers inside another <div> container.

for (i=0; i < MyString.length; i++)
document.write('<div id="MyTest"
style="position:absolute;top:0px;left:0;height:12;width:12;text-align:center">'+MyString+'</div>');


it is not allowed to have more than 1 element with same ID !

so try something as :

myHtml = '';
for (i=0; i < MyString.length; i++)
myHtml += '<div id="MyTest'+i+'"'+
'style="position:absolute;top:0px;left:0;height:12;width:12;text-align:center">'+
MyString+'</div>');
document.write(myHtml);

Would be better to have a separte css to do not copy same thing x times
With IE I am able to access these containers as follows:

for (i=0; i < MyString.length; i++) {
var Obj=MyTest.style;
Obj.top=NewPositionTop;
Obj.left=NewPositionLeft+i;
}


yes that's IE way of work

try :
for (i=0; i < MyString.length; i++) {
var Obj = document.all?
MyTest.style :
document.getElementById?
document.getElementById('MyTest'+i).style :
document.layers['MyTest'+i] ;
Obj.top = NewPositionTop+'px';
Obj.left = NewPositionLeft+'px';
}

Notice that document.write()
is not an "up to date" way to script
See : createElement and appendChild
See also : cloneNode (ask to google)
 
R

Robi

Michael said:
I have the following problem:
I populate a page with a specific amount of <div id="MyTest"> containers
inside another <div> container.

You cannot do that. An id attribute value must be unique throughout an
entire document.
for (i=0; i < MyString.length; i++)
document.write('<div id="MyTest" [...]

As you're writing each element, you can append the value of i to produce
unique values.

[snip]
With IE I am able to access these containers [using a global variable with the same name]

Yes, you can. However, this is a terrible feature in my opinion, and you
shouldn't use it.

Thanks, will avoid/omit the use of it from now on.
Obj1=document.getElementById("MyTest");
and then access Obj1.style.top/left but


The getElementById method returns a single element, not a collection,
because there should only ever be one element with a matching value. If
you do have multiple potential matchs, the most common result is that
first (in source order) will always be returned.

Continuing the suggestion above, you can alter your code to:

var obj = document.getElementById('MyTest' + i);

if(obj && obj.style) {
/* ... */
}


well, I did "forget" to mention in my post, that that was the /workaround/
I used.
The script was written by someone else and I was trying to adapt it to work
at least in my browser as well. Somehow I did know that element IDs should
be unique in a document although when I saw this code I thought it was a
neat way to access the objects.

Thanks for your reply and for getting me out of my doubt if I had done it
correctly or not.

What I don't understand is why do you check for (obj && obj.style).
Wouldn't a check for just (obj.style) suffice? Besides, since I know I set
the style, wouldn't (obj) be enough?

Robi
 
R

Robi

ASM said:
Robi said:
I have the following problem:
I populate a page with a specific amount of <div id="MyTest"> containers inside another <div> container.

for (i=0; i < MyString.length; i++)
document.write('<div id="MyTest"
style="position:absolute;top:0px;left:0;height:12;width:12;text-align:center">'+MyString+'</div>');


it is not allowed to have more than 1 element with same ID !

except for IE ;-) , but then, Microsoft has always been special ;-)
so try something as :

myHtml = '';
for (i=0; i < MyString.length; i++)
myHtml += '<div id="MyTest'+i+'"'+
'style="position:absolute;top:0px;left:0;height:12;width:12;text-align:center">'+
MyString+'</div>');
document.write(myHtml);

Would be better to have a separte css to do not copy same thing x times


Thanks, I'll keep that in mind
With IE I am able to access these containers as follows:

for (i=0; i < MyString.length; i++) {
var Obj=MyTest.style;
Obj.top=NewPositionTop;
Obj.left=NewPositionLeft+i;
}


yes that's IE way of work

try :
for (i=0; i < MyString.length; i++) {
var Obj = document.all?

^^^^^^^^^^^^
[undefined] in my tests

I came up with
NS4=(document.layers)?1:0;
IE4=(document.all)?1:0;
W3C=(document.getElementById&&!document.all)?1:0;

MyTest.style :
document.getElementById?
document.getElementById('MyTest'+i).style :
document.layers['MyTest'+i] ;
Obj.top = NewPositionTop+'px';

^^^^
will need to keep this in mind too
Obj.left = NewPositionLeft+'px';
}

Notice that document.write()
is not an "up to date" way to script
See : createElement and appendChild
See also : cloneNode (ask to google)

as well as these :)


Merci

Robi
 
A

ASM

Robi said:
except for IE ;-) , but then, Microsoft has always been special ;-)

Oh! any browser would be glad with what you want in ID :)
clean JavaScript less, and W3C more less again

try :
for (i=0; i < MyString.length; i++) {
var Obj = document.all?

^^^^^^^^^^^^
[undefined] in my tests

Arrgghh ! :-(
I came up with
NS4=(document.layers)?1:0;
IE4=(document.all)?1:0;
W3C=(document.getElementById&&!document.all)?1:0;

why not.
as well as these :)

yeap !
but
was if you'ld like to learn few more about DOM :)
(there are so much possibilities using DOM)
 
R

Robi

Notice that document.write()
Ok, so far I've been "messing" around with
document.createElement(str tag)
document.createTextNode(str value)
and so on, and now, I have questions about the amount of options:
Id=documentCreateAttribute('id'); id.value='div1'; Div1=setAttributeNode(id);
versus
Div1=setAttribute('id','div1');
versus
Div1.id='div1';

which one is "better"?

I also have another problem which I've been trying to solve:
I can't get hold of the "body" object.
It is there in the document, but whatever I do, I always end up with the error:
Body has no properties
or
Body.item(0) has no properties

here's an excerpt of my monster:
//var Body=(document.getElementsByTagName)?document.getElementsByTagName("body").item(0):document.body;
//var Div0=Body.appendChild(document.createElement("div"));
// above didn't work
var Body=(document.getElementsByTagName)?document.getElementsByTagName("body"):document.body;
var Div0=Body.item(0).appendChild(document.createElement("div"));
// and neither did these
Div0.id=BaseId; Div0.style.position='absolute';
Div0.style.top='0px'; Div0.style.left='0px';
var Div1=Div0.appendChild(document.createElement("div")); Div1.style.position='relative';

the appendChild() method seems to be the culprit.

quest ce que c'est?

Robi "psycho chicken"
 
A

ASM

Robi said:
Ok, so far I've been "messing" around with
document.createElement(str tag)
document.createTextNode(str value)
and so on, and now, I have questions about the amount of options:

Wasn't it a good idea to go to see this profusion ? :)
Id=documentCreateAttribute('id'); id.value='div1'; Div1=setAttributeNode(id);

on my idea :
foo = document.CreateAttribute('id')
is to create an attribute nammed 'foo',
'foo' then to be use where you want by setAttributeNode.
You can start creating an element
(usualy a tag as DIV or P but could bee a child of a tag as some text)

so in the document (virtual html code of page)
1) you create an element : createElement(tag)
2) you create a text : createTextNode(text)
3) you create an attribute : createAttribute(attribute)
3b) you create the meaning of this attribute : nodeValue = string;

stil this moment we have bits of virtual code sowed somewhere in
computer mind

All what that for ?
to easily (?!) use and re-use them
to be compatible with XLM HXML
to get dynamism (without run to server and back)

So, on next step : we have to organise them
i.e : to give an aign to each td of page
foo = document.createAttribute('style');
foo.nodeValue = "right";
T = document.getElementsByTagName('TD');
for(var i=0;i<T.length;i++) T.setAttributeNode('foo');

That was a simple example you can modify in DOM1 ou JS as :
for(var i=0;i<T.length;i++) T.align='right';
or
for(var i=0;i<T.length;i++) T.style.textAlign='right';
but it suposes you did catch all TDs (with JS I don't know how to do)

other example :
var montitre = document.createElement("h1");
var monTexte = document.createTextNode("A very dynamical page");
montitre.appendChild(monTexte); // inserts monTexte in h1
// determine/get a space (to set the title h1)
var passagesortie = document.getElementById("here");
// place the title (just in end of the space 'passagesortie')
passagesortie.appendChild(montitre);

Try to realise this example by JS (with document.write()?)
after page has loaded -> not possible

All these commands and functions are for dynamic javascript
Some dynamism can be set with old JS (move, resize, scroll, attributes)
but not creations and/or insertions after loading

One of most interest is cloneNode
i.e.
form with a table with one row (article price quantity total button:add)
table with an id and set to hidden and non-display
table followed by a span or div whom use is contener for next insertions
and with same table (with other id and displayed and visible)
on each click on add button
hop! you clone invible table then put it in end of reserved space
(that's to say after the last table of form)
set its id, display and visible
With only a simple single table of one row you can grow your light page
to heavy and at buyer's satisfaction.

versus
Div1=setAttribute('id','div1');
versus
Div1.id='div1';

which one is "better"?

All depends ;-)
I also have another problem which I've been trying to solve:
I can't get hold of the "body" object.

mybody = document.getElementsByTagName('BODY')[0];
(1st element in tags tree of value 'body')
//var Div0=Body.appendChild(document.createElement("div"));

supposing you'd cath body
what you wrote is : put a new div in end of body
better doing :
mybody = document.getElementsByTagName('BODY')[0];
myDiv = document.createElement("div");
to be abble to do :
for(var i=0;i<5;i++) {
myDiv = document.createElement("div");
myBody.appendChild(myDiv);
myBody.lastChild.id = 'Id_'+i;
}

the appendChild() method seems to be the culprit.

quest ce que c'est?

I don't know. What is culprit ?

c'est pour placer un element precedemment cree
that's to set an element previously created
it inserts the element just in end of space given
Like that, later, you can get it with lastChild

last example :
http://fr.selfhtml.org/javascript/objets/node.htm#append_child
(no real english version on this site)

<html><head><title>Test</title></head>
<body>
<ol id="Liste">
<li>Element</li>
</ol>
<script language="JavaScript" type="text/javascript">
<!--
document.getElementById("Liste").removeChild(document.getElementById("Liste").firstChild);

for(var i = 0; i < 10; i++) {
var newLI = document.createElement("li");
var numeroli = i + 1;
var nouveautexteli = document.createTextNode("It is list element "+
"number " + numeroli);
document.getElementById("Liste").appendChild(newLI);
document.getElementsByTagName("li").appendChild(nouveautexteli);
}
//-->
</script>
</body></html>

remove the li
then create and insert 10 times : new li + new text in li
 
R

Robi

ASM said:
Robi wrote: [...]
Ok, so far I've been "messing" around with
document.createElement(str tag)
document.createTextNode(str value)
and so on, and now, I have questions about the amount of options:

Wasn't it a good idea to go to see this profusion ? :)
Grrrr! hein! mais non!
on my idea :
foo = document.CreateAttribute('id')
is to create an attribute nammed 'foo',
'foo' then to be use where you want by setAttributeNode.
You can start creating an element
(usualy a tag as DIV or P but could bee a child of a tag as some text)

yeah, that is all "easy" to unnerstand, or comprendre ;) pardon my french.

[...]
One of most interest is cloneNode

yep, although I can't implement it momentarily but will fool around with it too.

what I don't get is the diversity to get to the same point.
All depends ;-)

I think I have reached that deep end ;-)
deep ends on what?
I also have another problem which I've been trying to solve:
I can't get hold of the "body" object.

mybody = document.getElementsByTagName('BODY')[0];
(1st element in tags tree of value 'body')
[...]
the appendChild() method seems to be the culprit.

quest ce que c'est?

I don't know. What is culprit ?

ARRRGGGHHHHHHHHHHH!!!!!!!!!!!!!!!!
this hertz!

<html>
<head>
<title></title>
<stile></style>
<script>
var Body=document.getElementsByTagName("body")[0];
Body.appendChild(document.createElement("div")); //kabloom!! because <body> is not yet created!!!!
</script>
</head>
<body>
</body>
</html>

BTW happy quartz juliet (fete d'independence la marseillaise)
 
A

ASM

Robi said:
ARRRGGGHHHHHHHHHHH!!!!!!!!!!!!!!!!
this hertz!

<html>
<head>
<title></title>
<stile></style>
<script>
var Body=document.getElementsByTagName("body")[0];
Body.appendChild(document.createElement("div")); //kabloom!! because <body> is not yet created!!!!

it is not *because it is DOM* that *is not javascript*

of course you have to put your commands/instructions/calls
in a right JS meanning

document.createSomethingElseWhatYouWant
I think would be put where you want (but before you call it)
(it's yet nothing more that a new object without space for it in page)

but to call an object is only possible if it exists ... (evident)
getElementsByTagName() is a function getting a specific tag tree
not to use before the tree exists
remember DOM is to manipulate existing(*) elements

(*) - html elements must be firstable read by navigator
(body ends at end of page, really exists after loading)
- existing elements can be those you did create by JS script

Body.appendChild() is a function
it calls the shortcut Body
to affect him something
(here : insert an element at end of these belonging to Body)
</script>
</head>
<body>
</body>
</html>

Want to see (with FF) a terrific code to do a simple table ?
http://perso.wanadoo.fr/stephane.moriaux/truc/tablescript-sm.html
the script is not mine it's from here :
http://www.webreference.com/js/column44/tablescript5.html
where it doesn't work :-/

curiously insertion of virtual code appends fefore body last tag
(they do not use the body by its tag but by its id)

see you monday
 
M

Michael Winter

On 15/07/2005 00:16, Robi wrote:

[snip]
Id=documentCreateAttribute('id'); id.value='div1'; Div1=setAttributeNode(id);
versus
Div1=setAttribute('id','div1');
versus
Div1.id='div1';

which one is "better"?

The latter, in my opinion. The createAttribute method isn't supported in
IE versions prior to 6, and you'll have to make exceptions to the use of
the setAttribute method, as well.

For instance, when using the shortcut properties, one would alter the
class attribute using the className property. The name was changed
because class is a keyword in many languages (it's a future reserved
word in ECMAScript), so it's not usable with most language bindings.
However, the setAttribute method doesn't take identifiers as arguments;
it takes strings. A string literal can contain any word, keyword or not,
and indeed you should use

element.setAttribute('class', ...);

however IE is broken and still requires 'className'.
I also have another problem which I've been trying to solve:
I can't get hold of the "body" object.

When are you trying to access it? Elements are available only once
they've been parsed. Most of the time, parsing the opening tag is
sufficient, though if you're trying to interact with the contents of
that element as well, you might have to defer to the closing tag.

If you're trying to access the BODY element within a script in the HEAD
element, then that will fail as the BODY starting tag won't have been
encountered by the browser.
It is there in the document

The BODY element is /always/ present, even if you omit its tags (which
is permissible as they are optional). The HTML, HEAD, BODY, and TBODY
elements are all instances of elements which have optional starting and
closing tags, but in each case, they are /always/ present in the
document tree - they are implicit.

[snip]

Mike
 
T

tsar bob

Yo can also help me if you got the solution to Robi's problem coz i also
have a simalar problem with ma code.
 

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
474,002
Messages
2,570,258
Members
46,858
Latest member
FlorrieTuf

Latest Threads

Top