为什么this.evaluate不正确地返回DOM节点?
我试图通过evaluate()
方法从网页中获取对象,所以我可以在evaluate
范围之外使用它。 用名称symbol
select的元素是一个带有<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}; }); });