首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从自定义对象分派Javascript自定义事件

如何从自定义对象分派Javascript自定义事件
EN

Stack Overflow用户
提问于 2022-02-25 23:47:21
回答 1查看 144关注 0票数 0

我有两个脚本(下面非常简单的例子)-第一个控制显示指定的导航菜单在一个页面和我们在几个地方使用的不同类型的菜单。

代码语言:javascript
运行
复制
const NavMenu = function(selector) {
  this.menuItems = document.querySelectorAll(`${selector} li > a`);
  let This = this;      
  This.menuItems.forEach(item => {
    item.addEventListener('click', e => {
        item.classList.toggle('selected'); 
    });
  });
}

const myNavMenu = new NavMenu('.menu-wrap'); 

另一个用于特定页面上的一个特定目的,该页面包含一个由第一个脚本控制的菜单。

代码语言:javascript
运行
复制
(function () {
   const menuItems = document.querySelectorAll('.menu-wrap li > a');
   menuItems.forEach(item => {
     item.addEventListener('click', e => {
         const selectedItems = document.querySelectorAll('.menu-wrap li > a.selected');
         let str = '';
         if(selectedItems.length) {
           selectedItems.forEach((item, i) => {
             str += `${item.textContent} `;
           });
           document.querySelector('#results').innerText = `Selected: ${str}`;
         }
       });
   });
 })();

如您所见,第二个脚本有一个单击处理程序,它根据每个菜单项的状态执行一个操作("selected“与否)。因为该状态是由第一个脚本设置的,所以只有当第一个脚本的单击处理程序在第二个脚本之前运行时,这个状态才能工作。

我创建了一个版本,强制第二个脚本的单击处理程序首先运行(通过setTimeout)。单击项目,可以看到结果文本不匹配。https://codepen.io/daveh0/pen/GROXmrq

因为第一个脚本在许多其他地方使用,所以它需要独立于任何其他脚本运行,否则我只需要组合2。

我认为一个定制的事件就是答案。我在这里实现了一个:https://codepen.io/daveh0/pen/xxPaqzJ是从我找到的一个例子中实现的,但我不知道这是否是正确的方法。很管用,但这并不意味着一吨.

我认为事件应该以某种方式绑定到NavMenu对象,但是除了windowdocument或其他DOM元素之外,我无法让它进行分派。有人能为我指明正确的方向吗?我可以这样做:myMenu.addEventListener('done', e => //do some stuff)而不是把它附加到window上?或者如果我开始的时候,也可以让我知道很多事情。

我知道这是内置在jQuery,但这需要保持香草JavaScript -谢谢!

EN

回答 1

Stack Overflow用户

发布于 2022-02-26 17:59:52

最后,我使用了一个事件发射器类,我在这篇文章中找到了这个类(并从中学到了很多东西)。正如@Bergi在关于OP的评论中指出的那样,事件不能附加到普通对象上。因为脚本1可以在所有不同的情况下在任何地方使用,这在我看来是最标准和最符合逻辑的。

非常简单..。

  1. 在脚本1中创建发射器的实例: This.emitter = new MyEventEmitter();
  2. 在任何需要的地方用任何适当的数据发出事件(在脚本1中):This.emitter.emit("done", item);
  3. “侦听”事件,并在脚本2中适当处理: NavMenu.emitter.on("done", menuItem => {...});

下面是在这个科德芬中工作的全部内容。

代码语言:javascript
运行
复制
class MyEventEmitter {
  constructor() {
    this._events = {};
  }

  on(name, listener) {
    if (!this._events[name]) {
      this._events[name] = [];
    }
    this._events[name].push(listener);
  }

  removeListener(name, listenerToRemove) {
    if (!this._events[name]) {
      throw new Error(
        `Can't remove a listener. Event "${name}" doesn't exits.`
      );
    }
    const filterListeners = (listener) => listener !== listenerToRemove;
    this._events[name] = this._events[name].filter(filterListeners);
  }

  emit(name, data) {
    if (!this._events[name]) {
      throw new Error(`Can't emit an event. Event "${name}" doesn't exits.`);
    }
    const fireCallbacks = (callback) => {
      callback(data);
    };
    this._events[name].forEach(fireCallbacks);
  }
}

const NavMenu = function (selector) {
  this.menuItems = document.querySelectorAll(`${selector} li > a`);
  let This = this;
  This.emitter = new MyEventEmitter();
  This.menuItems.forEach((item) => {
    item.addEventListener("click", (e) => {
        item.classList.toggle("selected");
        This.emitter.emit("done", item);
    });
  });
};

const myNavMenu = new NavMenu(".menu-wrap");

(function (NavMenu) {
  const menuItems = document.querySelectorAll(".menu-wrap li > a");
  menuItems.forEach((item) => {
    item.addEventListener("click", (e) => {
      NavMenu.emitter.on("done", (menuItem) => {
        const selectedItems = document.querySelectorAll(
          ".menu-wrap li > a.selected"
        );
        let str = "Selected: ";
        if (selectedItems.length) {
          selectedItems.forEach((item, i) => {
            str += `${item.textContent} `;
          });
        } else {
          str += `none`;
        }
        document.querySelector("#results").innerText = `${str}`;
      });
    });
  });
})(myNavMenu);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71272883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档