在Web Component的connectedCallback中使用jQuery访问子元素
如何用jQuery访问Web Component Shadow DOM中的子元素?
问题描述
我编写了一个简单的Web Component,用于从服务器加载组件模板文件,代码如下:
export default class EditorComponent extends HTMLElement { async connectedCallback() { let file = "http://blog/components/editor/editor.html"; let res = await fetch( file ); this.attachShadow( { mode: 'open' } ).innerHTML = await res.text(); } } customElements.define('editor-component', EditorComponent);
我需要通过jQuery访问该组件HTML文件中的子元素,尝试了以下代码但未成功:
async connectedCallback() { let file = "http://blog/components/editor/editor.html"; let res = await fetch( file ); this.attachShadow( { mode: 'open' } ).innerHTML = await res.text(); $(this).find('div').hide(); // 我尝试的操作,没有效果 }
我还添加了超时处理,但同样没有效果。请问是否可以实现这一需求?
解决方案
当然可以实现!问题的核心在于:jQuery默认只会在主DOM树中查找元素,而你的模板内容被挂载到了独立的Shadow DOM子树中,普通的$(this).find()无法穿透Shadow DOM的边界。
因为你已经将Shadow DOM的mode设置为open,所以可以直接访问到Shadow Root,再基于它用jQuery操作内部元素,这里有两种常用方式:
方式1:直接以Shadow Root为目标创建jQuery对象
通过this.shadowRoot获取Shadow DOM的根节点,再调用find()查找内部元素:
async connectedCallback() { let file = "http://blog/components/editor/editor.html"; let res = await fetch( file ); this.attachShadow( { mode: 'open' } ).innerHTML = await res.text(); // 指向Shadow Root后查找div并隐藏 $(this.shadowRoot).find('div').hide(); }
方式2:使用jQuery的上下文参数
在jQuery选择器中传入Shadow Root作为查找上下文,这样jQuery就会在指定的Shadow DOM内搜索元素:
async connectedCallback() { let file = "http://blog/components/editor/editor.html"; let res = await fetch( file ); this.attachShadow( { mode: 'open' } ).innerHTML = await res.text(); // 第二个参数指定查找上下文为Shadow Root $('div', this.shadowRoot).hide(); }
关于超时处理的说明
其实你完全不需要添加超时,因为await res.text()之后已经同步完成了HTML内容的插入,此时Shadow DOM内的元素已经存在。之前超时无效的原因,本质还是没有正确指向Shadow DOM的上下文,哪怕等待再久,jQuery依然只会在主DOM树中查找元素,自然找不到目标div。
内容的提问来源于stack exchange,提问作者Musaffar Patel
相关产品推荐
相关产品推荐

