Error getElementbyClassName

N

nameless

Why this code doesn't work ?

<html>
<head>
<script type="text/javascript">

function hello() {
alert("Hello World!");
}


function load() {
var el = document.getElementByClassName("uffa");
el.addEventListener("click", hello, false);
}


</script>
</head>
<body onload="load()";>

<a href="#" class="uffa">Hello</a>

</body>
</html>
 
J

JR

Why this code doesn't work ?

<html>
<head>
<script type="text/javascript">

   function hello() {
     alert("Hello World!");
   }

   function load() {
     var el = document.getElementByClassName("uffa");
     el.addEventListener("click", hello, false);

There´s no getElementByClassName method in DOM. But in HTML5 there
will be a method *getElementsByClassName*:
http://www.w3.org/TR/html5/dom.html

Ciao,
JR
 
R

RobG

Why this code doesn't work ?

<html>
<head>
<script type="text/javascript">

   function hello() {
     alert("Hello World!");
   }

   function load() {
     var el = document.getElementByClassName("uffa");

The method is called "getElementsByClassName" (note the 's' on
Elements). It is part of the HTML 5 draft specification and has only
been implemented in a few recent browsers so you should do a feature
test and provide an alternative for browsers that don't provide it as
a host method.

<URL: http://dev.w3.org/html5/spec/Overview.html#dom-document-getelementsbyclassname
     el.addEventListener("click", hello, false);

Since el will be a (live) collection in conforming browsers, and
probably an array where a native method has been substituted, you
probably want to enumerate its members and add the click listener to
each one:

for (var i=0, len=el.length; i<len; i++) {
el.addEventListener(...);
}


Also, addEventListener is not available in some recent, and many
older, browsers so you should also test for that and provide an
alternative.
 
T

Thomas 'PointedEars' Lahn

RobG said:
Since el will be a (live) collection in conforming browsers, and
probably an array where a native method has been substituted, you
probably want to enumerate its members and add the click listener to
each one:

for (var i=0, len=el.length; i<len; i++) {
el.addEventListener(...);
}


Or you could find the common ancestor (when in doubt, the BODY element), and
add a listener that tests the className. That would be a lot more
efficient.
Also, addEventListener is not available in some recent, and many
older, browsers so you should also test for that and provide an
alternative.

What other *recent* implementations except MSHTML that support CSS classes
do not support it?


PointedEars
 
G

Garrett Smith

[...]

el.addEventListener("click", hello, false);
Since el will be a (live) collection in conforming browsers, and
probably an array where a native method has been substituted, you
probably want to enumerate its members and add the click listener to
each one:

[...]
The cost of doing that could be avoided by using bubbling.
[...]

If only one element is of concern, give the element an ID and use
document.getElementById.
 
R

RobG

RobG said:
Since el will be a (live) collection in conforming browsers, and
probably an array where a native method has been substituted, you
probably want to enumerate its members and add the click listener to
each one:
  for (var i=0, len=el.length; i<len; i++) {
    el.addEventListener(...);
  }


Or you could find the common ancestor (when in doubt, the BODY element), and
add a listener that tests the className.  That would be a lot more
efficient.


The criteria for "efficient" depend on the circumstance and how it is
measured. I assumed (perhaps incorrectly) that the OP was a small
example and not intended to be production code.

Using getElementsByClassName for a single element is certainly
inefficient compared to say getElementById, however it is sufficient
for an example.

Using event delegation might be more efficient in terms of requiring
fewer listeners and so saving processing time adding them, or less
efficient as the listener will likely be called far more often than if
it is placed only on the elements it relates to.

What other *recent* implementations except MSHTML that support CSS classes
do not support it?

I don't know, but there are lots of browsers that I know little or
nothing about. Quirksmode[1] says that Konqueror 3.5.7 doesn't have
getElementsByClassname but it might be out of date as 4.3 is current
and 4.4 is in beta (Linux and Windows, the stable Mac OS X version is
3.5.9).


1. <URL: http://www.quirksmode.org/dom/w3c_core.html#fivemethods >
 
D

David Mark

RobG said:
Since el will be a (live) collection in conforming browsers, and
probably an array where a native method has been substituted, you
probably want to enumerate its members and add the click listener to
each one:
for (var i=0, len=el.length; i<len; i++) {
el.addEventListener(...);
}


Or you could find the common ancestor (when in doubt, the BODY element), and
add a listener that tests the className. That would be a lot more
efficient.
Also, addEventListener is not available in some recent, and many
older, browsers so you should also test for that and provide an
alternative.

What other *recent* implementations except MSHTML that support CSS classes
do not support it?


The addEventListener method? Opera 6 (and who knows how many off-
brand agents?) And what do CSS classes have to do with detecting
event-related features?

Also, though it is beside the point, typeof document.body.className ==
'string' in Opera 6 and CSS classes work in the static markup (of
course), but manipulating them programmatically has no effect.

Not sure of any general way to detect that oddball behavior, but a
couple of clues are that its (rather limited) inline style rule
properties actually compute styles and left, top, height and width
return numbers (rather than the usual strings). The last of those is
something I accounted for in My Library, but was never sure which
browser(s) were afflicted with the quirk.

So anyway, now that I think about it, if you set the className
property to a class known to define a top rule, you could then check
to see if the element's style.top is affected as expected. Of course,
my addStyleRule (API method) is disallowed in that browser as well, so
I can't use that to add a test rule. Only thing I can think of is a
multiple object inference based on the screwy style properties, but
I'm not adding anything like that for Opera 6. IMO, they should not
have exposed the CLASS attribute as a className property if changing
it would have no effect.
 
T

Thomas 'PointedEars' Lahn

David said:
The addEventListener method? Opera 6

Thanks. Would you still consider it?
(and who knows how many off-brand agents?)

I do not know. What do you consider an "off-brand agent"?
And what do CSS classes have to do with detecting event-related
features?

Read the Subject.
Also, though it is beside the point, typeof document.body.className ==
'string' in Opera 6 and CSS classes work in the static markup (of
course), but manipulating them programmatically has no effect.
Thanks.

So anyway, now that I think about it, if you set the className
property to a class known to define a top rule, you could then check
to see if the element's style.top is affected as expected.

I don't think so. The `top' "rule" (_declaration_, really) in a document
stylesheet does not affect the value of the `style.top' property, and Opera
6 does not support getComputedStyle().
[...]
I'm not adding anything like that for Opera 6. IMO, they should not
have exposed the CLASS attribute as a className property if changing
it would have no effect.

ACK


PointedEars
 
D

David Mark

Thomas said:
Thanks. Would you still consider it?

Consider it what? I would consider it when testing degradation paths
for unknown browsers. It's great for that. Gaps in logic are gaps in
logic, whether they affect the latest browsers or not. ;)
I do not know. What do you consider an "off-brand agent"?

Mobile devices for one example. Opera Mini is a the first one that
comes to mind. There's also some form of Opera in a Wii. Then there's
that POS in the PS3 (Netfront?) Knowing that my library makes a
graceful exit in Opera 6 gives me more confidence that it will deal
successfully with browsers that I haven't yet tested. Of course, some
scenarios (e.g. the lack of documentElement) can be simulated by
stubbing out methods.
Read the Subject.

No help there. :)

Yes, I thought you'd like that.
I don't think so. The `top' "rule" (_declaration_, really) in a document
stylesheet does not affect the value of the `style.top' property, and Opera
6 does not support getComputedStyle().

You did not read carefully. Opera 6 does have a goofy
quasi-computed-style capability. Just do a
window.alert(document.body.style.color) and you'll see what I mean. ;)
Come to think of it, I could detect that silliness and infer that
className won't work, but it's still too much of a stretch for my taste.
 
T

Thomas 'PointedEars' Lahn

David said:
Thomas said:
Thanks. Would you still consider it?

Consider it what? I would consider it when testing degradation paths
for unknown browsers. It's great for that. Gaps in logic are gaps in
logic, whether they affect the latest browsers or not. ;)
I do not know. What do you consider an "off-brand agent"?

Mobile devices for one example. [more examples]
ACK
Read the Subject.

No help there. :)

In this example, if there would be no way to determine the elements that
have a certain class name, it would not matter if the environments to which
this applied would support addEventListener() as execution would/should
never reach that point. As it is possible, that changes the situation.
You did not read carefully. Opera 6 does have a goofy
quasi-computed-style capability. Just do a
window.alert(document.body.style.color) and you'll see what I mean. ;)

Thanks. I tried that on <http://portal.opera.com/> (the default home page
for Opera 6.0.6) and it displayed nothing. To be precise, I checked type
and value: it was the empty string, unexpectedly.

I then found out that this must have been due to the empty `class'
attribute (which is invalid, BTW). The first child element with ID "opera-
websites" has a class attribute value of "clearfix", but the ID selector
has `color: #dddddd' which is what the `color' property yields.

This is probably what you meant by "goofy".
Come to think of it, I could detect that silliness and infer that
className won't work, but it's still too much of a stretch for my taste.

Which means in essence that you do not consider optimizing for this UA
anymore, does it not?


PointedEars
 
D

David Mark

Thomas said:
David said:
Thomas said:
David Mark wrote:
Thomas 'PointedEars' Lahn wrote:
RobG wrote:
Also, addEventListener is not available in some recent, and many
older, browsers so you should also test for that and provide an
alternative.
What other *recent* implementations except MSHTML that support CSS
classes do not support it?
The addEventListener method? Opera 6
Thanks. Would you still consider it?
Consider it what? I would consider it when testing degradation paths
for unknown browsers. It's great for that. Gaps in logic are gaps in
logic, whether they affect the latest browsers or not. ;)
(and who knows how many off-brand agents?)
I do not know. What do you consider an "off-brand agent"?
Mobile devices for one example. [more examples]
ACK
And what do CSS classes have to do with detecting event-related
features?
Read the Subject.
No help there. :)

In this example, if there would be no way to determine the elements that
have a certain class name, it would not matter if the environments to which
this applied would support addEventListener() as execution would/should
never reach that point. As it is possible, that changes the situation.

That's what I was driving at.
Thanks. I tried that on <http://portal.opera.com/> (the default home page
for Opera 6.0.6) and it displayed nothing. To be precise, I checked type
and value: it was the empty string, unexpectedly.

Then it had an empty class (or no color defined by the class).
I then found out that this must have been due to the empty `class'
attribute (which is invalid, BTW).

Not to mention clueless (and a waste of space). :)
The first child element with ID "opera-
websites" has a class attribute value of "clearfix", but the ID selector
has `color: #dddddd' which is what the `color' property yields.

This is probably what you meant by "goofy".
Yes.


Which means in essence that you do not consider optimizing for this UA
anymore, does it not?

No. I don't "optimize" for any specific browser. For example, this
browser has no way to get to the documentElement (literally none, even
gEBTN fails). There was a bad assumption in one of my module's feature
testing code, expecting that it would always be available one way or
another. That's simply a gap in logic and fixing it has nothing to do
with the browser that exposed the problem. Another gotcha with this
browser is that it has a bogus createElement method that invariably
returns the undefined value. (!) Luckily I was in the habit of testing
the result from that method (I never did trust it completely), so that
didn't pose an issue. About the only thing left to do for that one is
to find out why the mouse position stuff isn't working. That's
important for pruning the drag and drop methods (or actually making them
work). I suspect it is one of those browsers that used event.x and
event.y as I am pretty sure DnD was do-able in Opera 6.

One other interesting note with Opera < 9, is that it recalculates
offsetWidth/Height after evaluation, rather than before (at least in
some circumstances). It also seems to turn the usual hack-arounds into
noops. Example:-

(el.offsetWidth) // Force recalculation before reading--fails in Opera < 9

Changing that to an assignment or a test fixes the issue. I only did
that in the alert add-on, but ISTM the core should have a test for this
quirk (and use it in one or two places as well). FF1 had a similar
problem with the "shrink-wrapped" alert (fixed with the same hack).
 

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,781
Messages
2,569,615
Members
45,293
Latest member
Hue Tran

Latest Threads

Top