Можно ли получить доступ к элементам Shadow DOM через родительский документ?
Этот вопрос больше нацелен на созданные пользователем теневые элементы DOM, но для доступности я буду использовать date
тип ввода для этого вопроса:
Скажем, например, у меня есть date
вход на моей странице. Отредактированная пара битов, теневая разметка DOM для этого (с использованием Chrome) выглядит примерно так:
<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?
3 ответа
int32_t
Право в том, что Shadow DOM, по определению, является способом заполнения узла DOM, который вы хотите скрыть от внешних источников ( инкапсуляция). Дело в том, что вы, как автор компонента, можете точно выбрать, какие части будут видны вне CSS или JavaScript, а какие нет.
К сожалению, вы не можете создать общедоступный интерфейс JavaScript для своей Shadow DOM без использования другой передовой спецификации под названием Custom Elements. Если вы решите это сделать, это так же просто, как добавить пользовательские публичные методы в прототип вашего элемента. Из них вы можете получить доступ к внутренностям вашего Shadow DOM (см. Третий пример здесь).
Тем не менее, вы можете выставить хуки для CSS для доступа к внутренностям вашего Shadow DOM без использования пользовательских элементов. Есть два способа сделать это:
- Псевдо-элементы
- Переменные CSS
Псевдо-элементы
Chrome и Firefox предоставляют определенные части Shadow DOM CSS для специальных псевдоэлементов. Вот ваш пример date
ввод с добавлением правила CSS, которое применяется только к числовой части поля даты посредством использования Chrome -webkit-datetime-edit
Псевдо-элемент.
Вот неполный список доступных псевдоэлементов WebKit. Вы также можете просто включить Show Shadow DOM
опция в DevTools и искать атрибуты с именем pseudo
,
Авторы компонентов также могут создавать свои собственные псевдоэлементы для демонстрации частей своего Shadow DOM (см. 2-й пример здесь).
Переменные CSS
Еще лучше использовать CSS-переменные, которые вы можете включить с помощью Enable experimental WebKit features
в about:flags
в хроме. Затем проверьте эту скрипку, которая использует CSS-переменные, чтобы сообщить Shadow DOM, какой цвет он должен использовать для своей "темы".
Теперь (2016) вы можете получить доступ к открытым созданным пользователем теневым DOM-элементам (но не к созданным пользовательским агентом теневым DOM!), Используя метод querySelector
в корне Shadow DOM:
<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>
Да. Вы просто должны позвонить.root или.shadowRoot . Вот пример,
document.getElementById('itemId').root
Вы не получите элемент shadow dom без innerText или innerHTML в родительском элементе dom.
Вы не можете получить доступ к содержимому Shadow DOM из сценариев вне Shadow DOM. Инкапсуляция является целью Shadow DOM.