为什么this.evaluate不正确地返回DOM节点?

我试图通过evaluate()方法从网页中获取对象,所以我可以在evaluate范围之外使用它。 用名称symbolselect的元素是一个带有<options> (=下拉菜单)的<select>标签。

 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 

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

这是有道理的,因为在最后一个片段中的elmnt.options是一个数组完整的undefined值。 所以你知道元素的数量,但不知道它们的价值。 原因是DOM节点不能从页面上下文传递。 文档说:

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

闭包,函数,DOM节点等不起作用!

因此,无论是在页面上下文( evaluate )中执行所有操作,还是获得了要使用的DOM节点的表示forms。 我认为这不是你想要的。

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