Polymer — innerHTML — можно ли применять стили родительского элемента?

Как вы, наверное, знаете, Polymer запрещает привязку unescapedHTML по многим разумным причинам.

Как внедрить HTML в шаблон с помощью полимера< /а>

Как отобразить html внутри шаблона?

Однако в моем проекте требовалось применять HTML из внешнего источника.

Поэтому я реализовал компонент с именем ‹echo-html›:

<dom-module id="echo-html">
    <template>
        <style>
        </style>
    </template>
</dom-module>

<script>
(function() {
    Polymer({
        is: 'echo-html',
        properties: {
            html: {
                type: Object,
                value: '',
                observer: '_refreshHtml'
            },
        },

        _refreshHtml: function() {
            if (this.html) {
                var value = '';
                var container = Polymer.dom(this).parentNode;

                if ((this.html.constructor == Array) && (this.html.length == 1)) {
                    value = this.html[0];
                } else  {
                    value = this.html;
                }
                if (this.parentNode) {
                    this.outerHTML = value;
                }

                this.scopeSubtree(container, true);
                $(this).removeClass('echo-html');
            }
        },
    });
})();
</script>

Моя проблема заключается в том, что этот компонент связывает именно чистый HTML, поэтому, когда я хочу использовать ‹p› или ‹strong› или любой другой элемент, я не могу просто использовать стиль родительского компонента и поэтому должен использовать глобальные стили.

Есть ли способ применить стили родительского элемента, например:

<parent-element>
    <echo-html html$="{{some-nasty-html}}"></echo-html>
</parent-element>

"some-nasty-html" будет включать в себя класс .parent-element?

Можно ли как-нибудь удалить класс .echo-html? Собственно, это мой вопрос :)


person Chris Parjaszewski    schedule 14.11.2016    source источник


Ответы (2)


Используйте Polymer.dom() API, чтобы сообщить библиотеке полимеров ваши области в Shady DOM, манипулирование узлом или элементом не приведет к срабатыванию области видимости стиля:

Polymer.dom(this).innerHTML = '<p>My Paragraph!</p>';

С Shadow DOM это должно работать без конвейера через библиотеку.

person adaliszk    schedule 15.11.2016
comment
Вы уверены, что innerHTML применит стили ко всем унаследованным элементам? - person Chris Parjaszewski; 15.11.2016
comment
это должно быть, если вы обертываете его через DOM API, appendChild действительно работает в моих элементах таким образом, обратите внимание, что если вы загружаете другой элемент, то правильный способ сделать это - importHref, а затем createElement - person adaliszk; 16.11.2016

Кажется, у меня получилось. Я использовал Polymer.dom и jQuery для доступа как к Shadow DOM, так и к normal DOM.

Вот реализация, которую я сделал через 3-5 часов после добавления этого вопроса - надеюсь, вы сможете ее использовать и, возможно, просмотреть:

<dom-module id="echo-html">
    <template>
        <style>
        </style>
    </template>
</dom-module>

<script>
(function() {
    Polymer({
        is: 'echo-html',
        properties: {
            html: {
                type: Object,
                value: '',
                observer: '_refreshHtml'
            },
        },

        _refreshHtml: function() {
            if (this.html) {
                var value = '';
                var container = Polymer.dom(this).parentNode;
                var classList = Array.from($(container)[0].classList).filter(function(el) {
                    return ((el != 'echo-html') && (el != 'style-scope'));
                });
                var lastClass = classList[classList.length - 1];

                if ((this.html.constructor == Array) && (this.html.length == 1)) {
                    value = this.html[0];
                } else  {
                    value = this.html;
                }
                if (this.parentNode) {
                    this.outerHTML = value;
                }
                this.scopeSubtree(container, true);

                // First step - change the Shadom DOM
                Polymer.dom(container).classList.remove('echo-html');
                if (Polymer.dom(container).classList.contains(lastClass)==false) {
                    Polymer.dom(container).classList.add(lastClass);
                }

                // Second step - change the DOM
                $(container).find('*').removeClass('echo-html').addClass(lastClass);
            }
        },
    });
})();
</script>

Спасибо за все что ты сделал для меня!

Вот ссылка на репозиторий, если у вас есть комментарии по поводу проблем: https://github.com/krzysztofp/echo-html-polymer

person Chris Parjaszewski    schedule 15.11.2016