簡體   English   中英

獲取 Web 組件內的事件目標

[英]Get event target inside a web component

錨元素 ( <a> ) 在用戶與 Web 組件交互時創建。 問題是,當單擊錨點時,我無法從 Web 組件的“外部”返回錨點元素。

我添加了一個事件監聽器來document監聽點擊事件。 當單擊 DOM 中某處的元素時,我希望e.target是被單擊的元素。 在 Web 組件內某處單擊的情況下,將返回自定義元素 ( <fancy-list></fancy-list> ) - 而不是單擊的元素。

當 shadow DOM 的模式設置為open ,DOM 應該是可訪問的。

 class Fancylist extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: 'open' }); const wrapper = document.createElement('div'); wrapper.innerHTML = `<ul></ul><button>Add item</button>`; shadow.appendChild(wrapper); this.on_root_click = this.on_root_click.bind(this); } connectedCallback() { this.ul_elm = this.shadowRoot.querySelector('ul'); this.shadowRoot.addEventListener('click', this.on_root_click, false); } on_root_click(e){ switch(e.target.nodeName){ case 'BUTTON': this.ul_elm.innerHTML += '<li><a href="p1">List item</a></li>'; break; case 'A': e.preventDefault(); console.log('You clicked a link!'); break; } } } customElements.define('fancy-list', Fancylist);
 <!DOCTYPE html> <html> <head> <title>List</title> <meta charset="utf-8" /> <script type="text/javascript"> document.addEventListener('DOMContentLoaded', e => { document.body.addEventListener('click', e => { //console.log(e.composedPath()); console.log(e.target); // why is this not returning an anchor element when an anchor is clickend inside the <fancy-list>? }, false); }, false); </script> </head> <body> <h1>List</h1> <fancy-list></fancy-list> </body> </html>

Shadow DOM 的目的正是為了從容器的角度屏蔽Shadow DOM 的 HTML 內容。

這也是為什么重新定位內部事件以暴露 Shadow DOM 主機的原因。

但是,您仍然可以通過獲取Event.path Array 屬性的第一項來獲取真正的目標。

event.path[0]

注意:當然它只適用於open Shadow DOM。

 class Fancylist extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: 'open' }); const wrapper = document.createElement('div'); wrapper.innerHTML = `<ul></ul><button>Add item</button>`; shadow.appendChild(wrapper); this.on_root_click = this.on_root_click.bind(this); } connectedCallback() { this.ul_elm = this.shadowRoot.querySelector('ul'); this.shadowRoot.addEventListener('click', this.on_root_click, false); } on_root_click(e){ switch(e.target.nodeName){ case 'BUTTON': this.ul_elm.innerHTML += '<li><a href="p1">List item</a></li>'; break; case 'A': e.preventDefault(); break; } } } customElements.define('fancy-list', Fancylist);
 <!DOCTYPE html> <html> <head> <title>List</title> <meta charset="utf-8" /> <script type="text/javascript"> document.addEventListener('DOMContentLoaded', e => { document.body.addEventListener('click', e => { console.log(e.path[0]); }, false); }, false); </script> </head> <body> <h1>List</h1> <fancy-list></fancy-list> </body> </html>

2021 年更新

正如現在評論的那樣,您應該使用event.composedPath()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM