这个问题更多的是针对用户创建的影子DOM元素,但是对于可访问性,我将使用date
输入类型来解决这个问题:
比如说我的页面上有date
输入。在编辑了几个位之后,这个(使用Chrome)的阴影DOM标记看起来像:
<input type="date">
#document-fragment
<div pseudo="-webkit-datetime-edit">
<div pseudo="-webkit-datetime-edit-fields-wrapper">
<span role="spinbutton">dd</span>
<div pseudo="-webkit-datetime-edit-text">/</div>
<span role="spinbutton">mm</span>
<div pseudo="-webkit-datetime-edit-text">/</div>
<span role="spinbutton">yyyy</span>
</div>
</div>
<div></div>
<div pseudo="-webkit-calendar-picker-indicator"></div>
与date
输入相关联的方法和属性似乎根本没有引用阴影DOM(JSFiddle),所以我想知道这些阴影DOM元素是如何(如果有的话)访问?
答案 0 :(得分:18)
int32_t
是正确的,根据定义,Shadow DOM是一种用DOM来填充要隐藏的外部源(Encapsulation)的节点。关键是你作为组件的作者可以准确选择哪些部分将暴露给外部的CSS或JavaScript,哪些不会。
不幸的是,如果不使用另一个名为Custom Elements的前沿规范,则无法为Shadow DOM创建公共JavaScript界面。如果您选择这样做,就像向元素的原型添加自定义公共方法一样简单。从这些中你可以访问Shadow DOM的内部(参见第三个例子here)。
但是,您可以使用CSS的钩子来访问Shadow DOM的内部,而无需使用自定义元素。有两种方法可以做到这一点: Chrome和Firefox通过特殊的伪元素将其Shadow DOM的某些部分暴露给CSS。 Here's您date
输入的示例,其中添加了一条CSS规则,该规则仅适用于日期字段的数字部分,方法是使用Chrome提供的-webkit-datetime-edit
伪元素。 / p>
Here's可用的WebKit伪元素的部分列表。您也可以在DevTools中启用Show Shadow DOM
选项,并查找名为pseudo
的属性。
组件作者也可以创建自己的伪元素来公开他们的Shadow DOM部分(参见第二个例子here)。
更好的方法是使用CSS变量,您可以在Chrome中的Enable experimental WebKit features
中使用about:flags
启用它。然后查看使用CSS变量的this fiddle与Shadow DOM进行通信,了解它应该用于“主题”的颜色。
答案 1 :(得分:15)
现在(2016)您可以使用Shadow DOM根目录上的方法querySelector
访问开放的用户创建的影子DOM元素(但没有用户代理创建的影子DOM!): / p>
<body>
<div id="container"></div>
<script>
//Shadow Root
var root = container.createShadowRoot()
//new syntax:
var root = container.attachShadow( { mode: "open" } )
//Inside element
var span = document.createElement( "span" )
span.textContent = "i'm inside the Shadow DOM"
span.id = "inside"
root.appendChild( span )
//Access inside element
console.log( container.shadowRoot.querySelector( "#inside" ) )
</script>
</body>
//Shadow Root
var root = container.createShadowRoot()
//Inside element
var span = document.createElement( "span" )
span.textContent = "i'm inside the Shadow DOM"
span.id = "inside"
root.appendChild( span )
//Access inside element
function get()
{
alert( container.shadowRoot.querySelector( "#inside" ).id )
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<div id="container"></div>
<button onclick="get()">Get</button>
<script>
</script>
</body>
</html>
答案 2 :(得分:4)
您无法从Shadow DOM之外的脚本访问Shadow DOM的内容。封装是Shadow DOM的目的。
答案 3 :(得分:1)
是的。您只需要调用.root或.shadowRoot即可。这是一个例子,
document.getElementById('itemId').root
如果父dom元素上没有innerText或innerHTML,您将不会获得shadow dom元素。