【问题标题】:Nested events not working for window.onload or DOMContentLoaded嵌套事件不适用于 window.onload 或 DOMContentLoaded
【发布时间】:2021-11-04 16:04:40
【问题描述】:

我在 JavaScript ES6 中编写了一些组件,它们有多个事件,但是当我在窗口的加载事件上插入另一个类时,class1 窗口事件不会加载 Class2。我也尝试过使用 DOMContentLoaded,但我仍然得到相同的结果。我该怎么做才能使事件嵌套在 window 或 DOMContentLoaded 事件的 load 事件事件中?对于这种情况有什么解决方法,可以完成吗?下面是我的代码示例,我试图让 Class2 控制台注销,但它不会!

class Accordian {
  constructor(selector) {
    this.selector = selector;
    this.build();
  }
  
  build() {
    const self = this;
    window.addEventListener('DOMContentLoaded', (event) => {
      this.el = document.querySelector(this.selector);
      this.dispatch('accordian__load', event, { el: this.el });
    }, true);
  }
  
  on(name, callback) {
    var func = this['on' + name];

    if (!func) this['on' + name] = [callback];
    else func.push(callback);

    return this;
  }

  dispatch(name, event, ...props) {
    var callbacks = this['on' + name];
    if (callbacks)
      callbacks.forEach((callback) => callback.call(this, event, ...props));
  }

}

class Checkbox {
  constructor(selector) {
    this.selector = selector;
    this.build();
  }
  
  build() {
    const self = this;
    window.addEventListener('DOMContentLoaded', (event) => {
      this.el = document.querySelector(this.selector);
      this.dispatch('checkbox__load', event, { el: this.el });
    }, true);
  }
  
  on(name, callback) {
    var func = this['on' + name];

    if (!func) this['on' + name] = [callback];
    else func.push(callback);

    return this;
  }
    
  dispatch(name, event, ...props) {
    var callbacks = this['on' + name];
    if (callbacks)
      callbacks.forEach((callback) => callback.call(this, event, ...props));
  }

}

var accordian = new Accordian('#accordian')
var checkbox = new Checkbox('#chk_enable');

accordian.on('accordian__load', function(event, props) {
  console.log('accordian load');
  console.log(props);
  checkbox.on('checkbox__load', function(event, props) {
    console.log('checkbox load');
    console.log(props);
  });
});
<div id="accordian">
  <input type="checkbox" id="chk_enable">
</div>

【问题讨论】:

  • 要添加多个事件,请考虑使用window.addEventListener("load", event =&gt; { /* function body */})
  • @Iván 请给我一个例子,因为我试过了,但它不起作用
  • 理论上它应该和.onload一样工作。这是带有一些实时示例的文档:developer.mozilla.org/en-US/docs/Web/API/Window/load_event
  • @Iván 给我一个例子来回答我的问题,这就是我发布这个的原因。

标签: javascript php html ecmascript-6


【解决方案1】:

onload 只接受一个函数。避免这种情况的一种方法是使用addEventListener。为此,请更改您的:

window.onload = function(event) {
  self.dispatch('load', event, {});
}

window.addEventListener("load", function (event) {
  self.dispatch("load", event, {});
});

无论如何,Class2 对象是在 Class1“加载”事件中创建的。 window.onload 不会触发两次,因此您的 Class2“负载”不会触发。如果 Class2 对象是在 Class1 "load" 之外创建的,您可以使其工作。

最后,您在 build 方法中分配给没有 letconstself 变量。这样一来,您就将 self 重新定义为始终是最后一个构造的类:

class Class1 {
  constructor() {
    this.build();
  }
  
  build() {
    const self = this;
    window.addEventListener("load", function (event) {
      self.dispatch("load", event, {});
    });
  }
  
  on(name, callback) {
    const self = this;
    var callbacks = this['on' + name];

    if (!callbacks) this['on' + name] = [callback];
    else callbacks.push(callback);

    return this;
  }

  dispatch(name, event, ...props) {
      var callbacks = this['on' + name];
      if (callbacks)
        callbacks.forEach((callback) => callback.call(this, event, ...props));
  }

}

class Class2 {
  constructor() {
    this.build();
  }
  
  build() {
    const self = this;
    window.addEventListener("load", function (event) {
      self.dispatch("load", event, {});
    });
  }
  
  on(name, callback) {
        const self = this;
        var callbacks = this['on' + name];
    
        if (!callbacks) this['on' + name] = [callback];
        else callbacks.push(callback);
    
        return this;
    }
    
    dispatch(name, event, ...props) {
        var callbacks = this['on' + name];
        if (callbacks)
          callbacks.forEach((callback) => callback.call(this, event, ...props));
    }

}

var myclass1 = new Class1();

myclass1.on('load', function(event) {
  console.log('Class 1');
});

var myclass2 = new Class2();

myclass2.on('load', function(event) {
  console.log('Class 2');
});

【讨论】:

  • 但它不是嵌套的,这就是我想要完成的
  • 如果你想让它嵌套,它就行不通。嵌套时,执行顺序为:Register 1 -> onload(1) -> Register 2。注册2后,事件onload不会再次触发(已经用Class1触发了)。为什么要使用window.onload 来注册这些事件?
  • 如果你在 .on('load', function(){}) 范围之外声明变量,它会在加载函数内部触发
  • 检查我的原始代码我更新了它,有没有改进它
  • 我不知道你的用例,但是像这样将你的类与window.onload 联系起来通常是一个危险的想法,因为它只会触发一次。您通常可以以更有条理的方式实现相同的效果,只需将一个函数添加到 onload,然后从那里调用其他函数。但是,这取决于您想要实现的目标
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 2013-07-03
  • 1970-01-01
  • 2021-11-03
  • 2020-04-11
  • 2019-07-08
相关资源
最近更新 更多