是否可以在主题/插件中将事件处理程序附加到小部件?

你好,

我想为主题列表中的项目添加点击事件处理程序(以便在某些条件下添加自定义行为)。是否可以使用类似 api.decorateWidget() 的方法来为特定类型的所有小部件实例添加事件处理程序?

——

其他已考虑的方案:

  • 在全局函数中使用 addEventListener 并不实际,因为页面加载后可能会动态加载额外的主题列表项(例如无限滚动)。这种实现需要使用类似 MutationObserver 的工具来观察 DOM 变化,并在渲染更多小部件时附加更多事件处理程序。
  • 虽然理论上可以为 body 元素附加点击事件处理程序,并通过事件冒泡进行监控(例如 jQuery 中使用的 $("body").on("click", ".list-item-topic", function())),但我需要能够调用 preventDefault()stopPropagation(),而我认为这种方法不支持这些操作。

api.attachWidgetAction 是正确的方法。你可以搜索代码库,很快就能搞定。

示例见此处

啊,谢谢!这些是标准的 DOM 事件吗?例如:

  • 从示例来看,这些事件似乎不是像 clickmouseover 等标准的 DOM 事件。是否可以实现类似 api.attachWidgetAction("topic-list-item", "click", ...) 的操作?
  • 是否可以访问 event 对象,例如调用 event.stopPropagation()
  • 如果这些不是标准的 DOM 事件,我该如何了解某个特定组件广播了哪些事件?

感谢您的指点!

另外:我有点困惑,如何找到与特定 UI 元素关联的“widget”?(在我的例子中,是负责在主题列表中显示单个主题的 topic-list-item 的 widget。)从 widget 目录 来看,似乎没有与 topic-list-item 相关的项。这个“组件” 似乎反而是负责渲染 topic-list-item 的。

我不太清楚 widget 和组件之间的区别(抱歉我对这些不太熟悉)——大概只能通过 api.attachWidgetAction 将事件处理器附加到“widget”上,而不能附加到“组件”上。那么,组件是否有等效的方法呢?

关于小部件和组件:

谢谢大家!已经解决了。

供将来想要覆盖组件事件处理器的其他人参考,请将以下内容添加到 javascripts/your-plugin-name/initializers/script-name-of-your-choice.js.es6

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "custom-click-handler",

  initialize() {
    withPluginApi("0.8.20", (api) => {
      api.modifyClass("component:topic-list-item", {
        click(e) {
          ...
        }
      });
    });
  },
};