Hi and thanks for looking at my post. I'm very new to scripting, and I'm having a simple problem that I can't figure out. So...
I have a button that freezes up when I press it, and its "onclick" function doesn't get triggered. There is a "onmouseout" function that is causing this, but I don't know why.
I'd like "onmouseout" and "onclick" functions to apply to one button, but it's not working. Please see my code:
Javascript:
function popup()
{
alert("Hello World")
}
function pop2()
{
alert("Good job")
}
function pop3()
{
alert("CLICK ME!")
}
HTML:
<input type="button" onclick="popup()" value="Hello World">
<input type="button" onclick="pop2()" onmouseout="pop3()" value="click me">
Hi and thanks for looking at my post. I'm very new to scripting, and I'm having a simple problem that I can't figure out. So...
I have a button that freezes up when I press it, and its "onclick" function doesn't get triggered. There is a "onmouseout" function that is causing this, but I don't know why.
I'd like "onmouseout" and "onclick" functions to apply to one button, but it's not working. Please see my code:
Javascript:
function popup()
{
alert("Hello World")
}
function pop2()
{
alert("Good job")
}
function pop3()
{
alert("CLICK ME!")
}
HTML:
<input type="button" onclick="popup()" value="Hello World">
<input type="button" onclick="pop2()" onmouseout="pop3()" value="click me">
Share
Improve this question
edited Dec 27, 2012 at 3:59
Lee Taylor
7,98416 gold badges37 silver badges53 bronze badges
asked Dec 27, 2012 at 3:19
MarkMark
3,1481 gold badge19 silver badges26 bronze badges
8
- 2 Fiddle: jsfiddle/238Nz/2 (Be careful testing, and fixed.) – Jared Farrish Commented Dec 27, 2012 at 3:22
- 3 Unable to reproduce jsfiddle/2R3Z5 – Musa Commented Dec 27, 2012 at 3:25
-
Using
console.log
instead ofalert
: jsfiddle/238Nz/3 – Jared Farrish Commented Dec 27, 2012 at 3:25 -
@Musa - It freezes for several seconds on my Firefox using the fixed
alert
s version I posted. The first one I posted had the functions in anonload
.:s
And note it does not happen in Chrome. – Jared Farrish Commented Dec 27, 2012 at 3:27 - @Mark your code definitely works. – irrelephant Commented Dec 27, 2012 at 3:32
3 Answers
Reset to default 4Adjusting your code to isolate and provide detail to what's going on, I've prepared the following:
http://jsfiddle/238Nz/8/
Skip below this part for the answer. This is intended for Mark.
Let's ignore whether or not using
on*
attributes to add handlers is considered good or bad$. Also, let's use some logging to check the order. I am usingconsole.log()
to send messages to the browser's Javascript console. In Firefox, I use Firebug, and Chrome has a built-in console. In both, right-click on the page andInspect Element
, then choose theConsole
tab for these tests.One more thing: jsFiddle can be a little plicated to figure out at first. The Javascript in the bottom, left pane is actually put within the
head
block above theinput
(andbody
tag) within the source. Right-click andView Source
on the bottom, right (Result
) pane and you'll see what the browser is using. It's just like your own example HTML document, just reordered for jsFiddle. Try not to be confused by how that works, though.
The markup I am using to test your problem is the following:
<input type="button" onclick="doclick()" onmouseout="domouseout()" value="Click">
Notice I plainly label my functions and use descriptive error messages. This helps me keep track of what is going on by embedding that detail within the code and the message log information. Always try to be descriptive in your labels (function
, var
, log information, etc.), instead of doing things like yay!
or what happened
. It's simply too hard to follow once your scripts get to be longer and more plex.
Next, I used the following function to narrow down and consistently replicate the same action:
function popup(msg) {
// Note, console.log is first here. This is so that the
// alert does not "steal" focus before I get any result.
console.log(msg);
// Now, let's try the alert. Notice, the same msg is used.
alert(msg);
}
This allows me to call both console.log
and alert
in a specific order, from both event handlers. Next, I establish my two event handler functions:
function doclick() {
popup('onclick fired');
}
function domouseout() {
popup('onmouseout fired');
}
See, all they do is call popup()
with an action-specific log message about what was supposed to happen. Since alert
s are designed to "focus" to the user and block interaction, which appears to be a possible cause of the "frozen" browser frame.
What I do next is try this in different browsers. Always try to replicate and test across different browsers#. In this case, I notice a big difference between two...
Chrome: Does not block processing; both
alert
s fire, and theonmouseout
-firedalert
is not run throughconsole.log
until after I hitOk
on thealert
and and I move the mouse pointer off of theinput
element. This, it seems, is the desired oute. Right?Firefox (17.0.1): Firefox does show the behavior you're describing. Note, when I click on the button, I get both
doclick
anddomouseout()
called at the same time. So Firefox is detecting theonclick
as taking the mouse pointer away from the button, and you get the "freeze". If you watch theconsole
, you'll see bothlog
s fire immediately, and you seemingly get noalert
to interact with (by clickingOk
).IE (7-9, 9 Compatibility View): IE of course provides an interesting illustration. For instance, when I click the button in IE9, I see:
https://i.sstatic/Rzj82.png
Which of course appears to be the same effect Firefox is having... But for some reason with Firefox, the
onmouseout
-firedalert
does not focus on top of theonclick
-firedalert
. IE 7-9 plus Compatibility View all exhibit this particular behavior, with slight variations.Opera (12.02): Opera does not fire the
onmouseout
-firedalert
orconsole.log
message until after theonclick
-firedalert
and log message, and you move the mouse (assuming you've moved it off of theinput
button element after clicking it). This seems weird, but more palatable than the Firefox and IE behaviors. Maybe I'm mistaken, though.
So what's happening? I'm not quite sure, but I think that the onmouseout
is blocking the onclick
's alert
from focusing to the user. If you hit [Enter]
while it's frozen, you get the onclick
alert but no onmouseout
. Chrome seems correct here; Firefox's "popunder" alert seems, well, sorta fishy.
In summary, at least the behavior of the two events in this case are not only specific to Firefox. What seems to be specific to Firefox (at least 17.0.1) is the fact the onmouseout
-fired alert
does not focus correctly, and the page "appears to freeze". This seems like a bug. I wonder if it's been reported?
$ It's not usually a good idea to use inline attribute event handlers like
<input onclick="doclick()"...>
, but let's ignore what's beside the point here. See MDN'sDOM Event
documentation, specifically the HTML attribute section, and realize this is a bit trickier and detailed than is worth going into here.# If you continue working with Javascript within the browser, you'll find out IE is... special. It has a special place in history, so weird or "abnormal" behavior is not unusual when checking your code with versions of IE. Personally, I suggest learning and working within Firefox or Chrome, and then checking in IE and other browsers that it works.
Javascript:
var clicked = false;
function popup()
{
alert("Hello World")
}
function pop2(ev)
{
alert("Good job");
clicked=true;
}
function pop3()
{
if(clicked == false)
{
alert("CLICK ME!");
}
clicked=false;
}
HTML:
<input type="button" onclick="popup()" value="Hello World">
<input type="button" onclick="return pop2(event)" onmouseout="pop3()" value="click me">
link to demo
Since the click and mouseout/mouseleave events occur soon after the other on FireFox due to poor focusing during click event, we can add a sort of a delay for the code that will be processed during mouseout/mouseleave event. The following worked for me:
//Bind the element with classname to a function on click event
$(".rej").bind("click", showData);
//Bind the same element with classname to another function on mouseout event.
$(".rej").bind("mouseout", hideData);
Then you can proceed with your showData function. However in hideData function you will need to add a delay of few seconds before processing the code in that function, as show below:
function showData() {
//Do something
}
function hideData() {
var delay = 1000;
setTimeout(function(){
//Do something
}, delay);
}
And you're good to go. The mouseout event no longer overpowers the click event in Firefox. :) :)