Jea*_*eri 2 javascript web-component shadow-dom stenciljs
我前段时间开始使用 Stencil,今天我做了一个事件冒泡的实验。
基本上,我单击一个子元素并监听其父元素的mousedown。我所期望的是那event.target是我的子组件。这非常简单,例如,如果我使用常规 DOM 元素(而不是 Stencil)运行此测试,那么一切都会按预期工作
但在 Stencil 中event.target是父元素。这就是我所做的。我的父组件如下所示:
@Component({
tag: 'app-root',
styleUrl: 'app-root.scss',
shadow: true
})
export class MyApp {
@Listen('mousedown')
onMousedown(event) {
console.log(event.target, event.currentTarget);
}
render() {
return (
<div>
<my-element></my-element>
</div> );
}
}
Run Code Online (Sandbox Code Playgroud)
还有孩子
@Component({
tag: 'my-element',
styleUrl: './my-element.scss',
shadow: true
})
export class MyElement {
@Listen('mousedown')
onMouseDonw(e) {
console.log(e.target);
}
render() {
return ( <div>YO</div> );
}
}
Run Code Online (Sandbox Code Playgroud)
现在,正如我所说,当我单击 时my-element,我首先看到console.logfrom my-element,这证实了这event.target是my-element。但随后该事件到达其父级并且event.target(但也event.currentTarget)包含app-root。我注意到,当我设置shadow为falseof my时app-root,一切似乎都有效,但我不明白为什么,这是解决我的问题的唯一解决方案吗?
它被认为是 Shadow DOM 封装的一个特性。原始目标被隐藏为“内部实现”,而是事件被重新定位到宿主元素。
当您将侦听器附加Listen到 中的装饰器时MyApp,它会附加到组件的宿主元素,app-root在本例中就是如此。
不过,您可以使用它event.composedPath()来获取真正的目标(IE 和旧版 Edge 不支持)。
或者,您可以从组件内部捕获事件并将其作为自定义事件重新发出,然后转发真实事件或目标元素:
export class MyApp {
@Event() myMousedown: EventEmitter<MouseEvent>;
handleElementMousedown = (event: MouseEvent) => {
this.myMousedown.emit(event);
}
render() {
return (
<div>
<my-element onMousedown={handleElementMousedown} />
</div> );
}
}
Run Code Online (Sandbox Code Playgroud)
export class MyApp {
@Event() myMousedown: EventEmitter<MouseEvent>;
handleElementMousedown = (event: MouseEvent) => {
this.myMousedown.emit(event);
}
render() {
return (
<div>
<my-element onMousedown={handleElementMousedown} />
</div> );
}
}
Run Code Online (Sandbox Code Playgroud)
(免责声明:此代码未经测试)
| 归档时间: |
|
| 查看次数: |
2108 次 |
| 最近记录: |