2010-04-01 3 views
2

s'il vous plaît considérer le problème suivant:Combinaison de gestionnaires d'événements DOM0 et DOM2 - annulation d'un événement possible dans le gestionnaire DOM0?

(1) Vous avez attribué un gestionnaire d'événements en ligne à un élément DOM, comme si <a id="link1" href="..." onclick=" ... ´">

(2) Vous pouvez également attribuer un ou plusieurs autres gestionnaire d'événements (s) à l'événement onclick de link1 avec le mécanisme d'affectation spécifique DOM2 ou IE.

Le comportement vérifié dans FF3.019 et IE7 est: le gestionnaire assigné dans (1) est exécuté AVANT tous les gestionnaires assignés dans (2) en cas de clic. C'est sympa (donc, probablement, rien écrit dans la pierre ...). Mais comptons sur ce comportement pour un moment. QUESTION: est-il possible d'ANNULER le barbotage de l'événement click dans les gestionnaires assignés dans (2) DANS le gestionnaire assigné dans (1)?

Avant de crier: Bien sûr, pourquoi pas, voir ce qui suit: Supposons que vous affectez onclick = "if (ready1) renvoie true, sinon renvoie load (event);" pour lier1 et définir le chargement à être

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 
} 

dans certaines balises de script ci-dessus. Ceci n'empêche PAS la propagation (ni dans FF3.019 ni IE) aux gestionnaires assignés dans (2).

Tout indice apprécié! Merci d'avance!

Jannico

Contexte (ou: pourquoi voudrais-je faire cela?):

A) Lazy/chargement tardif de javascript pour reendering rapide du contenu.
-> vous voulez informer l'utilisateur qu'une fonctionnalité est en cours de chargement (au lieu de simplement désactiver un élément de l'interface utilisateur, ce qui n'est pas vraiment convivial - pourquoi ce bouton est-il désactivé ???). Vous souhaitez également utiliser un javascript minimal déjà intégré dans la page, car le chargement d'une bibliothèque javascript avec une requête supplémentaire va à l'encontre du but (sinon vous pouvez utiliser l'un des mécanismes implémentés qui permettent l'enregistrement des événements B), vous voulez aussi "libérer les bêtes" en un seul point "atomique" dans le temps, c'est-à-dire: vous ne voulez pas être obligé de intégrer/changer tous les gestionnaires assignés en (2) pour attendre une sorte de signal "maintenant vous êtes autorisé à travailler parce que tout est chargé", vous voulez simplement donner ce signal à la tête de la chaîne de traitement des événements (le gestionnaire affecté dans (1)) seulement, qui peut alors simplement commencer à propager l'événement à tout ce qui peut arriver (sinon, des réactions partielles à l'entrée de l'utilisateur peuvent se produire, car certaines fonctionnalités sont en réalité Ady attaché et d'autres fonctionnalités non - qui est potentiellement pire que ne rien faire;)

+0

* "QUESTION maintenant: est-il possible d'ANNULER le bouillonnement de l'événement click aux gestionnaires assignés dans (2)" * Juste FWIW, je ne dirais pas "bouillonner" là-bas, ça va faire réfléchir les gens événement bouillonnant le DOM. Vous voulez l'arrêter * propager * aux autres gestionnaires. –

+0

@ T.J. Crowder: en fait je lis "propagation" et je pense "événement bouillonnant dans le DOM";) –

+0

@Jannico: ce que vous cherchez est en fait dans le DOM niveau ** 3 ** spec, appelé 'stopImmediatePropagation()': http : //www.w3.org/TR/DOM-Level-3-Events/#events-event-type-stopImmediatePropagation Malheureusement, je ne crois pas qu'aucun navigateur l'implémente actuellement. –

Répondre

0

Réponse courte: Non

Réponse longue: Vous pouvez utiliser le premier gestionnaire pour définir une variable que le 2ème (et après) les gestionnaires vérifient. Voici un exemple rapide

<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"></script> 
<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> 

Tout cela semble très hacky cependant. Il semble que vous devriez utiliser des rappels d'achèvement à la place, ou l'application de certains continuation passing style.

+0

@ T.J.Crowder: merci, oui, devrait mieux lire "propagation". @Peter Bailey: la réponse courte "non" est triste. La vérification de quelque chose dans les autres gestionnaires pourrait être une solution, merci de l'avoir montré explicitement (désinstaller le gestionnaire onclick de (1) lorsque le premier gestionnaire de (2) est connecté à # link1 serait également un moyen possible - sans résoudre le problème transactionnel problème de "tous les gestionnaires disponibles"). Je voulais résoudre une sorte de situation «héritée» où je ne voulais pas changer les gestionnaires de type (2). Mais, ok, je vais laisser tomber cette idée alors;) Merci pour la réponse/commentaires! – Jannico

Questions connexes