Могу ли я получить доступ к теневой модели DOM с помощью jQuery?

Я определил компонент с полимером следующим образом:

<polymer-element name="my-component">
  <template>
    <div id='test'>CONTENT</div>
  </template>
</polymer-element>

Теперь я хочу получить доступ к теневому дому, например: чтобы получить содержимое div id='test'

var x = $("div#test").html();

Указанный код не работает. Могу ли я получить доступ к теневому дому с помощью jquery?


person mica    schedule 19.01.2014    source источник


Ответы (8)


Нет, не за пределами элемента Polymer.

После прочтения о Polymer, похоже, вы можете иметь доступ только к теневой DOM элементов Polymer в сценариях внутри элемента Polymer. В документации Polymer по автоматическому поиску узлов говорится:

Каждый узел в теневой DOM компонента, помеченный атрибутом id, автоматически упоминается в хеше this.$ компонента.

Это означает, что вы можете добавить тег <script> в качестве родственного тега <template>, где this.$.test будет нужным вам элементом.

<polymer-element name="my-component">
  <template>
    <div id='test'>CONTENT</div>
  </template>
  <script>
    Polymer('my-component', {
        logNameValue: function () {
            console.log('polymer element', this.$.test);
            console.log('jQuery wrapper of polymer element', $(this.$.test));
        }
    });
  </script>
</polymer-element>
person Henry Blyth    schedule 19.01.2014
comment
Хороший ответ для 0.5, но я не уверен, что это все еще так, как это делается в 1.0. - person The Onin; 06.09.2015
comment
Мой вопрос не имел отношения к полимеру, но я нашел этот ответ полезным. stackoverflow.com/a/58417950/897326 - person Neolisk; 26.07.2021

Вы можете использовать шаблон $('body /deep/ your-selector'), чтобы проникнуть сквозь теневой DOM и заставить Jquery работать внутри него.

обновление: пока мне удалось заставить это работать только на хроме для рабочего стола. Я полагаю, что другие браузеры не поддерживают комбинатор /deep/.

обновление 2: комбинатор /deep/ устарел и больше не должен использоваться. Его планируется удалить из Chrome.

person David Aroesti    schedule 29.07.2014
comment
@NickFlekerFelker Возможно, вам поможет эта ссылка. ;) - person David Aroesti; 08.08.2014
comment
/deep/ кажется устаревшим: chromestatus.com/features/6750456638341120 - person artemave; 23.01.2016
comment
Ты прав. Он устарел и больше не должен использоваться. - person David Aroesti; 24.02.2017


Я думаю, это работает для меня...

$('polymer-element::shadow #test')

Хотя проверял только на хроме

person Val    schedule 13.03.2015
comment
Это также устарело. stackoverflow.com/questions/35741722 / - person Ally; 12.06.2017

Я написал простой помощник на TypeScript для решения этой проблемы:

class DomUtils {

    public static getShadowElementById(id: string):any {

        try {
            // Try to get it by simple id in case of browser doesn't support shadow DOM
            var element = $("#" + id);

            if (element.length <= 0) {
                // Support Chrome browser
                element = $("body /deep/ #" + id);
            }

            return element;

        } catch (error) {
            console.log("Error: " + error + ", while trying to get shadow element with id: " + id);
            return null;
        }
    }
} 

Применение:

var element = DomUtils.getShadowElementById('mainContainer');

Протестировано на ПК Chrome, Internet Explorer, Firefox.

person Konrad G    schedule 14.04.2015

Используйте что-то вроде этого:

jQuery.fn.extend({
  shadowRoot: function() {
     return $(this.get(0).shadowRoot);
  },
});

и позвоните:

$("my-element").shadowRoot());
person Peter Karena    schedule 22.03.2020

Вы можете сделать это следующим образом:

$("#example", this.shadowRoot).DataTable();
person Adolfo Martin    schedule 29.05.2020

Это сработало для меня

$(element)[0].shadowRoot

person IMPLATRIX    schedule 19.01.2021