setting onmouseout in javascript (not html)

A

Andy

Hi,

I want to create a div ajax popup:

var popup = document.createElement('div');
popup.id = 'my_id';
popup.innerHTML = popuptext;
popup.style.clip = 'auto';
popup.style.overflow = 'scroll';
popup.style.position = 'absolute';
popup.style.width = popupwidth;
popup.style.height = popupheight;
popup.style.top = ymouse + "px";
popup.style.left = xmouse + "px";
popup.onmouseout = 'alert(this)';
document.body.appendChild(popup);

I cannot get the alert set via setting popup.onmouseout to come up.
Is it possible to set onmouseout attribute of a div element created
this way?

Andy
 
M

Martin Honnen

Andy said:
var popup = document.createElement('div');
popup.onmouseout = 'alert(this)';

I cannot get the alert set via setting popup.onmouseout to come up.
Is it possible to set onmouseout attribute of a div element created
this way?

No, you need to assign a function
popup.onmouseout = function(evt) { alert(this); };

Note however that the mouseout event might not do what you want as it
fires not only when the mouse is moved outside of the div but also when
the mouse is moved inside of a div over a child element. So with IE you
might rather want
popup.onmouseleave = function() { alert(this); };
or if you need a cross browser solution then you need to use onmouseout
but in that handler you need to check the relatedTarget property of the
event object for the W3C DOM and the toElement property of the event
object in IE.
 
T

Thomas 'PointedEars' Lahn

Martin said:
popup.onmouseleave = function() { alert(this); };

That might finally cure my hover-on-IE headache. Big thanks for that!


Kind regards,

PointedEars
 
A

Andy

Note however that the mouseout event might not do what you want as it
fires not only when the mouse is moved outside of the div but also when
the mouse is moved inside of a div over a child element. So with IE you
might rather want

Well, you're right! I am testing with firefox and I dynamically
created a popup div with a form tag with several buttons. If I
mousein to one of the button vicinities, then it mouses out of the div
based on the onmouseout function(evt) that you told me to use, and
then I wrongly close the popup. This is not good.

Can you explain how I can look at evt in my function to determine
whether the mouse has left the div tag box, whose x,y coordinates I
already know? And based on your post, it looks like the evt isn't
passed to onmouseout in IE?

Andy
 
M

Martin Honnen

Andy said:
Can you explain how I can look at evt in my function to determine
whether the mouse has left the div tag box, whose x,y coordinates I
already know?

The event object has a property relatedTarget that tells you to which
node the mouse moved to. You then need to check whether that node is
contained in your div or not and if not you can hide the div.
See http://www.faqts.com/knowledge_base/view.phtml/aid/1606/fid/145 for
code samples, it talks about rather old browser versions with IE 4 and
Netscape 6 and Opera 7 but nothing has changed in regard to event
handling of mouseout/mouseover since then.

And based on your post, it looks like the evt isn't
passed to onmouseout in IE?

IE does not pass an event object to event handlers assigned with script
but it has a window.event object you need to access and that has a
property named toElement that you can access and IE even exposes a
contains methods on element nodes you can use for the check.
 
T

Thomas 'PointedEars' Lahn

Please keep those attribution lines, shorten them if necessary.
vvvvvvvvvvv said:
Well, you're right! I am testing with firefox and I dynamically
created a popup div with a form tag with several buttons. If I
mousein to one of the button vicinities, then it mouses out of the div
based on the onmouseout function(evt) that you told me to use, and
then I wrongly close the popup. This is not good.

Can you explain how I can look at evt in my function to determine
whether the mouse has left the div tag box,

(The *what*?
<http://www.w3.org/TR/1999/REC-html401-19991224/intro/sgmltut.html#h-3.2.1>)

MSHTML provides the `srcElement', `toElement', and `fromElement' properties
for event objects. However, AFAIK that does not help with the `mouseover'
and `mouseout' events because, e.g.

,-- DIV -------------------
| ,-- UL -----------------
| | ,-- LI --------------
| | | ,-- P ------------
| | | | ,--------------
| | | | | line 1 |
| | | | `---------|----
| | | | v
| | | | ,--------------
| | | | | line 2
| | | | `--------------

is also considered a `mouseout' event on the LI element with srcElement=LI,
fromElement=P, and toElement=DIV(!). It gets better with `line-height:
normal' on the P and paddings instead of margins but it doesn't go away in
IE 6, 7, and 8 in Compatibility Mode (one pixel spoils it all, BTDT). (And
I need to force IE 8 in Compatibility Mode because z-index in Standards Mode
is apparently borken.) That's the headache I was talking about which
`onmouseleave' (as Martin suggested) might cure.
whose x,y coordinates I already know?

You better check for the ID of the event target. Rest assured you do _not_
know its coordinates.
And based on your post, it looks like the evt isn't passed to
onmouseout in IE?

It isn't passed to the listener. You need to use window.event instead.
Search the archives for a multi-DOM solution.


PointedEars
 
A

Andy

You better check for the ID of the event target.  Rest assured you do _not_
know its coordinates.

I did try this and it seems to work. I very carefully move the mouse
out of the popup box and it disappears. So I don't seem to "lose" any
mouseouts.

my code
--------------------

Singleton.prototype.DoMakeAnnotation = function (win)
{
.... get popupinnerhtml, popupwidth, popupheight, xmouse, ymouse

var popup = win.document.createElement('div');
popup.innerHTML = popupinnerhtml;
popup.style.clip = 'auto';
popup.style.overflow = 'scroll';
popup.style.position = 'absolute';
popup.style.width = popupwidth;
popup.style.height = popupheight;
popup.style.background = '#ddd';
popup.style.border = '1px solid #000';
popup.style.top = ymouse + "px";
popup.style.left = xmouse + "px";
popup.mysingleton = this;
popup.mywindow = win;
popup.mytop = ymouse;
popup.myleft = xmouse;
popup.mybot = ymouse + popupheight;
popup.myright = xmouse + popupwidth;
popup.onmouseout = function (evt) { this.mysingleton.AnnoMouseout
(this, evt); };
popup.style.display = "block";
win.document.body.appendChild(popup);
}

Singleton.prototype.AnnoMouseout = function (element, evt)
{
var posx = 0;
var posy = 0;
if (!evt)
evt = window.event;
if (evt.pageX || evt.pageY) {
posx = evt.pageX;
posy = evt.pageY;
}
else if (evt.clientX || evt.clientY) {
posx = evt.clientX +
document.body.scrollLeft +
document.documentElement.scrollLeft;
posy = evt.clientY +
document.body.scrollTop +
document.documentElement.scrollTop;
}
if (posx < element.myleft ||
posx > element.myright ||
posy < element.mytop ||
posy > element.mybot)
element.mywindow.document.body.removeChild(element);
}

Do you guys think this code is too risky for production use? My
concern is that the browser would give me an off by 1 coordinate of
the last mouseout, and the popup would never disappear.

Andy
 
A

Andy

You better check for the ID of the event target.  Rest assured you do _not_
know its coordinates.

I do have a buglet in my implementation in Firefox on Linux. When the
browser finishes displaying a page the little circle of diamonds stops
rotating clockwise. When I mouseover and the popup comes up, firefox
starts spinning its circle of diamonds in the upper right hand corner
of the browser title bar. It doesn't stop spinning when I removeChild
the popup. I have another popup that goes away with a form button
click, and the browser also doesn't stop spinning its circle.

Why does the browser think its waiting for more content from the
server?

Andy
 
T

Thomas 'PointedEars' Lahn

[Restored attribution]
[Thomas 'PointedEars' Lahn wrote: ]
You better check for the ID of the event target. Rest assured you do
_not_ know its coordinates.

I did try this and it seems to work. I very carefully move the mouse
out of the popup box and it disappears. So I don't seem to "lose" any
mouseouts.

my code

Not a constructor, so the property name should not start uppercase.

I would also submit that you don't need the singleton pattern in
ECMAScript implementations, provided you try to implement it here.

{
doMakeAnnotation: function(win) {
// ...
}
}

refers to a newly constructed object that has identity and a property
(here: a method) named `doMakeAnnotation'.
{
.... get popupinnerhtml, popupwidth, popupheight, xmouse, ymouse

var popup = win.document.createElement('div');
popup.innerHTML = popupinnerhtml;

Eschew `innerHTML'; search the archives (discussed recently again).
[...]
popup.mysingleton = this;

Make this a local variable. I seem to prefer `me' for the identifier; YMMV.
popup.mywindow = win;
popup.mytop = ymouse;
popup.myleft = xmouse;
popup.mybot = ymouse + popupheight;
popup.myright = xmouse + popupwidth;

Don't, see below.
popup.onmouseout = function (evt) { this.mysingleton.AnnoMouseout
(this, evt); };

Prefer the standards-compliant approach; use this proprietary one only as
fallback. Search for _addEventListener() (notice the underscore).
popup.style.display = "block";
win.document.body.appendChild(popup);
}

I don't see this method called anywhere, though.
Singleton.prototype.AnnoMouseout = function (element, evt)

See above.
{
var posx = 0;
var posy = 0;
if (!evt)
evt = window.event;

It's not necessarily either one or the other. After this line, you
need to test `evt' again before you access it or its properties.
if (evt.pageX || evt.pageY) {

And if both are 0 (or NaN, undefined, etc.)?
posx = evt.pageX;
posy = evt.pageY;
}
else if (evt.clientX || evt.clientY) {

And if both are 0 (or NaN, undefined, etc.)?
posx = evt.clientX +
document.body.scrollLeft +
document.documentElement.scrollLeft;
posy = evt.clientY +
document.body.scrollTop +
document.documentElement.scrollTop;

That might actually work. But what if another parent node refers to a
scrollable element?
}
if (posx < element.myleft ||
posx > element.myright ||
posy < element.mytop ||
posy > element.mybot)
element.mywindow.document.body.removeChild(element);
}

Do you guys think this code is too risky for production use?

Absolutely, yes.
My concern is that the browser would give me an off by 1 coordinate of
the last mouseout, and the popup would never disappear.

I still don't understand what you think you need the coordinates for.
Suppose `mouseout' works (which it doesn't in MSHTML), you hide the
"popup" on event, i.e. when the listener for the event is called.
As "simple" as that.

Your main concern with this code should be that

- you are calling host methods without feature test (createElement etc.)
- you are accessing host properties without feature test (innerHTML etc.)
- you are using error-prone host properties (innerHTML)
- you are trying to augment host objects (popup.mysingleton etc.)


I already told you about attribution lines; continued failure to comply with
established Usenet communication standards will result in your postings
being scored down here up to the point of being filtered out (killfile).

Regarding both Usenet and the programming languages, read the FAQ and
search the archives to avoid the most common blunders.

<http://jibbering.com/faq/#posting>


HTH

PointedEars
 
D

David Mark

That might finally cure my hover-on-IE headache.  Big thanks for that!

That's one way (and likely the most efficient.) Best to detect
support for that event of course.

[snip]
 
D

David Mark

Please keep those attribution lines, shorten them if necessary.
vvvvvvvvvvv




(The *what*?
<http://www.w3.org/TR/1999/REC-html401-19991224/intro/sgmltut.html#h-3...>)

MSHTML provides the `srcElement', `toElement', and `fromElement' properties
for event objects.  However, AFAIK that does not help with the `mouseover'
and `mouseout' events because, e.g.

Does for me.
  ,-- DIV -------------------
  |  ,-- UL -----------------
  |  |  ,-- LI --------------
  |  |  |  ,-- P ------------
  |  |  |  |  ,--------------
  |  |  |  |  | line 1  |
  |  |  |  |  `---------|----
  |  |  |  |            v
  |  |  |  |  ,--------------
  |  |  |  |  | line 2
  |  |  |  |  `--------------

is also considered a `mouseout' event on the LI element with srcElement=LI,
fromElement=P, and toElement=DIV(!).

So? Work it out.
It gets better with `line-height:
normal' on the P and paddings instead of margins but it doesn't go away in
IE 6, 7, and 8 in Compatibility Mode (one pixel spoils it all, BTDT).

Forget all of that.
(And
I need to force IE 8 in Compatibility Mode because z-index in Standards Mode
is apparently borken.)  That's the headache I was talking about which
`onmouseleave' (as Martin suggested) might cure.

Regardless of mode, your headaches are quite curable (with or without
mouseenter/leave.)
You better check for the ID of the event target.  Rest assured you do _not_
know its coordinates.

No doubt there. His headaches will be even worse if he goes down that
road.

[snip]
 
T

Thomas 'PointedEars' Lahn

David said:
That's one way (and likely the most efficient.) Best to detect
support for that event of course.

The only problem is how to do that.

Do you have an alternative (better) solution?


PointedEars
 
T

Thomas 'PointedEars' Lahn

David said:
Does for me.

How? See below.
So? Work it out.

"Work it out"! In case you have not noticed, DIV is an ancestor of LI.
Forget all of that.


Regardless of mode, your headaches are quite curable (with or without
mouseenter/leave.)

Talk is cheap. Show me the code.
-- Linus Torvalds


PointedEars
 
D

David Mark

The only problem is how to do that.

How to do what? Detect support for specific events? Kangax wrote a
piece on my recommendation for that. Once again, it's not rooted in
any written standard, but has a lot history behind it (sometimes all
you can go on.)
Do you have an alternative (better) solution?

No, I like that one just fine. Just detect the event support.

Or do you mean better event detector? You can bypass all of that by
attaching both sets of listeners and then sorting it out on the first
time through. I did something like that for mousewheel events in My
Library. More work, but certainly a future=proof strategy.
 
D

David Mark

How?  See below.

I saw that the first time.
"Work it out"!  In case you have not noticed, DIV is an ancestor of LI.

So what? Perhaps you should explain your diagram in more detail or
post a test page. I'm a busy guy. :)
Talk is cheap.  Show me the code.
-- Linus Torvalds

Does he need help in this area as well?

Regardless, show me the non-working example and perhaps I can help you
adjust your design (if needed.)
 
T

Thomas 'PointedEars' Lahn

David said:
How to do what? Detect support for specific events? Kangax wrote a
piece on my recommendation for that. Once again, it's not rooted in
any written standard, but has a lot history behind it (sometimes all
you can go on.)

Could you provide some reference to start with, please?
Or do you mean better event detector? You can bypass all of that by
attaching both sets of listeners and then sorting it out on the first
time through. I did something like that for mousewheel events in My
Library. More work, but certainly a future=proof strategy.

Sounds more promising. I'll look into it, thanks.


PointedEars
 
T

Thomas 'PointedEars' Lahn

David said:
I saw that the first time.


So what? Perhaps you should explain your diagram in more detail or
post a test page. I'm a busy guy. :)

It is ASCII art so you need a fixed-width font. The arrow indicates the
pointer movement. (As pointers are usually pointing upwards, I did not
expect someone not to understand that.)

When you move the pointer from one line of the P element to the next one,
that is considered a `mouseout' event on the ancestor LI element by MSHTML
and the corresponding listener (defined via `onmouseoout' attribute) is
called. And according to my tests the values of the `srcElement',
`fromElement', and `toElement' properties of the event object are then the
same as if you moved the pointer very quickly from the P to the DIV (which
also calls the listener, and it is entirely possible to trigger that
condition, too. You wouldn't believe what strange values can be logged in
IE if your tests are meticulous.)

So how to determine -- without onmouseleave -- whether the pointer really
moved out of the target area?
Regardless, show me the non-working example and perhaps I can help you
adjust your design (if needed.)

I would need to extract that from a running Plone site first, and I'm on
vacation; perhaps later.


PointedEars
 
D

David Mark

Could you provide some reference to start with, please?

It's a recently blog post by Kangax. I can't believe I'm saying this,
but STFW. We discussed it here a ways back, but perhaps you were on
vacation.
Sounds more promising.  I'll look into it, thanks.

I'm sure you can make that work.
 
D

David Mark

It is ASCII art so you need a fixed-width font.  The arrow indicates the
pointer movement.  (As pointers are usually pointing upwards, I did not
expect someone not to understand that.)

I understood that. Still not getting anything. Just describe your
predicament (or post a test page.)
When you move the pointer from one line of the P element to the next one,
that is considered a `mouseout' event on the ancestor LI element by MSHTML

Yes, transparent backgrounds, right?
and the corresponding listener (defined via `onmouseoout' attribute) is
called.  And according to my tests the values of the `srcElement',
`fromElement', and `toElement' properties of the event object are then the
same as if you moved the pointer very quickly from the P to the DIV (which
also calls the listener, and it is entirely possible to trigger that
condition, too.  You wouldn't believe what strange values can be loggedin
IE if your tests are meticulous.)

Oh, you'd be surprised.
So how to determine -- without onmouseleave -- whether the pointer really
moved out of the target area?

I still can't figure out which element(s) you want to report entering
and leaving. I'm sure it's there somewhere, but I would prefer a
simplified example/explanation.
I would need to extract that from a running Plone site first, and I'm on
vacation; perhaps later.

Okay, answer the above question and perhaps we can get somewhere. And
how is this a vacation for you? I went to alt.html last year. What a
dump.
 

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,098
Messages
2,570,625
Members
47,236
Latest member
EverestNero

Latest Threads

Top