基本上我想要的是能够向我的聚合物按钮添加一个“onTap”属性:
<paper-button onTap={this.handleTap}></paper-button>
到目前为止,我已经尝试了以下方法。前四个不起作用,我觉得后两个非常难吃:
1) 编写一个自定义的 React 事件插件。由于多种原因,这不起作用。虽然乍一看似乎您可以将“tap”事件添加到 React 监听的事件集中,但是没有办法扩展 topEventMapping
ReactBrowserEventEmitter.js
中的表.
(有人想知道 this code 是如何工作的,答案很可能是行不通 - 它已经过时了。)
(一个相关的问题是 react 插件系统非常奇怪,它似乎竭尽全力阻止任何人添加新插件——就像你必须重置整个事件系统并重新注册所有内置的-如果您想添加一个新插件,请在插件中。)
2) 创建一个 mixin 类,将“tap”事件监听器添加到 React 组件的根元素。 mixin 会查看事件目标并从属性中获取处理函数的名称,然后将事件分派(dispatch)给它。
根据 this article,这不起作用,因为源自 Web 组件的事件不会传播以正确响应组件.因此永远不会触发事件监听器。
3) 在窗口对象上添加事件监听器,然后将事件路由到原始组件。尽管事件确实被窗口监听器接收到,但是没有方法可以在给定元素引用的情况下定位 react 组件。 (至少,不适用于 Meteor 1.2 的 React 版本。)
4) 对所有具有 'onTap' 属性的 DOM 元素执行 querySelector 搜索,并分别为每个元素添加一个事件监听器。这可以在 React 组件的混合类中完成。
问题是无法从 querySelector 结果中排除子组件中的元素,因此如果您有嵌套的 React 组件,每个组件内部都有 Web 组件,事件将触发多个处理程序。
5) 将每个 Web 组件包装在一个 React 组件中。虽然这是 React 推荐的方法,但它的工作量很大(我使用了几十个 Polymer 组件,每个组件都有很多属性)而且它在代码膨胀和反惯用代码方面效率低下 - 生成的 HTML 代码看起来不再像 Polymer 代码。
6) 使用“ref”获取对每个 Web 组件的引用,并手动为每个组件添加一个监听器。这可行,但它很丑陋并且使代码困惑很多(请记住您还必须取消订阅)。我想要“onTap”的全部原因是我可以避免编写所有这些样板文件。
最佳答案
你可以尝试使用xeact .
import xeact, {dispatchEvent, Component} from 'xeact';
@xeact('paper-button')
export default class PaperButton extends Component {
handleTap() {
dispatchEvent(this, 'tap' , {
data
});
}
render() {
return <div onClick={() => {this.handleTap()}} />
}
}
然后将其用作 html 中的 web 组件
<x-paper-button></x-paper-button>
<script>
document.querySelector('x-paper-button').addEventListener('tap',
function(){
// onTap
})
</script>
关于javascript - 在 React 中监听 Web 组件事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35448371/