最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

events - Javascript conflict with onclick and onmouseout - Stack Overflow

programmeradmin1浏览0评论

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 of alert: jsfiddle/238Nz/3 – Jared Farrish Commented Dec 27, 2012 at 3:25
  • @Musa - It freezes for several seconds on my Firefox using the fixed alerts version I posted. The first one I posted had the functions in an onload. :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
 |  Show 3 more ments

3 Answers 3

Reset to default 4

Adjusting 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 using console.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 and Inspect Element, then choose the Console 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 the input (and body tag) within the source. Right-click and View 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 alerts 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 alerts fire, and the onmouseout-fired alert is not run through console.log until after I hit Ok on the alert and and I move the mouse pointer off of the input 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 and domouseout() called at the same time. So Firefox is detecting the onclick as taking the mouse pointer away from the button, and you get the "freeze". If you watch the console, you'll see both logs fire immediately, and you seemingly get no alert to interact with (by clicking Ok).

  • 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-fired alert does not focus on top of the onclick-fired alert. IE 7-9 plus Compatibility View all exhibit this particular behavior, with slight variations.

  • Opera (12.02): Opera does not fire the onmouseout-fired alert or console.log message until after the onclick-fired alert and log message, and you move the mouse (assuming you've moved it off of the input 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's DOM 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. :) :)

发布评论

评论列表(0)

  1. 暂无评论