Javascript 使用CasperJS从querySelectorAll遍历节点列表

Javascript 使用CasperJS从querySelectorAll遍历节点列表,javascript,phantomjs,casperjs,selectors-api,Javascript,Phantomjs,Casperjs,Selectors Api,我想遍历来自querySelectorAll的节点列表 不工作 var nodelist = this.evaluate(function() { return document.querySelectorAll('tr.firstrow'); }); this.echo("nodelist.length=" + nodelist.length); for (var i=0; i<nodelist.length; i++) { this.echo("i=" + i);

我想遍历来自querySelectorAll的节点列表

不工作

var nodelist = this.evaluate(function() {
    return document.querySelectorAll('tr.firstrow');
});

this.echo("nodelist.length=" + nodelist.length);

for (var i=0; i<nodelist.length; i++) {
    this.echo("i=" + i);
    line = nodelist[i];
    this.echo("Line: " + line.innerText);
}
var nodelist=this.evaluate(function() 
{
console.log("...evaluate()");
var fr_n=document.querySelectorAll('tr.firstrow');
console.log("fr_n.length:" + fr_n.length);

var fr_a=Array.prototype.slice.call(fr_n);

console.log("fr_a.length:" + fr_a.length);
console.log("typeof fr_a:" + typeof fr_a);
console.log("fr_a[0]=" + fr_a[0].innerText);
console.log("fr_a[1]=" + fr_a[1].innerText);
console.log("fr_a[2]=" + fr_a[2].innerText);

return fr_a;

});

this.echo("nodelist.length=" + nodelist.length);

if (Array.isArray(nodelist))
{
 this.echo ("nodelist is array");
}
else
{
 this.echo ("nodelist is not array");
}

for (var i=0; i<nodelist.length; i++)
{
 this.echo("i:" + i);
 line = nodelist[i];
 this.echo("Line: " + line); 
};
在i=1之后,输出冻结。对于第一个项目,“For”循环按预期运行,但随后不会继续。在浏览器控制台中运行querySelectorAll时,我会看到所有三个不同的项

在这里,我发现了一种有效的方法:

有效

var nodelist = this.evaluate(function() {
    var nodes = document.querySelectorAll('tr.firstrow');
    var array = [nodes[0].innerText,nodes[1].innerText,nodes[2].innerText];
    return array;
});
this.echo("nodelist.length=" + nodelist.length);
for (var i=0; i<nodelist.length; i++) {
    this.echo("i=" + i);
    line = nodelist[i];
    this.echo("Line: " + line);
}

我希望nodelist.length应该是3而不是0。

尝试将
节点列表
(由
querySelectorAll
返回)转换为
数组

var nodelist=this.evaluate(function() {
    return Array.prototype.slice.call(document.querySelectorAll('tr.firstrow'));
});
PhantomJS的函数是沙盒页面上下文。传递的所有内容都必须重新进行字符串化和解析

注意:evaluate函数的参数和返回值必须是简单的原语对象。经验法则:如果可以通过JSON对其进行序列化,那么就可以了

闭包、函数、DOM节点等将无法工作

这意味着您无法从页面上下文中获取元素,但可以在页面上下文中构建元素的表示并将其传递给外部

您可能需要这些元素的
textContent
。您可以使用CasperJS函数,该函数为每个元素提供
text
属性。然后,您可以仅筛选此属性的信息:

var texts = casper.getElementsInfo('tr.firstrow').map(function(tr){
    return tr.text;
});

如果不是您要查找的文本,则必须在页面上下文中(在
casper.evaluate()
内)查找另一个表示或遍历节点列表。

抱歉,键入错误。我的意思是
line=nodelist[I]
var nodelist=this.evaluate(function() {
    return Array.prototype.slice.call(document.querySelectorAll('tr.firstrow'));
});
var texts = casper.getElementsInfo('tr.firstrow').map(function(tr){
    return tr.text;
});