开发者问题收集

聚合体就绪事件后 querySelector 未找到元素

2015-02-04
1710

我有一个自定义元素(我们称之为“el-barto”)。它位于另一个模板的模板内。

现在。我可以使用 querySelector document.querySelector('el-barto') 来选择它,使用 chrome dev tools 控制台没有任何问题。

但是,如果从 js 文件执行相同的查询,则不会返回任何内容。

$(document).ready(function() { document.querySelector('el-barto'); });

人们说:为 polymer-ready 添加事件监听器,所以我这样做了:

...
document.addEventListener('polymer-ready', function() {
    console.log('yey, poly is ready!');
    console.log(document.querySelector('el-barto'));
});
...

并且打印:

yey, poly is ready!
null

因此,我继续设置超时,就像这样:

...
document.addEventListener('polymer-ready', function() {
    console.log('yey, poly is ready!');
    setTimeout(function(){
        console.log(document.querySelector('el-barto'));
    },100);
});
...

你知道什么?

yey, poly is ready!
<el-barto>...</el-barto>

(我注意到,少于 100 毫秒的超时对于查询选择器返回 null)。

现在,我不会到处设置超时了,对。

我在这里做错了什么吗?

甚至更多。

如果我使用类似这样的查询选择器:

document.querySelector('#main').content.querySelector('#sub-main').content.querySelector('#sub-sub-main').content.querySelector('el-barto')

它将工作而无需设置超时。但问题是为什么 100 毫秒后我可以在没有这个长查询的情况下找到“el-barto”?我的目标是在不使用那些长查询选择器的情况下找到这样的元素。

1个回答

当所有内容实际上都在 DOM 中时, 'polymer-ready' 事件不会触发。它仅确认页面加载时存在的所有元素都已导入并升级。此外,仅仅因为元素已升级并不意味着 DOM 已被完全操纵(尽管如果您没有执行太多复杂操作,通常情况如此)。如果您的自定义元素根据属性动态添加到 DOM,则尤其如此。

对于任何操纵 DOM 的库或框架来说,过早查询 DOM 始终是一种危险。如果库具有复杂的初始化过程,则尤其如此。如果您的其他脚本和/或元素需要 <el-barto> 存在,请考虑在 <el-barto>domReady 函数中触发事件。这将通过祖先元素将 DOM 向上冒泡,让您 知道 <el-barto> 已升级并存在(及其直属子元素)。

无论您选择哪个祖先元素,您都可以使用 addEventListener 简单地监听您的事件,然后添加查询,或者更好的是,从事件对象中获取 <el-barto>

Polymer('el-barto', {
    ... other el-barto code ...
    domReady: function() {
        this.fire('el-barto-ready');
    }
    ... other el-barto code ...
});

其他任何地方...

[ancestor].addEventListener('el-barto-ready', function() {
    console.log(document.querySelector('el-barto');
});
Fuzzical Logic
2015-02-04