Je recherche des informations sur la manière d'implémenter la gestion d'événements personnalisée dans jquery de la meilleure façon. Je sais comment connecter des événements à partir des éléments dom comme 'click', etc., mais je construis une minuscule bibliothèque / plugin javascript pour gérer certaines fonctionnalités de prévisualisation.
J'ai un script en cours d'exécution pour mettre à jour du texte dans un élément dom à partir d'un ensemble de règles et d'entrées de données / utilisateur que j'ai, mais maintenant j'ai besoin du même texte affiché dans d'autres éléments que ce script ne peut pas connaître. Ce dont j'ai besoin, c'est d'un bon modèle pour observer d'une manière ou d'une autre ce script produisant le texte nécessaire.
Alors comment faire ça? Ai-je négligé certaines fonctionnalités intégrées de jquery pour déclencher / gérer les événements utilisateur ou ai-je besoin d'un plugin jquery pour le faire? Selon vous, quel est le meilleur moyen / plugin pour gérer cela?
Réponses:
Regarde ça:
(réimprimé de la page du blog expiré http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/ sur la base de la version archivée à http://web.archive.org/web /20130120010146/http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/ )
Publier / S'abonner avec jQuery
17 juin 2008
En vue d'écrire une interface utilisateur jQuery intégrée à la fonctionnalité hors ligne de Google Gears, j'ai joué avec du code pour interroger l'état de la connexion réseau à l'aide de jQuery.
L'objet de détection de réseau
Le principe de base est très simple. Nous créons une instance d'un objet de détection de réseau qui interrogera une URL à intervalles réguliers. Si ces requêtes HTTP échouent, nous pouvons supposer que la connectivité réseau a été perdue ou que le serveur est tout simplement inaccessible à l'heure actuelle.
$.networkDetection = function(url,interval){ var url = url; var interval = interval; online = false; this.StartPolling = function(){ this.StopPolling(); this.timer = setInterval(poll, interval); }; this.StopPolling = function(){ clearInterval(this.timer); }; this.setPollInterval= function(i) { interval = i; }; this.getOnlineStatus = function(){ return online; }; function poll() { $.ajax({ type: "POST", url: url, dataType: "text", error: function(){ online = false; $(document).trigger('status.networkDetection',[false]); }, success: function(){ online = true; $(document).trigger('status.networkDetection',[true]); } }); }; };
Vous pouvez voir la démo ici. Configurez votre navigateur pour qu'il fonctionne hors ligne et voyez ce qui se passe…. non, ce n'est pas très excitant.
Déclenchement et liaison
Ce qui est passionnant (ou du moins ce qui m'excite), c'est la méthode par laquelle le statut est relayé via l'application. Je suis tombé sur une méthode largement non discutée d'implémentation d'un système pub / sous en utilisant les méthodes de déclenchement et de liaison de jQuery.
Le code de démonstration est plus obtus qu'il ne devrait l'être. L'objet de détection de réseau publie les événements de «statut» dans le document qui les écoute activement et publie à son tour les événements de «notification» à tous les abonnés (nous en parlerons plus tard). Le raisonnement derrière cela est que dans une application du monde réel, il y aurait probablement plus de logique contrôlant quand et comment les événements de «notification» sont publiés.
$(document).bind("status.networkDetection", function(e, status){ // subscribers can be namespaced with multiple classes subscribers = $('.subscriber.networkDetection'); // publish notify.networkDetection even to subscribers subscribers.trigger("notify.networkDetection", [status]) /* other logic based on network connectivity could go here use google gears offline storage etc maybe trigger some other events */ });
En raison de l'approche centrée DOM de jQuery, les événements sont publiés dans (déclenchés sur) les éléments DOM. Cela peut être la fenêtre ou l'objet de document pour les événements généraux ou vous pouvez générer un objet jQuery à l'aide d'un sélecteur. L'approche que j'ai adoptée avec la démo est de créer une approche presque en espace de noms pour définir les abonnés.
Les éléments DOM qui doivent être abonnés sont simplement classés par «abonné» et «détection de réseau». On peut alors publier des événements uniquement sur ces éléments (dont il n'y en a qu'un dans la démo) en déclenchant un événement de notification sur
$(“.subscriber.networkDetection”)
Le
#notifier
div qui fait partie du.subscriber.networkDetection
groupe d'abonnés a alors une fonction anonyme qui lui est liée, agissant effectivement en tant qu'auditeur.$('#notifier').bind("notify.networkDetection",function(e, online){ // the following simply demonstrates notifier = $(this); if(online){ if (!notifier.hasClass("online")){ $(this) .addClass("online") .removeClass("offline") .text("ONLINE"); } }else{ if (!notifier.hasClass("offline")){ $(this) .addClass("offline") .removeClass("online") .text("OFFLINE"); } }; });
Alors, voilà. Tout est assez verbeux et mon exemple n'est pas du tout passionnant. Cela ne présente pas non plus quelque chose d'intéressant que vous puissiez faire avec ces méthodes, mais si quelqu'un est intéressé à fouiller dans la source, n'hésitez pas. Tout le code est en ligne dans la tête de la page de démonstration
la source
Le lien fourni dans la réponse acceptée montre une bonne façon d'implémenter le système pub / sous en utilisant jQuery, mais j'ai trouvé le code un peu difficile à lire, voici donc ma version simplifiée du code:
http://jsfiddle.net/tFw89/5/
$(document).on('testEvent', function(e, eventInfo) { subscribers = $('.subscribers-testEvent'); subscribers.trigger('testEventHandler', [eventInfo]); }); $('#myButton').on('click', function() { $(document).trigger('testEvent', [1011]); }); $('#notifier1').on('testEventHandler', function(e, eventInfo) { alert('(notifier1)The value of eventInfo is: ' + eventInfo); }); $('#notifier2').on('testEventHandler', function(e, eventInfo) { alert('(notifier2)The value of eventInfo is: ' + eventInfo); });
la source
n
nombre d'arguments.var eventData = [].slice.call(arguments).splice(1)
Je pense que oui ... il est possible de «lier» des événements personnalisés, comme (à partir de: http://docs.jquery.com/Events/bind#typedatafn ):
$("p").bind("myCustomEvent", function(e, myName, myValue){ $(this).text(myName + ", hi there!"); $("span").stop().css("opacity", 1) .text("myName = " + myName) .fadeIn(30).fadeOut(1000); }); $("button").click(function () { $("p").trigger("myCustomEvent", [ "John" ]); });
la source
myCustomEvent
est levée, la liaison en haut ajoute un auditeur.J'avais une question similaire, mais je cherchais en fait une réponse différente; Je cherche à créer un événement personnalisé. Par exemple au lieu de toujours dire ceci:
$('#myInput').keydown(function(ev) { if (ev.which == 13) { ev.preventDefault(); // Do some stuff that handles the enter key } });
Je veux l'abréger en ceci:
$('#myInput').enterKey(function() { // Do some stuff that handles the enter key });
trigger et bind ne racontent pas toute l'histoire - c'est un plugin JQuery. http://docs.jquery.com/Plugins/Authoring
La fonction "enterKey" est attachée en tant que propriété à jQuery.fn - c'est le code requis:
(function($){ $('body').on('keydown', 'input', function(ev) { if (ev.which == 13) { var enterEv = $.extend({}, ev, { type: 'enterKey' }); return $(ev.target).trigger(enterEv); } }); $.fn.enterKey = function(selector, data, fn) { return this.on('enterKey', selector, data, fn); }; })(jQuery);
http://jsfiddle.net/b9chris/CkvuJ/4/
Une des particularités ci-dessus est que vous pouvez gérer la saisie au clavier avec élégance sur les écouteurs de lien comme:
$('a.button').on('click enterKey', function(ev) { ev.preventDefault(); ... });
Modifications: mise à jour pour transmettre correctement le bon
this
contexte au gestionnaire et pour renvoyer toute valeur de retour du gestionnaire à jQuery (par exemple, au cas où vous cherchiez à annuler l'événement et à faire des bulles). Mis à jour pour transmettre un objet d'événement jQuery approprié aux gestionnaires, y compris le code de clé et la possibilité d'annuler l'événement.Ancien jsfiddle: http://jsfiddle.net/b9chris/VwEb9/24/
la source
scroll
, qui ne se propage pas. Je pense qu'au lieu d'avoir les auditeurs codés en dur sur le corps, j'ai besoin des éléments qui ont leon
-event lié à eux pour déclencher l'événement eux-mêmes.C'est un ancien message, mais je vais essayer de le mettre à jour avec une nouvelle information.
Pour utiliser des événements personnalisés, vous devez le lier à un élément DOM et le déclencher. Vous devez donc utiliser
et
Le code ressemble à ceci:
$(document).on("getMsg", { msg: "Hello to everyone", time: new Date() }, function(e, param) { console.log( e.data.msg ); console.log( e.data.time ); console.log( param ); }); $( document ).trigger("getMsg", [ "Hello guys"] );
Une belle explication peut être trouvée ici et ici . Pourquoi exactement cela peut-il être utile? J'ai trouvé comment l'utiliser dans cette excellente explication de l' ingénieur Twitter .
PS En javascript simple, vous pouvez le faire avec le nouveau CustomEvent , mais méfiez-vous des problèmes d'IE et de Safari.
la source
Voici comment je crée des événements personnalisés:
var event = jQuery.Event('customEventName'); $(element).trigger(event);
Certes, vous pouvez simplement faire
$(element).trigger('eventname');
Mais la façon dont j'ai écrit vous permet de détecter si l'utilisateur a empêché le défaut ou non en faisant
var prevented = event.isDefaultPrevented();
Cela vous permet d'écouter la demande de votre utilisateur final d'arrêter de traiter un événement particulier, par exemple si vous cliquez sur un élément de bouton dans un formulaire mais que vous ne souhaitez pas que le formulaire soit publié en cas d'erreur.
J'écoute généralement les événements comme ça
$(element).off('eventname.namespace').on('eventname.namespace', function () { ... });
Encore une fois, tu pourrais juste faire
$(element).on('eventname', function () { ... });
Mais j'ai toujours trouvé cela un peu dangereux, surtout si vous travaillez en équipe.
Il n'y a rien de mal à ce qui suit:
$(element).on('eventname', function () {});
Cependant, supposons que je doive dissocier cet événement pour une raison quelconque (imaginez un bouton désactivé). Je devrais alors faire
$(element).off('eventname', function () {});
Cela supprimera tous les
eventname
événements de$(element)
. Vous ne pouvez pas savoir si quelqu'un dans le futur liera également un événement à cet élément, et vous dissocieriez également cet événement par inadvertance.Le moyen le plus sûr d'éviter cela est d'espacer les noms de vos événements en faisant
$(element).on('eventname.namespace', function () {});
Enfin, vous avez peut-être remarqué que la première ligne était
$(element).off('eventname.namespace').on('eventname.namespace', ...)
Je personnellement toujours unbind un événement avant de se lier juste pour vous assurer que le même gestionnaire d'événements ne fait jamais appelé plusieurs fois (imaginez ce fut le bouton soumettre un formulaire de paiement et l'événement avait été lié 5 fois)
la source