【问题标题】:How can I interact with browser-inserted Shadow DOM content in an input field?如何在输入字段中与浏览器插入的 Shadow DOM 内容进行交互?
【发布时间】:2021-09-22 20:16:28
【问题描述】:

目前我正在尝试设置一个功能,该功能将点击 <input type=time> 内的小时钟,但无法找到标签的 innerHTML 以找到时钟。

这就是我想做的:

html

<input id='timeInput' type='time'/>

JS

document.getElementById("timeInput").children('clockIcon').click()

但是当我运行 document.getElementById('timeInput').innerHTML 时,我得到了 null。

我认为这与Shadow DOM有关,但一直无法找到有关shadow DOM输入的信息。

我以前能够检查隐藏的浏览器 HTML,但无法找到以前的资源。有什么想法吗?

具体来说,我的应用程序仅在 Chrome 和 Opera 浏览器上显示,因为它是 Chrome 扩展程序。

【问题讨论】:

  • documentation 可以看到,并非所有浏览器的输入中都有这个时钟图标。如果有帮助,使用document.getElementById('timeInput').focus() 可以让用户进入&lt;input&gt;
  • 如果你使用一个输入,我建议你添加一个名称标签,它使querySelector 更容易定位,就像在document.querySelector('input[name="inputname"]').click 中选择时钟本身很棘手,你的innerhtml 会不起作用,因为输入标签本身没有任何内容。我更愿意为其添加一个真正的时钟图标,而不是让浏览器解决您的问题,因为每个浏览器处理输入类型 time 不同
  • 附带说明:并非所有浏览器都支持&lt;input type="time"&gt;。因此,为了使其更容易和跨浏览器,我建议(就像@Dorvalla 一样)创建@987654337 的自定义组合@ 或 &lt;select&gt; 具有自定义交互,使其在所有浏览器上都相同,并且能够更精确地控制交互。
  • document.getElementById('timeInput').shadowRoot 会返回任何东西吗?如果没有,那么你需要打开 shadow DOM。 developer.mozilla.org/en-US/docs/Web/Web_Components/…

标签: javascript html chromium shadow-dom


【解决方案1】:

无法与影子 DOM 交互。影子树的全部目的是将功能、行为和样式与外界隔离——即使模式是“开放的”。如果特定组件的作者希望您能够控制行为或样式,他们将为此提供 API。如果作者没有为它提供 API,他们不希望你乱用它。

在使用表单字段时,我的经验法则是始终遵循以下规则之一:

  1. 使用浏览器表单域 - 不要太花哨,因为您可能会破坏可访问性、键盘导航、自动填充和其他您不打算破坏的东西。除了设置边框、背景和内边距之外的任何东西通常都不是一个好主意。您可能认为是这样,但我可能会通过展示您如何破坏某些默认行为来证明您错了。

例如,自动显示时间选择器会使注意力从用户正在做的事情上转移开。也许屏幕阅读器正在阅读一些文本,或者高级用户正在使用他们的键盘在导航中切换,然后突然之间他们在他们不想出现的时间选择器上。

  1. 使用经过广泛测试的 UI 库。流行的 UI 库的作者已经考虑了所有的行为等,以便为用户提供流畅和可预测的体验。当您想要执行诸如自动显示日期/时间选择器或其他一些您可能不应该做但无论如何都会去做的花哨行为时,请使用这些。

无论您做什么,都不要尝试滚动您自己的花哨的表单控件。我保证你会惹恼你的一位用户。

【讨论】:

    【解决方案2】:

    如果你想在 Chrome DevTools 中查看 shadowDom,你必须在 Elements 部分的 Settings 中打开它。除了通过元素属性和事件处理程序之外,您无法以编程方式与元素交互。

    这应该使 shadowroot 可见

    您可以向组件本身添加更改和输入以及事件侦听器,但不能向 shadowDom 的元素添加。

    【讨论】:

      【解决方案3】:

      有一种方法可以用纯 js 与开放的 shadow dom 进行交互,比如点击

      例子:

      document.querySelector("shadowRootsCss").shadowRoot.querySelector("#timeInput").click()

      如果您使用谷歌浏览器,检查并找到该元素,在该元素上,单击:复制 js 路径

      然后你就会有你需要点击的路径

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-20
        • 2019-10-16
        • 2015-01-16
        • 2013-12-25
        • 2016-09-21
        • 2021-11-11
        相关资源
        最近更新 更多