如何选择Shadow-Root元素?Polymer中Canvas元素获取报错求助
解决Polymer中Shadow DOM内Canvas元素的选择问题
嘿,我来帮你搞定这个Shadow DOM元素选择的坑!你遇到的报错和null返回问题,主要是两个原因:id写错了,还有Shadow DOM的封装特性导致全局方法无法访问内部元素,咱们一步步来解决:
首先修正最直接的错误:this.$的使用
你页面里的canvas id是chart,但你代码里写的是this.$.canvas——这肯定找不到啊!Polymer的this.$对象只会映射你元素模板里定义了id的元素,所以正确的写法应该是:
var ctx = this.$.chart.getContext('2d')
这一步先解决Cannot read property 'canvas' of undefined的报错,因为之前你访问的this.$.canvas根本不存在,自然是undefined。
为什么getElementById返回null?
Shadow DOM是具有封装性的,全局的document.getElementById()无法穿透Shadow Root访问内部的元素。想要访问Shadow DOM里的元素,必须通过元素自身的shadowRoot对象来查询。
几种可靠的Shadow DOM元素选择方式
除了上面修正后的this.$.chart,还有两个常用方法:
1. 使用Polymer的快捷方法this.$$(selector)
这是Polymer提供的语法糖,等价于this.shadowRoot.querySelector(selector),用起来更简洁:
var canvas = this.$$('#chart'); var ctx = canvas.getContext('2d');
2. 直接通过shadowRoot查询
如果你需要更复杂的CSS选择器(比如选某个类名的元素),可以直接操作shadowRoot:
var canvas = this.shadowRoot.querySelector('#chart'); var ctx = canvas.getContext('2d');
额外注意:元素生命周期时机
还要确保你调用_drawChart方法的时机是对的——不能在constructor里调用,因为此时Shadow Root还没构建完成。最好在Polymer的ready()或者attached()生命周期钩子中触发,比如:
ready() { super.ready(); // Shadow DOM已经初始化完成,这里可以安全调用绘图方法 this._drawChart(price, time); }
总结一下常见坑
- 别写错元素的
id,this.$是严格对应模板里的id的; - 不要用全局的
document方法访问Shadow DOM内部元素; - 确保在Shadow Root创建完成后再去查询元素(比如
ready之后)。
内容的提问来源于stack exchange,提问作者Suhayb
相关产品推荐
相关产品推荐

