开发者

In JavaScript event handling, why "return false" or "event.preventDefault()" and "stopping the event flow" will make a difference?

It is said that when we handle a "click event", returning false or calling event.preventDefault() makes a difference, in which

the difference is that preventDefault will only prevent the default event action to occur, i.e. a page redirect on a link click, a form submission, etc. and return false will also stop the event flow.

Does that mean, if the click event is registered several times for several actions, using

$('#clickme').click(function() { … })

returning false will stop the other handlers from running?

I am on a Mac now and so can only use Firefox and Chrome but not IE, which has a different event model, and tested it on Firefox and Chrome by adding 3 handlers, and all 3 handlers ran without any stopping…. so what is the real difference, or, is there a situation where "stopping the event flow" is not d开发者_开发百科esirable?

This is related to

Using jQuery's animate(), if the clicked on element is "<a href="#" ...> </a>", the function should still return false?

and

What's the difference between e.preventDefault(); and return false?


hopes this code can explain it to you...

html

<div>
<a href="index.html" class="a1">click me</a>
<a href="index.html" class="a2">click me</a>
</div>​

jquery

$('div').click(function(){
    alert('I am from <div>');
});

$('a.a1').click(function(){
    alert('I am from <a>');
    return false; // this will produce one alert
});

$('a.a2').click(function(e){
    alert('I am from <a>');
    e.preventDefault(); // this will produce two alerts
});​

demo

or

$('div').click(function(){
    alert('I am from <div>');
});

$('a').click(function(){
    alert('I am from <a>');
});

$('a.a1').click(function(){
    alert('I am from <a class="a1">');
    return false;
});

$('a.a2').click(function(e){
    alert('I am from <a class="a2">');
    e.preventDefault();
});​

demo 2


Writing return false or e.preventDefault() will not prevent other handlers from running.

Rather, they will prevent the browser's default reaction, such as navigating to a link.

In jQuery, you can write e.stopImmediatePropagation() to prevent other handlers from running.


return false and preventDefault() are there to prevent the browser's default action associated with an event (for example, following a link when it's clicked). There is a different technique to achieve this for each of three different scenarios:

1. An event handler added using addEventListener() (non-IE browsers). In this case, use the preventDefault() method of the Event object. Other handlers for the event will still be called.

function handleEvent(evt) {
    evt.preventDefault();
}

2. An event handler added using attachEvent() (IE). In this case, set the returnValue property of window.event to true. Other handlers for the event will still be called, and may also change this property.

function handleEvent() {
    window.event.returnValue = false;
}

3. An event handler added using an attribute or event handler property.

<input type="button" value="Do stuff!" onclick="return handleEvent(event)">

or

button.onclick = handleEvent;

In this case, return false will do the job. Any other event handlers added via addEventListener() or attachEvent() will still be called.

function handleEvent() {
    return false;
}


Sometimes an event listener wants to cancel the sideeffects of the event is is interested in. Imagine a textbox which you wish to only allow numbers. Because textboxes can accept anything it becomes necessary to tell the browser to ignore non numbers that are typed. This is achieved by listening the key events and returning false if the wrong key is typed.


This doesn't completely answer your question, but the other day I used YUI's e.preventDefault() on an <a> element to squash the href action, as I only wanted the JavaScript onclick event to have control (unless no JS detected). In this situation stopping the entire chain of events wouldn't effect me.

But a couple days before that, I had an <input type="checkbox"> nested inside a <label> element, and I had to use a conditional in the event handler to determine if the clicked target was a label, as neither e.preventDefault() nor e.stopEvent() stopped my 'click' event from (legitimately) triggering twice (except in IE6).

What would have been nice is the ability to squash an entire chain of related events, since I'd already tried propagation and return false ;, but I was always going to get a 2nd event fire thanks to my label element.


Edit: I wouldn't mind knowing how jQuery would've handled my double-event situation, if anyone's keen to comment on that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜