Créer un événement personnalisé JavaScript

Je souhaite créer un événement personnalisé en JavaScript.

J'ai une application WPF avec un WebBrowser à l'intérieur, et une page HTML avec JavaScript.

Je travaille avec une imprimante. Lorsque l'état de l'imprimante change, il déclenche un événement dans .NET.

Ensuite, j'appelle une méthode JavaScript OnPrinterStateChanged(state) avec la fonction InvokeScript du contrôle WebBrowser.

Le problème est que je dois implémenter la méthode OnPrinterStateChanged(state) dans ma page Web. Je ne peux pas modifier le nom de la méthode ou m'abonner / se désabonner à l'événement …

Je souhaite déplacer la méthode JavaScript OnPrinterStateChanged(state) dans un fichier JavaScript séparé.

Ce que je veux :

  • Abonnez-vous / Désabonnez-vous à l'événement dans ma page HTML et décidez ce que je veux faire lorsque l'événement est déclenché (ex: "function ChangeState")
  • Lorsque l'événement .NET est déclenché, il appelle OnPrinterStateChanged(state) de mon fichier .js distinct, puis l'événement JavaScript est déclenché et la fonction ChangeState est appelée.

J'ai trouvé des solutions, mais je n'ai pas réussi à le faire fonctionner … Quelle est la manière la plus simple de le faire?

Peut-être quelque chose comme ça?

 function OnPrinterStateChanged(state) { var evt = new CustomEvent('printerstatechanged', { detail: state }); window.dispatchEvent(evt); } //Listen to your custom event window.addEventListener('printerstatechanged', function (e) { console.log('printer state changed', e.detail); }); 

Une autre solution serait d'utiliser la composition de la fonction, mais il serait difficile d'enlever les auditeurs spécifiques.

 function OnPrinterStateChanged(state) {} function compose(fn1, fn2) { return function () { fn1.apply(this, arguments); fn2.apply(this, arguments); }; } //Add a new listener OnPrinterStateChanged = compose(OnPrinterStateChanged, function (state) { console.log('listener 1'); }); //Add another one OnPrinterStateChanged = compose(OnPrinterStateChanged, function (state) { console.log('listener 2'); }); 

MODIFIER:

Voici comment vous pouvez le faire avec jQuery.

 function OnPrinterStateChanged(state) { var evt = $.Event('printerstatechanged'); evt.state = state; $(window).trigger(evt); } //Listen to your custom event $(window).on('printerstatechanged', function (e) { console.log('printer state changed', e.state); }); 

J'aime utiliser cette méthode de constructeur EventDispatcher qui, en utilisant un élément fictif, isole les événements afin qu'ils ne soient pas déclenchés sur un élément DOM existant, ni la window ni le document .

J'utilise CustomEvent et non createEvent car c'est l'approche la plus récente. Lire la suite ici .

J'aime envelopper chaque méthode native avec ces noms:

on , off , trigger

 function EventDispatcher(){ // Create a dummy DOM element var dummy = document.createTextNode(''); // Create custom wrappers with nicer names this.off = dummy.removeEventListener.bind(dummy); this.on = dummy.addEventListener.bind(dummy); this.trigger = function(eventName, data){ if( !eventName ) return; var e = new CustomEvent(eventName, {"detail":data}); dummy.dispatchEvent(e); } } //////////////////////////////////// // initialize the event dispatcher by creating an instance in an isolated way var myEventDispatcher = new EventDispatcher(); //////////////////////////////////// // listen to a "foo" event myEventDispatcher.on('foo', e =>{ console.log(e.type, e.detail); }); //////////////////////////////////// // trigger a "foo" event with some data myEventDispatcher.trigger('foo', 123); 

Ok j'ai trouvé une solution.

J'ai dû changer la version IE de WebBrowser vers Internet Explorer 11: http://weblog.west-wind.com/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version

Et alors :

 function OnPrinterStateChanged(state) { var evt = document.createEvent("Event"); evt.state = state; evt.initEvent("printerstatechanged", true, false); window.dispatchEvent(evt); } window.addEventListener('printerstatechanged', function (e) { // Do something });