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

IT技术 javascript phantomjs casperjs
2021-02-26 10:11:14

我正在尝试通过该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个回答

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

注意: 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};
    });
});