stopPropagation and startPropagation

Piotr Wójcik picture Piotr Wójcik · Jul 17, 2013 · Viewed 27.9k times · Source

I want to make an additional click handler (client page, cant modify his js/html) and it should work like this in my script:

1) event.stopPropagation (pause client click propagation)
2) my function (do my function, when everything is done do next)
3) event.startPropagation (continue standard client action)

Right now, the first and second work. The third is the problem.
I know event.startPropagation doesn't exist, but I want something like that. Any hints?

Answer

David Hellsing picture David Hellsing · Jul 17, 2013

You can re-trigger the same event object on the parent node, f.ex (jQuery). You will need to copy the event object first and pass it into the trigger in order to capture the same event properties in the bubble (f.ex e.pageX):

var copy = $.extend(true, {}, e);
setTimeout(function() {
    $(copy.target.parentNode).trigger(copy);
},500);
e.stopPropagation();

Demo: http://jsfiddle.net/GKkth/

EDIT

Based on your comment, I think you are looking for something like:

$.fn.bindFirst = function(type, handler) {
    return this.each(function() {
        var elm = this;
        var evs = $._data(this).events;
        if ( type in evs ) {
            var handlers = evs[type].map(function(ev) {
                return ev.handler;
            });
            $(elm).unbind(type).on(type, function(e) {
                handler.call(elm, e, function() {
                    handlers.forEach(function(fn) {
                        fn.call(elm);
                    });
                });
            });
        }
    });
};

This prototype allows you to bind a "premium handler" that holds a next function that will execute all previous handlers to the same element when you want to. Use it like:

$('button').click(function() {
    console.log('first');
}).click(function() {
    console.log('second');
}).bindFirst('click', function(e, next) {
    console.log('do something first');
    setTimeout(next, 1000); // holds the other handlers for 1sec
});

DEMO: http://jsfiddle.net/BGuU3/1/