 |
 |
More javascript trouble
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 2001
Location: Are Eye
Status:
Offline
|
|
I've been digging deeper into javascript and I've hit a bump with guess which browser.
I've got a list.
I've attached a mouseover event handler to each <li> within my list that fires off the function doStuff(). I borrowed the code from PPK, and it works dandy.
My script works in all browsers if doStuff() contains generic code like alert("hi!"); That tells me that all browsers realize that the mouseover event handler exists.
However, that's about as far as it goes with IE6. In IE6, if change doStuff() to alert(this); it reports that this is an object. (duh). In modern browsers, however, it reports that this is an HTMLLIElement because the <li> triggered the event. So alert(this.innerHTML) reports what is inside the <li>. But not in IE6. I have no idea what object IE6 refers to. None at all.
I'd post all the code, but it's really long, so I made a new abbreviated copy of the relevant bits here:
Code:
function addMouseOver() {
var theUL = document.getElementById('mylist');
var listItmes = theUL.getElementsByTagName('li');
for (var i=0; i<listItmes.length; i++) {
addEvent(listItmes[i], 'mouseover', doStuff);
addEvent(listItmes[i], 'mouseout', undoStuff);
}
//ensure that all onload events are executed
function addEvent(obj, evType, fn){
if (obj.addEventListener){
obj.addEventListener(evType, fn, true);
return true;
} else if (obj.attachEvent){
var r = obj.attachEvent('on'+evType, fn);
return r;
} else {
return false;
}
}
function doStuff() {
alert(this.innerHTML); //yeah yeah, innerHTML... it's convenient for this exercise
}
function undoStuff() {
//undo stuff
}
//load up the onload events
addEvent(window, 'load', addMouseOver);
....
<ul id="mylist">
<li>blah...</li>
<li>blahblah...</li>
</ul>
any takers? any ideas? Is there a way to get IE6 to figure out what object I'm interested in manipulating?
|
|
|
| |
|
|
|
 |
|
 |
|
Grizzled Veteran
Join Date: Nov 2003
Location: Hebburn, UK
Status:
Offline
|
|
Gosh, I'm quite surprised this.innerHTML worked on anything, to be honest.
Anyway, since you're adding event listeners, why not go for checking event.target or event.srcElement? I'll admit, I'm very rusty with IE, I haven't coded specifically for it in 4+ years, so forgive me if this doesn't work (can't test it either).
Code:
function addMouseOver() {
var theUL = document.getElementById('mylist');
var listItmes = theUL.getElementsByTagName('li');
for (var i=0; i<listItmes.length; i++) {
addEvent(listItmes[i], 'mouseover', doStuff);
addEvent(listItmes[i], 'mouseout', undoStuff);
}
}
//ensure that all onload events are executed
function addEvent(obj, evType, fn){
if (obj.addEventListener){
obj.addEventListener(evType, fn, true);
return true;
} else if (obj.attachEvent){
var r = obj.attachEvent('on'+evType, fn);
return r;
} else {
return false;
}
}
function doStuff(e) {
var el = (document.addEventListener) ? e.target : event.srcElement;
if (el.nodeType != 1) el = el.parentNode; //we've likely hit the text node and not the element
alert(el.innerHTML); //yeah yeah, innerHTML... it's convenient for this exercise
}
function undoStuff() {
//undo stuff
}
I think IE6 also supports event.target, but I don't know...
Hope that helps a wee bit.
|
|
Just who are Britain? What do they? Who is them? And why?
Formerly Black Book
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Sep 2000
Location: Denver, CO, USA
Status:
Offline
|
|
i had to go dig up somebody's addEvent function, add in a '}' and put the code below the page - if you use a js include (which you should) that shouldn't be a problem.
first the html (code is called AFTER the elements):
Code:
<html>
<ul id="mylist">
<li>blah...</li>
<li>blahblah...</li>
</ul>
<script language="javascript" src="doListStuff.js"></script>
</html>
now the js:
Code:
function addMouseOver()
{ var theUL,listItems,i;
theUL = document.getElementById('mylist');
listItmes = theUL.getElementsByTagName('li');
for (i=0; i<listItmes.length; i++)
{ addEvent(listItmes[i], 'mouseover', doStuff);
addEvent(listItmes[i], 'mouseout', undoStuff);
}
//ensure that all onload events are executed
function addEvent(obj, evType, fn)
{ if (obj.addEventListener)
{ obj.addEventListener(evType, fn, true);
return true;
}
else if (obj.attachEvent)
{ var r = obj.attachEvent('on'+evType, fn);
return r;
}
else
{ return false;
}
}
}
function addEvent(obj, evType, fn){
if (obj.addEventListener){
obj.addEventListener(evType, fn, true);
return true;
} else if (obj.attachEvent){
var r = obj.attachEvent("on"+evType, fn);
return r;
} else {
return false;
}
}
function doStuff()
{ alert("dostuff");
}
function undoStuff()
{ //undo stuff
alert("undo stuff");
}
//load up the onload events
addEvent(window, 'load', addMouseOver);
|
|
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 2001
Location: Are Eye
Status:
Offline
|
|
I was surprised that this.innerHTML worked too to tell the truth. But it does in both Safari and FF, so I won't complain about it!
And your addition did the trick! It's reporting a child of the <li>, but I'm in the right neighborhood and I can crawl the DOM from there.
Thank you very much!
|
|
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 2001
Location: Are Eye
Status:
Offline
|
|
hotani, thanks for the reply. But a neat thing about the way I'm adding event listeners is that it doesn't actually add them until the document is loaded. That means that the script tag can happily reside in the head of the html without fear of it running before the body is loaded.
It's worth a look, and if you're interested, I pulled the technique from quirksmode.
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Sep 2000
Location: Denver, CO, USA
Status:
Offline
|
|
ah cool - i'll have to try that out. I've spent many hours in the past trying to figure out why something wasn't working and it would usually turn out to be the code placement, which is rather irritating.
EDIT: ha! yeah I moved the include to the top and it still worked - nice.
|
|
|
| |
|
|
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Apr 2005
Status:
Offline
|
|
Originally Posted by registered_user
Code:
//ensure that all onload events are executed
function addEvent(obj, evType, fn){
if (obj.addEventListener){
obj.addEventListener(evType, fn, true);
Warning: the script snippet above is not entirely standards-compliant. It will work for now in FireFox but once they fix this bug it will not work reliably in FireFox anymore. It probably does not do what you want in Opera, it supports the standards correctly.
The issue is that you set up a "capturing" event handler by using "true" as the third argument to the addEventListener function:
Code:
if (obj.addEventListener){
obj.addEventListener(evType, fn, true);
That true should be false. If it is true, the event listener should not fire for any element the event listener is registered on. For instance, if you use this with a LI element it will not do anything unless the LI has child elements. Test in Opera
Could you consider editing your posts and using "false" as the third argument to addEventListener instead? I'm afraid these snippets will be misleading to cut-and-paste JavaScript authors, they may not read the full thread.
--
Hallvord R. M. Steen
Technical Support Consultant, Opera Software
http://www.opera.com/
Opera - simply the best Internet experience
|
|
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 2001
Location: Are Eye
Status:
Offline
|
|
I won't go back and edit, because that would disrupt the discussion for people who come lataer to read the thread! As for people grabbing the code and not reading the thread, well shame on them for copying code that it is in a thread that asks for help because the code doesn't work properly!  But I will certainly take heed of your advice and test the same script with false instead of true; and heck, I'll even download Opera and give the script this is a part of a whirl in it.
If you are, however, concerned about people using that code snippet, Its source is from Peter Paul Koch's site, quirksmode.org (I linked to the page above), and you might want to contact him about it.
I'm still largely a n00b when it comes to javascript, and the Event model(s) is something I'm not completely comfortable with. But you've given me something interesting to research, and I appreciate it!
|
|
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 2001
Location: Are Eye
Status:
Offline
|
|
Well, I tried that script in Opera, and the events all fire -- more or less. But the script really doesn't run on Opera, not well anyway.
And Opera 8 doesn't render the CSS correctly. It doesn't position elements absolutely in relation to their nearest parent with position: relative.
|
|
|
| |
|
|
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Apr 2005
Status:
Offline
|
|
Originally Posted by registered_user
Well, I tried that script in Opera, and the events all fire -- more or less. But the script really doesn't run on Opera, not well anyway.
And Opera 8 doesn't render the CSS correctly. It doesn't position elements absolutely in relation to their nearest parent with position: relative.
Can you be a bit more specific about where you see the problem?
|
|
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 2001
Location: Are Eye
Status:
Offline
|
|
of course.
abbreviated css:
ul { position: relative; }
li { position: relative; }
li a {position: relative;}
li a span { position: absolute; top: 0; left: 0; }
abbreviated mark up:
<ul>
<li><a><span>words</span><img /></a></li>
<span>span</span> is positioned absolutely. An absolutely positioned element is supposed to be positioned relative to its nearest parent that has position: relative; specifically declared. On my page, Opera positions the span relative to the ul or perhaps even its container, I'm not certain which; it should position the span relative to the <a> tag.
|
|
|
| |
|
|
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Apr 2005
Status:
Offline
|
|
Thanks for the details :-)
First of all: the script runs nicely in my Opera 8 when I fix your addEventListener call to avoid capture. I'm not sure what you meant by "really doesn't run on Opera". Perhaps Mac Opera is not up for it while Win Opera is??
It had serious problems in my FireFox though, it printed out a very long list of complaints in the JS console about obj not being defined on line 130.
BTW, are you the author of the script? If not I'd like to send the original author a note about these issues.
Originally Posted by registered_user
abbreviated css:
ul { position: relative; }
li { position: relative; }
li a {position: relative;}
li a span { position: absolute; top: 0; left: 0; }
abbreviated mark up:
<ul>
<li><a><span>words</span><img /></a></li>
<span>span</span> is positioned absolutely. An absolutely positioned element is supposed to be positioned relative to its nearest parent that has position: relative; specifically declared. On my page, Opera positions the span relative to the ul or perhaps even its container, I'm not certain which; it should position the span relative to the <a> tag.
Yes, Opera gets confused there (though the minimized markup/style doesn't capture enough detail). It is at least partly because you're creating invalid markup with your styling: you set the SPAN to block on hover and voila, you have a block-level element inside (several) inline elements, the equivalent of doing
<span><p>hi</p></span>
Replacing that "block" with "inline" in your CSS causes a really funny behaviour though. Try it yourself 
A bug report would be welcome - bugs.opera.com/wizard/
|
|
|
| |
|
|
|
 |
|
 |
|
Fresh-Faced Recruit
Join Date: Apr 2005
Status:
Offline
|
|
(set the UL to display: inline-block. Works. I'm not fluent enough in CSS2.1 to say why though .. :-p )
|
|
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 2001
Location: Are Eye
Status:
Offline
|
|
Yes, I'm the author.
I will try the false bit, and see if that helps; I didn't get a chance to play with it today.
Also true that it creates a block level element within an inline element. Just like the rest of the xhtml pages on the internet do including opera.com But that has absolutely nothing to do with the validity of the mark-up.
|
|
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Nov 2001
Location: Are Eye
Status:
Offline
|
|
well, it seems to work just as well with it set to false, at least in this instance, so I'll take your word for it. I don't know enough about events yet to really form an opinion on it either way.
|
|
|
| |
|
|
|
 |
 |
|
 |
|
|
|
|
|

|
|
 |
Forum Rules
|
 |
 |
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
 |
 |
 |
 |
|
 |
|