Il n'y a rien de mal avec cette configuration (ou y en a-t-il?), Mais puis-je l'adoucir un peu?
Regardez plutôt l'utilisation de la délégation d'événements. C'est là que vous surveillez l'événement sur un conteneur qui ne disparaît pas, puis utilisez event.target
(ouevent.srcElement
sur IE) pour déterminer où l'événement s'est réellement produit et le gérer correctement.
De cette façon, vous n'attachez le ou les gestionnaires qu'une seule fois, et ils continuent de fonctionner même lorsque vous échangez du contenu.
Voici un exemple de délégation d'événements sans utiliser de bibliothèques d'assistance:
(function() {
var handlers = {};
if (document.body.addEventListener) {
document.body.addEventListener('click', handleBodyClick, false);
}
else if (document.body.attachEvent) {
document.body.attachEvent('onclick', handleBodyClick);
}
else {
document.body.onclick = handleBodyClick;
}
handlers.button1 = function() {
display("Button One clicked");
return false;
};
handlers.button2 = function() {
display("Button Two clicked");
return false;
};
handlers.outerDiv = function() {
display("Outer div clicked");
return false;
};
handlers.innerDiv1 = function() {
display("Inner div 1 clicked, not cancelling event");
};
handlers.innerDiv2 = function() {
display("Inner div 2 clicked, cancelling event");
return false;
};
function handleBodyClick(event) {
var target, handler;
event = event || window.event;
target = event.target || event.srcElement;
while (target && target !== this) {
if (target.id) {
handler = handlers[target.id];
if (handler) {
if (handler.call(this, event) === false) {
if (event.preventDefault) {
event.preventDefault();
}
return false;
}
}
}
else if (target.tagName === "P") {
display("You clicked the message '" + target.innerHTML + "'");
}
target = target.parentNode;
}
}
function display(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
})();
Exemple en direct
Notez que si vous cliquez sur les messages qui sont ajoutés dynamiquement à la page, votre clic est enregistré et géré même s'il n'y a pas de code pour accrocher les événements sur les nouveaux paragraphes ajoutés. Notez également que vos gestionnaires ne sont que des entrées dans une carte et que vous avez un gestionnaire sur le document.body
qui s'occupe de toute la répartition. Maintenant, vous enracinez probablement cela dans quelque chose de plus ciblé que document.body
, mais vous voyez l'idée. De plus, dans ce qui précède, nous distribuons essentiellement par id
, mais vous pouvez faire des correspondances aussi complexes ou simples que vous le souhaitez.
Bibliothèques JavaScript modernes comme jQuery , Prototype , YUI , Closure ou l' un de plusieurs autres devraient offrir des fonctionnalités de délégation d'événements pour lisser les différences de navigateur et gérer proprement les cas de bord. jQuery le fait certainement, avec ses fonctions live
et ses delegate
fonctions, qui vous permettent de spécifier des gestionnaires en utilisant une gamme complète de sélecteurs CSS3 (et plus encore).
Par exemple, voici le code équivalent utilisant jQuery (sauf que je suis sûr que jQuery gère les cas de bord, la version brute prête à l'emploi ci-dessus ne le fait pas):
(function($) {
$("#button1").live('click', function() {
display("Button One clicked");
return false;
});
$("#button2").live('click', function() {
display("Button Two clicked");
return false;
});
$("#outerDiv").live('click', function() {
display("Outer div clicked");
return false;
});
$("#innerDiv1").live('click', function() {
display("Inner div 1 clicked, not cancelling event");
});
$("#innerDiv2").live('click', function() {
display("Inner div 2 clicked, cancelling event");
return false;
});
$("p").live('click', function() {
display("You clicked the message '" + this.innerHTML + "'");
});
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
})(jQuery);
Copie en direct