开发者

Intercepting JavaScript event invocations (add an event listener to always be invoked first or alternative)

I'm looking for a way to prevent an event listener receiving any notification of the event before another event listener has confirmed that it is alright to proceed.

My initial thought was to bind my event listener that determines whether all other event listeners for that element should be triggered, as the first event listener in the chain. Having investigated this - it doesn't seem possible (at least not with my combination of ways event listeners are bound to an element).

To provide some context:

I have a list of items on a web-page. When a user clicks one of these 'item links' another area of the page is populated with a form where the user can then modify some of the item's properties. For the modified item's properties to be persisted, the user must click an 'Update' button that relates to the form.

My aim is to ensure that if the user modifies an item's property without clicking 'Update' but then clicks on another 'item link', they must confirm that they are happy to disregard the changes they have just made.

My attempted solution:

  1. Bind a change event listener to all form elements that sets a JavaScript 'hasChanges' field to true.
  2. Add a class to all 'item links' that identifies them as links that will cause the user to loose changes.
  3. Using jQuery, bind click and keypress event listeners to all elements with this class to display a confirm pop-up if 'hasChanges' is true.
  4. If the user wishes to save their changes, by clicking cancel, stop propagation of the event.

Issue with this is that the 'item links' elements already have a (Java) Spring AJAX decoration click event listener to update the section of the page that allows the user to modify an item's properties, and this is always invoked before the event listener that displays the confirmation. Realistically I don't think I can bind the event listener for the confirmation to proceed before the AJAX decorations to ensure that the confirmation is displayed before the item properties form section of the page is updated.

Does anyone have any suggestions?

Update:

The suggested solution was to set the 'capture' flag to true. So my code that adds an event listener to the 'item links' now looks like this:

$("." + linkClassName).each(function()
{开发者_如何学JAVA
    if ($.browser.msie)
    {
        this.setCapture(true);
        this.attachEvent("onclick", _self.linksFunction);
    }
    else
    {
        this.addEventListener("click", _self.linksFunction, true);
    }
});

However, having added logging (to Firefox's console) to all functions invoked on click of an 'item link', my function linksFunction is still the last to be called. Have I done something wrong?


Use addEventListener with capture set to true.

Read all about it here: https://developer.mozilla.org/en/DOM/element.addEventListener

Update:

If IE support is needed, use setCapture.
It only supports mouse events, but as far as i can tell that is all you need.

Update again:

Sorry, I was too quick, to use capturing is a useless answer since it will not solve your problem.

The only way i see of doing what you wish is to use global click delegation. That way you will have a single point where all your click events will go through and you can thus control the events through there.

There are several downsides to this solution however that you might not like. One obvious one is that you can forget about normal event bubbling, since the delegation is based on the last step in the bubbling phase. another one is that you will have to go about attaching events in a completely different way than you are used to.

That said, if you can live with this, it can be a fantastic way of handling click events, one I have preferred to use for the past couple of years myself. You end up having only a single click event registered in your entire page (on document.body) and you then build a tiny framework around binding/unbinding events to css selectors, and manual triggering if needed.

Some of the benefits with this method is that you can register click events before the elements exist, since you are not registering them on the elements themselves, which is great if you build the site on the fly using client side templates for instance.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜