我正在尝试通过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
所以只要我不读取数组,我就可以访问选项属性。奇怪没有?
答案 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};
});
});