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 :
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 noncreateEvent
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 });