【问题标题】:Why doesn't this.evaluate return DOM nodes correctly?为什么 this.evaluate 不能正确返回 DOM 节点?
【发布时间】:2014-10-14 05:45:58
【问题描述】:

我正在尝试通过evaluate() 方法从网页中获取一个对象,以便我可以在evaluate 的范围之外使用它。选择名称为 symbol 的元素是带有 148 <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

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

【问题讨论】:

  • 如果你想直接在你的代码中访问 DOM,你可能想看看zombie.js,它是一个 DOM/浏览器模拟器,而不是真正的浏览器(webkit)的包装器跨度>

标签: javascript phantomjs casperjs


【解决方案1】:

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

注意:评估函数的参数和返回值必须是简单的原始对象。经验法则:如果可以通过 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};
    });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    • 2019-06-07
    • 1970-01-01
    • 2018-12-22
    • 2016-11-05
    • 1970-01-01
    相关资源
    最近更新 更多