创建JavaScript自定义事件

Gab*_*Gab 65 javascript events

我想用JavaScript创建一个自定义事件.

我有一个带有WebBrowser的WPF应用程序,以及一个带有JavaScript的HTML页面.

我使用打印机.当打印机的状态发生变化时,它会在.NET中触发事件.

然后,我OnPrinterStateChanged(state)使用InvokeScriptWebBrowser控件的函数调用JavaScript方法.

问题是我必须OnPrinterStateChanged(state)在我的网页中实现该方法.我无法更改方法的名称或订阅/取消订阅活动...

我想将JavaScript方法移到OnPrinterStateChanged(state)单独的JavaScript文件中.

我想要的是 :

  • 订阅/取消订阅我的HTML页面中的事件,并决定在触发事件时我想要做什么(例如:"function ChangeState")
  • 当触发.NET事件时,它会调用OnPrinterStateChanged(state)我单独的.js文件,然后触发JavaScript事件并ChangeState调用该函数.

我找到了一些解决方案,但我没有设法让它工作......最简单的方法是什么?

pla*_*alx 97

也许是这样的?

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);
});
Run Code Online (Sandbox Code Playgroud)

另一种解决方案是使用函数组合,但是很难删除特定的侦听器.

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');
});
Run Code Online (Sandbox Code Playgroud)

编辑:

以下是使用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);
});
Run Code Online (Sandbox Code Playgroud)


vsy*_*ync 6

我喜欢使用这个EventDispatcher构造函数方法,它使用虚拟元素隔离事件,这样就不会在任何现有的DOM元素上触发它们,也不会触发windowor document.

我正在使用CustomEvent而不是createEvent因为它是更新的方法.在这里阅读更多.

我喜欢用这些名称包装每个本机方法:

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);
Run Code Online (Sandbox Code Playgroud)

以上内容EventDispatcher可用于其他代码

(例如某些组件)

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

/////////////////////
// Some component: //
/////////////////////

var MyComponent = function(){
    // set some default value
    this.value = 1;

    // merge `EventDispatcher` instance into "this" ('MyComponent' instance)
    Object.assign(this, new EventDispatcher()); 
}

MyComponent.prototype = {
    set : function(v){
        this.value = v;
        this.trigger('change', v);
    }
}

var comp = new MyComponent();

// bind a listener to "comp" (which itself is an instance of "MyComponent")
comp.on('change', e =>{
    console.log("event type:", e.type, "  |  event value:", e.detail);
});

// set some value
comp.set(3);
Run Code Online (Sandbox Code Playgroud)