How can I access DOM elements in Polymer elements from a global namespace?

半城伤御伤魂 提交于 2020-01-15 11:13:28

问题


I want to access a DOM element that's in my-app-as-an-element.html from my app.dart global (because it's a method I want to call from several places, e.g. it changes the page title), but as it's wrapped in shadows and all, I can't seem to get at it. There's a trick to do e.g.

HtmlElement el;
el = document.querySelector('body /deep/ #page-title');

But /deep/ isn't respected in Safari, so that's off the table. Ideas?


回答1:


What you are trying to do goes directly against the philosophy of Polymer: the point of all the encapsulation, using Shadow DOM etc. is to have reusable components that manage their own state, DOM included.

If the element that ones that owns that DOM element you are trying to access is a custom element (i.e. you or someone at your company has written it), the best solution would be exposing the functionality you need as a public method on that element.

Say for example, your element has a <h1> and you want to change its content. You could achieve this as follows:

Polymer("my-custom-element", {
    changeTitle: function(newTitle) {
        // this operates on the element's Shadow DOM *only*,
        // NOT the entire page
        document.querySelector('h1').htmlContent = newTitle;
    }
})

You can then make this call from your global code:

document.querySelector("my-custom-element").changeTitle("My New Title");

If the element your are trying to change is owned by a public element (e.g. from core-elements or paper-elements), or anything you've downloaded from some repository, read the documentation and see if it exposes the functionality you need somehow. If not, you could try writing your own custom element that extends that element. In your extended element, you can insert the extendee's Shadow DOM using the <shadow></shadow> tag, and manipulate it via your element's JavaScript in the same way as described above.

EDIT: Actually, there IS a way to do what you want directly, although I would only recommend this as a last resort. If you read Shadow DOM 201, you'll notice that you can access an element's Shadow DOM via the .shadowRoot property. This gives you another Document object, on which you can use .querySelector again, like so:

document.querySelector('my-custom-element').shadowRoot.querySelector('h1');

Or even

document.querySelector('my-custom-element::shadow h1');

This gives you a handle on the element, which you can then modify as necessary. But again, I don't recommend using this unless you need quick access to this element for debugging purposes.




回答2:


Polyfill for /deep/ in querySelector is work in progress and will be available soon on browsers without native Shadow DOM support.



来源:https://stackoverflow.com/questions/25478000/how-can-i-access-dom-elements-in-polymer-elements-from-a-global-namespace

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!