【发布时间】:2017-10-03 21:52:22
【问题描述】:
我试图抓取的页面上有一堆 span 元素,它们的格式如下:
<div class="ca-evp1 te" style="color:#2952A3">
<span class="te-t">11am </span>
<span class="te-s">Antoine Diel</span>
</div>
所以,我决定使用 getElementsByClassName() 来选择它们,然后遍历这个 HTMLCollection,当我在开发者控制台中查看它时显示 32 个项目,但当我检查长度属性时它是 0。
var toType = function(obj) {
return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
var eventToClick = document.getElementsByClassName('te-s');
console.log(eventToClick); // shows 32 elements
console.log(toType(eventToClick)); //htmlcollection
console.log(eventToClick.length); // 0...huh?
我一定错过了 getElementsByClassName 或 HTMLCollections 在一般工作中的工作方式,但目前我似乎无法通过 docs 或 Google 弄清楚。
据我了解,如果我将所有这些 span 元素视为 console.log 语句的一部分,它们应该会影响 eventToClick HTMLCollection 并且我应该能够使用 for 循环对其进行迭代,但这不起作用!开发者控制台是否在这里执行某种巫术,而我并没有真正将这些元素作为 HTMLCollection 的一部分?
这是一个实时版本,因此您可以在自己的浏览器中复制:http://danielschroedermusic.com/apps/cal-test/cal.html
在控制台中为帮助解决此问题的人发布第二张 span 元素的图片。
可行的解决方案,但不是很好!
document.addEventListener('DOMContentLoaded', function(event) {
var intervalID = window.setInterval(myCallback, 50);
function myCallback() {
var eventToClick = document.getElementsByClassName('te-s');
if (eventToClick.length > 0) {
console.log(eventToClick);
for (var i = 0; i < eventToClick.length; i++) {
console.log(eventToClick[i]); // 32 elements!
}
clearInterval(intervalID);
}
}
});
正如 Harshal 在接受的答案中指出的那样,我无法抓取这些元素,因为我的脚本在它们加载到页面上之前正在执行。正在加载此日历数据的 Google 脚本非常复杂,并且使用调试器单步执行它们并没有产生一个我可以在逻辑上看到正在添加的元素的地方,所以我尝试使用间隔计时器来检查是否存在具有我正在寻找的类名的元素。
目前看来这可以解决问题,如果您有任何更优雅的解决方案,我愿意接受!还在研究这个...
【问题讨论】:
-
@melpomene 刚刚上传到现场,满意吗?
-
什么时候添加这些元素?
HTMLCollection是现场合集。这意味着从document添加/删除的任何元素都将反映在该集合中。因此,虽然日志显示长度为 0,但当您在控制台中展开 HTMLCollection 时,它已更新为包含添加到document的新元素 -
这看起来非常复杂。
-
@melpomene 我同意,这只是一个愚蠢的项目,看看我是否可以从 iCal 嵌入中提取日历信息,然后重新格式化,但我认为合适。看起来我应该能够让 HTMLCollection 执行我使用过的方法,但这就是让我难过的原因。