Canceling and Stopping Browser Events

If your Ajax application is graphically intensive, it probably uses a lot of CSS absolute positioned elements and the CSS z-order attribute extensively. The problem with overlapping elements is that events automatically bubble up from foreground elements to background elements, so if you blindly capture events like click in background elements, you may receive them when you are not expecting them. For example, if you have a div element floating above other elements, events will automatically bubble up to background elements, often leading to your application inadvertently handling the event in both the foreground div and the background div.

If you want to prevent events from bubbling up to background elements, you can capture the event with this recipe:

function stopEvent(e) {
    if (!e) e = window.event;
    if (e.stopPropagation) {
        e.stopPropagation();
    } else {
        e.cancelBubble = true;
    }
}

For example, to prevent the container of a link to receive a click event when the link is clicked, you would use the function above like this:

var link = document.getElementById("link");
link.onclick = stopEvent;

The snippet above will prevent the background of the link from receiving a click event, but how do you prevent the link itself from getting the click event? This recipe completely cancels an event, which, in this case, prevents the link from executing at all:

function cancelEvent(e) {
    if (!e) e = window.event;
    if (e.preventDefault) {
        e.preventDefault();
    } else {
        e.returnValue = false;
    }
}

If you want to both cancel the event for the link (i.e., prevent a click from executing the link) and prevent the event from bubbling to background elements, you can combine the two functions like this:

var link = document.getElementById("link");
link.onclick = function(e) {
    cancelEvent(e);
    stopEvent(e);
}

See the example

Comments

No, no and no. Definitively NO. Here you are dealing with IE and the rest of the world. So instead of testing over and over the event and the methods, create a generic method and update it if it is IE. This will be a lot of test the browser will not have to do anymore.

Another good practice is to use names that's mean something. Here, stopEvent and cancelEvent are really 2 names too close to let readers understand what's going on. And even if you are the creator of the code, you will need time to figure out what's going on 6 months later. There's a standard, we fixing IE only, so let's wrapper our events function into standard names.

function stopPropagation(e) { e.stopPropagation(); };
function preventDefault(e) { e.preventDefault(); };

/*@cc_on
stopPropagation = function() { window.event.cancelBubble = true; };
preventDefault = function() { window.event.returnValue = false; };
@*/
Laurent: Wake up on the wrong side of the bed this morning? ;)

I think you have a slight misunderstanding of browser performance optimization. These tests will have no impact on your application's performance, as execution time is almost always overwhelmed by DOM manipulation and redrawing in all browsers and platforms.

I appreciate your feedback though, keep it coming.
Cuando termino de ejecutar ajax y tengo que traer los datos me muestra antes un formulario de windows con un icono de advertencia que me muestra por codigo lo que va a desplegar y tiene un boton aceptar, luego de clickear sobre el ejecuta barbaro,
lo que necesito es capturar el evento de ese boton para ejecutarlo por codigo y que no se vea.
como lo puedo capturar??
quisiera hacer lo mismo que hicistes con el link pero con un Form of windows y un button
thanks
What about Opera? In opera this script do not work!
I mean not work for Tab key...
lukom: opera?? who the f*** is opera? ;)

Write a Comment