为什么不评估正确返回DOM节点?

时间:2014-10-14 05:45:59

标签: javascript phantomjs casperjs

我正在尝试通过evaluate()方法从网页中获取对象,因此我可以在evaluate范围之外使用它。使用名称symbol选择的元素是<select>标记,其中包含148 <options>(=下拉菜单)。

casper.then(function () {
    var elmnt = this.evaluate(function () { return document.getElementsByName("symbol")[0]; });
    console.log(elmnt.options[14].index);
});

//Returns TypeError: 'null' is not an object (evaluating 'elmnt.options[14].index')

casper.then(function () {
    var elmnt = this.evaluate(function () { return document.getElementsByName("symbol")[0].options[14].index; });
    console.log(elmnt);
});

//Returns 14

所以看起来好像通过evaluate()方法返回一个对象不完整地返回它,因为这可以正常工作:

casper.then(function () {
    var elmnt = this.evaluate(function () { return document.getElementsByName("symbol")[0]; });
    console.log(elmnt.options.length);
});

//Returns 148

所以只要我不读取数组,我就可以访问选项属性。奇怪没有?

1 个答案:

答案 0 :(得分:3)

这是有道理的,因为最后一个代码段中的elmnt.options是一个包含undefined值的数组。所以你知道元素的数量,但不知道它们的值。原因是DOM节点无法从页面上下文传递。 docs说:

  

注意: evaluate函数的参数和返回值必须是一个简单的原始对象。经验法则:如果它可以通过JSON序列化,那就没关系了。

     

闭包,函数,DOM节点等将工作!

因此,您要么在页面上下文(evaluate)内部执行所有操作,要么获得要使用的DOM节点的表示。我认为这不是你想要的。

var elmnt = this.evaluate(function () {
    return [].map.call(document.getElementsByName("symbol")[0].options, function(option){
        return {text: option.innerText, value: option.value};
    });
});