views:

78

answers:

1

Dear expert,

please consider the following problem:

(1) You have assigned an inline event handler to a DOM element, like so <a id="link1" href="..." onclick=" ... ´">

(2) You also assign one or more further event handler(s) to the onclick event of link1 with the DOM2 or IE-specific assignment mechanism.

The verified behavior in FF3.019 and IE7 is: the handler assigned in (1) is executed BEFORE all handlers assigned in (2) in case of a click. This is nice (so, probably, nothing written into stone ...). But let's rely on this behaviour for a moment.

QUESTION now: is it possible to CANCEL the bubbling of the click event to the handlers assigned in (2) WITHIN the handler assigned in (1)?

Before you scream: Sure, why not, see the following: Assume you assign onclick="if (ready1) return true; else return loading(event);" to link1 and define loading to be

function loading(e) {
    // alert("Still loading functionality - sorry, slow line perhaps...");
    // no propagation
    if( e.stopPropagation ) { e.stopPropagation(); }
    e.cancelBubble = true;
    return false; // Cancel default handling
}

in some script tag above. This DOES NOT prevent propagation (neither in FF3.019 nor IE) to the handlers assigned in (2).

Any hint appreciated! Thanks in advance!

Jannico

Context (or: why would I want to do this?):

A) Lazy / Late loading of javascript for fast reendering of content.
-> you want to inform the user that some functionality is still loading (instead of simply disabling an UI element, which is not really user-friendly -- why is this button disabled???). You also want to use minimal javascript already embedded into the page, because loading a javascript library first with an additional request somewhat defeats the purpose (otherwise you could, of course, use one of the implemented mechanisms that allow event registration with guaranteed execution sequence (which you'll need for B, see below)

and B) you also want to "set the beasts free" at a single "atomic" point in time, that is: you don't want to be forced to integrate/change all handlers assigned in (2) to wait for some kind of signal "now you are allowed to work because everything is loaded", you simply want to give this signal to the head of the event processing chain (the handler assigned in (1)) only, which then can simply start propagating the event to whatever may come (otherwise, partial reactions to user input may occur, because some functionality is already attached and other functionality not -- which is potentially worse than doing nothing ;)

A: 

Short answer: No.

Long answer: You can use the first handler to set a variable that the 2nd (and subsequent) handlers check. Here's a quick example

<div id="outer">
  <a id="link1" href="#" onclick="return loading();">test</a>
</div>

<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">

var passCheck = false;

setTimeout( function()
{
  passCheck = true;
}, 5000 );

function loading()
{
  alert( 'a#link1 was clicked!' );
  return false;
}

$(function()
{
  $('#link1').click( function( event )
  {
    if ( !passCheck )
    {
      event.stopPropagation();
    }
  });

  $('#outer').click( function( event )
  {
    alert( 'div#outer was clicked!' );
  });
});

</script>

This all feels very hacky though. It feels like you should use some completion callbacks instead, or the application of some continuation passing style.

Peter Bailey
@T.J.Crowder: thanks, yeah, should better read "propagating". @Peter Bailey: the short answer "no" is sad. Checking something in the further handlers could be a solution, thanks for showing it explicitly (unsetting the onclick handler of (1) when the first handler of (2) is connected to #link1 would also be a possible way - though not solving the transactional problem of "not all handlers available"). I wanted to solve some kind of a "legacy" situation where I did not want to change the handlers of type (2). But, ok, I'll drop that idea then ;) Thanks for answer/comments!
Jannico