js操作shadow-root内的DOM元素

一、背景

项目中在DOM结构里遇到了shadow-root(open),用JS方法无法直接获取其内的DOM元素

二、shadow DOM

Web components 的一个重要属性是封装——可以将标记结构、样式和行为隐藏起来,并与页面上的其他代码相隔离,保证不同的部分不会混在一起,可使代码更加干净、整洁。其中,Shadow DOM 接口是关键所在,它可以将一个隐藏的、独立的 DOM 附加到一个元素上。shadow-root包裹下的对象,不在全局的DOM树中,因此getElementById 等方法,获取不到包裹中的对象。

  • Shadow DOM 这款工具旨在构建基于组件的应用。因此,可为网络开发中的常见问题提供解决方案:
  • 隔离 DOM:组件的 DOM 是独立的(例如,document.querySelector() 不会返回组件 shadow DOM 中的节点)。
  • 作用域 CSS:shadow DOM 内部定义的 CSS 在其作用域内。样式规则不会泄漏,页面样式也不会渗入。
  • 组合:为组件设计一个声明性、基于标记的 API。
  • 简化 CSS - 作用域 DOM 意味着您可以使用简单的 CSS 选择器,更通用的 id/类名称,而无需担心命名冲突。
  • 效率 - 将应用看成是多个 DOM 块,而不是一个大的(全局性)页面。

Shadow DOM 与普通 DOM 相同,但有两点区别:

  • 创建/使用的方式;
  • 与页面其他部分有关的行为方式。

通常,您创建 DOM 节点并将其附加至其他元素作为子项。 借助于 shadow DOM,您可以创建作用域 DOM 树,该 DOM 树附加至该元素上,但与其自身真正的子项分离开来。这一作用域子树称为影子树。被附着的元素称为影子宿主。

简单的意思就是可以用来独立建立一块渲染块,不受外层样式的影响,内层的样式也不影响外层的显示。

三、操作shadow-root内的元素

1.先获取shadow-root的父级节点,然后用shadowRoot取得这个父级节点的shadow块,然后就可以进行操作了

document.querySelector('#root').shadowRoot.querySelector('.chakra-portal')

2.在shadow块下面创建style标签,在里面添加样式

    let gtx = document.querySelector("#root");
    let style = document.createElement("style");
    style.innerHTML =
      ".grid_wrap { display: flex;justify-content: center;align-items: center;}";
    gtx.shadowRoot.appendChild(style);

 相关资料:使用 shadow DOM - Web Components | MDN

                   深入理解Shadow DOM v1 - 掘金         

在Python中,特别是在Web自动化测试或使用Selenium库时,定位Shadow DOM(阴影根)下的元素可能会有些复杂,因为Shadow DOM是一种CSS隔离技术,用于封装HTML元素和其样式。要在Shadow DOM中定位元素,你需要采取以下几个步骤: 1. 导入所需库:首先确保已经安装了selenium、webdriver_manager以及可能需要的如pyside2等UI自动化工具。 ```python from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC ``` 2. 设置浏览器和driver:创建一个支持Shadow DOM功能的WebDriver实例,例如Firefox with FirefoxDriver or Chrome with ChromeDriver。 3. 使用显式等待(`WebDriverWait`):由于Shadow DOM中的元素默认不可见,需要等待元素变为可用状态。这通常通过`element_to_be_clickable()`等预期条件函数完成。 ```python wait = WebDriverWait(driver, timeout=10) element = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '[some-shadow-selector]'))) ``` 4. 使用 ShadowRoot API:Selenium的`execute_script`方法可以让你直接操作浏览器的JavaScript环境。你可以使用这个方法找到Shadow DOM元素。 ```python # 获取元素所在的ShadowRoot shadow_root = driver.execute_script("return arguments[0].shadowRoot;", element) # 现在可以在shadow_root里查找元素 shadow_element = shadow_root.find_element(by=By.TAG_NAME, value='desired-element') ``` 5. 完成操作:现在你可以像平常一样对`shadow_element`进行操作,比如点击、输入文本等。 请注意,Shadow DOM的结构可能因网页的具体实现而变化,因此在编写代码时,需要准确匹配选择器或使用更具体的属性来定位元素
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值