2012-08-15 4 views
35

Je suis à la recherche d'un moyen simple et abstrait de cloner ou de redistribuer les événements DOM uniquement. Je ne suis pas intéressé par le clonage de noeuds DOM.Comment cloner ou redistribuer des événements DOM?

J'ai expérimenté un peu, lisez le DOM Events specification et je n'ai pas trouvé de réponse claire.

Idéalement, je suis à la recherche de quelque chose d'aussi simple que-:

handler = function(e){ 
    document.getElementById("decoy").dispatchEvent(e) 
} 
document.getElementById("source").addEventListener("click", handler) 

Cet exemple de code, bien sûr, ne fonctionne pas. Il existe une exception DOM indiquant que l'événement est en cours d'expédition - évidemment.

Je voudrais éviter de créer manuellement de nouveaux événements avec document.createEvent(), en les initialisant et en les envoyant.

Existe-t-il une solution simple à ce cas d'utilisation?

+0

Pourquoi avez-vous besoin d'une nouvelle répartition des événements? – josh3736

+0

J'ai besoin de cela comme une solution de contournement pour les régions CSS qui actuellement ne distribuent pas les événements de nœud enfant. Les régions ne restituent que le contenu du noeud enfant, elles n'agissent pas en tant que parentNodes. –

Répondre

63

Je sais, la question est vieux, et l'OP voulait éviter de créer/initialisation approche, mais il est un moyen relativement simple de dupliquer les événements:

new_event = new MouseEvent(old_event.type, old_event) 

Si vous voulez plus que les événements de la souris, vous pouvez faire quelque chose comme ceci:

new_event = new old_event.constructor(old_event.type, old_event) 

Et dans le contexte d'origine:

handler = function(e) { 
    new_e = new e.constructor(e.type, e); 
    document.getElementById("decoy").dispatchEvent(new_e); 
} 
document.getElementById("source").addEventListener("click", handler); 

(Pour les utilisateurs jQuery: vous devrez peut-être utiliser e.originalEvent.constructor au lieu de e.constructor)

+1

Notez que cela ne fonctionne que dans les versions modernes de Firefox et Chrome, et ne fonctionne dans aucune version de IE –

+3

@Alexis Je reçois: '' 'Uncaught TypeError: Illegal constructor''': ( – niieani

+0

@NIX dans quel navigateur? – Alexis

-2

Qu'en est-il de l'événement déclencheur?

Dans votre cas:

$('#decoy').trigger('click') 

Ou dans JS pur, vous pouvez le trouver dans How to trigger event in JavaScript?


MISE À JOUR

J'ai trouvé un chemin à travers jQuery:

  1. Comme écrit ici - jQuery find events handlers registered with an object vous devez obtenir l'événement nécessaire. Par exemple $('#decoy').data('events').click[0].handler;

  2. Vous pouvez maintenant obtenir un lien vers ce gestionnaire. Mais si vous voulez créer une copie indépendante du gestionnaire - utiliser ce code pour créer une copie du gestionnaire:


function clone_obj(obj){ 
    if(obj == null || typeof(obj) != 'object') return obj; 
    var temp = new obj.constructor(); 
    for(var key in obj) temp[key] = clone_obj(obj[key]); 
    return temp; 
} 
+1

Oui, je peux déclencher un nouvel événement, mais cela implique une configuration manuelle de son état pour refléter l'événement d'origine. Je cherche un moyen pour que le DOM gère le clonage de l'événement, quel qu'il soit: cliquez, touchez, etc. –

+0

J'ai ajouté la mise à jour avec la réponse – Rustam

Questions connexes