课堂上的自定义事件

2024-04-02

我需要从类启动自定义事件。我知道用 DOM 对象和 jquery 来做到这一点,使用triggerHandler,比如 $(object)..triggerHandler("inputChange", {param:X}); 问题是当我在一个类中尝试这个时,如下所示:

    var MyClass = (function(){

        var static_var = 1;

        var MyClass = function () {

            var privateVar;
            var privateFn = function(){ alert('Im private!'); };

            this.someProperty = 5;
            this.someFunction = function () {
                alert('Im public!');
            };
            this.say = function() {
                alert('Num ' + this.someProperty);
                $(this).triggerHandler("eventCustom");
            }
            this.alter = function() {
                this.someProperty ++;
            }
        };

        return MyClass;

    })();

    TheClass = new MyClass();

    $(TheClass).on('eventCustom', function() {
        alert('Event!');
    });

    TheClass.say();

这不会启动警告或错误,但事件侦听器不起作用(或未调度事件)。我认为 jQuery 事件系统不适用于非 DOM 对象,对吗?

还有其他方式(我需要事件,而不是针对我的具体情况的回调)来启动事件吗?

多谢!


我现在在不使用 JQuery 的情况下用不到 100 行代码编写了一个 ES6 事件类。如果你不想使用 DOM 事件,你可以扩展你的类,它应该处理事件。

要监听事件,您可以使用上、一次、onReady、onceReady。 On 是每次触发标签时执行回调函数。一次只有一次。如果标签之前已被触发,“就绪”函数将执行回调。

要触发事件,请使用触发器。要删除事件处理程序,请使用 off。

我希望这个例子能够清楚地表明:

class ClassEventsES6 {
                constructor() {
                    this.listeners = new Map();
                    this.onceListeners = new Map();
                    this.triggerdLabels = new Map();
                }

                // help-function for onReady and onceReady
                // the callbackfunction will execute, 
                // if the label has already been triggerd with the last called parameters
                _fCheckPast(label, callback) {
                    if (this.triggerdLabels.has(label)) {
                        callback(this.triggerdLabels.get(label));
                        return true;
                    } else {
                        return false;
                    }
                }

                // execute the callback everytime the label is trigger
                on(label, callback, checkPast = false) {
                    this.listeners.has(label) || this.listeners.set(label, []);
                    this.listeners.get(label).push(callback);
                    if (checkPast)
                        this._fCheckPast(label, callback);
                }

                // execute the callback everytime the label is trigger
                // check if the label had been already called 
                // and if so excute the callback immediately
                onReady(label, callback) {
                    this.on(label, callback, true);
                }

                // execute the callback onetime the label is trigger
                once(label, callback, checkPast = false) {
                    this.onceListeners.has(label) || this.onceListeners.set(label, []);
                    if (!(checkPast && this._fCheckPast(label, callback))) {
                        // label wurde nocht nicht aufgerufen und 
                        // der callback in _fCheckPast nicht ausgeführt
                        this.onceListeners.get(label).push(callback);
                }
                }
                // execute the callback onetime the label is trigger
                // or execute the callback if the label had been called already
                onceReady(label, callback) {
                    this.once(label, callback, true);
                }

                // remove the callback for a label
                off(label, callback = true) {
                    if (callback === true) {
                        // remove listeners for all callbackfunctions
                        this.listeners.delete(label);
                        this.onceListeners.delete(label);
                    } else {
                        // remove listeners only with match callbackfunctions
                        let _off = (inListener) => {
                            let listeners = inListener.get(label);
                            if (listeners) {
                                inListener.set(label, listeners.filter((value) => !(value === callback)));
                            }
                        };
                        _off(this.listeners);
                        _off(this.onceListeners);
                }
                }

                // trigger the event with the label 
                trigger(label, ...args) {
                    let res = false;
                    this.triggerdLabels.set(label, ...args); // save all triggerd labels for onready and onceready
                    let _trigger = (inListener, label, ...args) => {
                        let listeners = inListener.get(label);
                        if (listeners && listeners.length) {
                            listeners.forEach((listener) => {
                                listener(...args);
                            });
                            res = true;
                        }
                    };
                    _trigger(this.onceListeners, label, ...args);
                    _trigger(this.listeners, label, ...args);
                    this.onceListeners.delete(label); // callback for once executed, so delete it.
                    return res;
                }
            }
            
// +++ here starts the example +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class TestClassEvents extends ClassEventsES6 {
     constructor() {
        super();
        this.once('sayHallo', this.fStartToTalk);
        this.on('sayHallo', this.fSayHallo);
     }

     fStartToTalk() {
         console.log('I start to talk... ');
     }

     fSayHallo(name = 'Nobody') {
        console.log('Hallo ' + name);
     }
}

let testClassEvents = new TestClassEvents();

testClassEvents.trigger('sayHallo', 'Tony');
testClassEvents.trigger('sayHallo', 'Tim');

testClassEvents.onReady('sayHallo', e => console.log('I already said hello to ' + e));
testClassEvents.trigger('sayHallo', 'Angie');
testClassEvents.off('sayHallo');
testClassEvents.trigger('sayHallo', 'Peter');
console.log('I dont say hallo to Peter, because the event is off!')
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

课堂上的自定义事件 的相关文章

  • 检测 iframe 内容加载失败

    我可以使用以下命令检测 iframe 的内容何时加载load事件 不幸的是 就我的目的而言 这有两个问题 如果加载页面时出现错误 404 500 等 则永远不会触发加载事件 如果某些图像或其他依赖项加载失败 则会照常触发加载事件 有什么方法
  • 区分单击与 mousedown/mouseup

    我已经阅读了有关这种情况的 stackoverflow 上的几个答案 但没有一个解决方案有效 我尝试根据用户是否单击某个元素或使用 jQuery 将鼠标按住该元素来执行不同的操作 有可能做到这一点吗 onMouseDown 将在按下左侧或右
  • Chrome 扩展程序中的后台脚本到底何时运行?

    在我的 chrome 扩展中 我有一个后台脚本 它将使用XMLHttpRequest note that this code is in the global scope i e outside of any function also n
  • JSDoc:如何在生成的文档中包含自定义 css 文件模板?

    JS文档docs https jsdoc app about configuring default template html say 将图像目录复制到输出目录 复制全部 将 myproject static 中的静态文件复制到输出目录
  • 使用 ES6 模块导出/导入单个类方法?

    假设我有一个像这样的简单课程fileA js class foo constructor x this name x fooMethod x return x hello 我想导入并使用fooMethod in fileB js像这样 im
  • Bootstrap:下拉菜单无法通过 jQuery 单击打开

    我正在创建一个包含多行的表 所有行都有一个 选项 按钮 该按钮应该显示下拉上下文菜单 为了使代码更短 我使用了一个div以便将其重用为上下文菜单的通用标记 我正在使用 Bootstrap 5 1 3 和 jQuery 3 6 0 以下是我的
  • Relay 中的嵌套片段数据始终相同

    我是 Relay 新手 并且遇到了片段上嵌套数据的问题 当我在 graphiql 中进行测试时 以下查询返回正确的数据 因此我确信我的架构是正确的 viewer customers name billing address city 但是
  • django ajax post 403被禁止

    使用 django 1 4 当我尝试从我的 javascript 做我的 django 服务器上的帖子时 我收到 403 错误 我的 get 工作正常 尽管问题仅出在帖子上 也尝试过 csrf exempt但没有运气 更新 我现在可以发布我
  • 用于导出到 CSV/Excel 的数据 URI(无服务器端请求):浏览器支持/限制?

    以下问题 Javascript 或 Flash 导出至 CSV Excel https stackoverflow com questions 8150516 javascript or flash export to csv excel
  • Rxjs 可观察等待直到满足某些条件

    我有以下重试逻辑来重试操作 对于单个请求来说它工作得很好 对于多个正在进行的请求 我想在重试之前等待现有的重试逻辑完成 handleError errors Observable
  • CryptoJS 和 Pycrypto 一起工作

    我正在使用 CryptoJS v 2 3 加密 Web 应用程序中的字符串 并且需要在服务器上使用 Python 对其进行解密 因此我使用 PyCrypto 我觉得我错过了一些东西 因为我无法让它工作 这是JS Crypto AES enc
  • 在 中动态添加链接样式表 [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 如何将链接
  • 加载 Ember.View 的内容后初始化 jQuery 插件

    DEBUG Ember VERSION 1 0 0 rc 6 ember js DEBUG Handlebars VERSION 1 0 0 rc 4 ember js DEBUG jQuery VERSION 1 9 1 控制器是一个Em
  • 在浏览器上录制视频并上传到LAMP服务器

    我已经尝试了很多东西 red5 jquery 网络摄像头 html5 但这些解决方案都没有录制视频并准备好上传到服务器 无论如何 html5 flash 等等 更好的跨浏览器解决方案 最好的 上传视频 音频 并将结果上传到服务器 我猜是通过
  • 使用 JavaScript 从 URL 变量读取来加载不同的 CSS 样式表

    我试图在我的 WordPress 博客上使用两个不同的样式表 以便在通过 Web 访问页面时使用一个样式表 而在通过我们的 iOS 应用程序访问博客内容时使用另一个样式表 现在 我们将 app true 附加到来自 iOS 应用程序的 UR
  • 地址更改时如何停止 Angular 重新加载

    我正在使用 Angular 的scrollTo and anchorScroll像这样 app controller TestCtrl function scope location anchorScroll scope scrollTo
  • Chrome Prerender 功能每次都会被取消

    我正在尝试 Chrome 中的预渲染功能 但是当我检查网络时 我可以看到任何链接的请求都被取消 我使用以下语法 我尝试了现场演示http prerender test appspot com http prerender test apps
  • 从 Node.js 调用 execl、execle、execlp、execv、execvP 或 execvp 的方法

    POSIX 系统公开了一系列exec函数 允许人们将可能不同的东西加载到当前进程中 保留打开的文件描述符 进程标识符等 可以出于多种原因执行此操作 在我的情况下 这是引导 我想更改我自己的进程的命令行选项 然后在现有进程上重新加载它 这样就
  • 我可以防止将 Leaflet 地图平移到世界边缘之外吗?

    有没有办法限制平移到世界边缘之外 在这幅画中 棕色是世界 灰色是虚空 我想让它不可能像这样平移 Leaflet 允许您控制地图抵抗被拖出边界的程度maxBoundsViscosity选项 值 0 到 1 将其设置为最大值会完全禁用拖动出界
  • html5 canvas 使用图像作为蒙版

    是否可以使用具有形状的图像作为整个画布或画布内图像的蒙版 我想将图像放置在画布中 并在图像上添加蒙版 然后将其另存为新图像 您可以使用 source in globalCompositeOperation 将黑白图像用作蒙版 首先 将蒙版图

随机推荐