简体   繁体   English

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

[英]Why doesn't this.evaluate return DOM nodes correctly?

I'm trying to get an object from a web page through the evaluate() method so I can work with it outside the scope of evaluate . 我正在尝试通过evaluate()方法从网页获取对象,以便可以在evaluate范围之外使用它。 The element selected with name symbol is a <select> tag with 148 <options> (=dropdown menu). 用名称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

So it looks likes returning an object through the evaluate() method returns it incompletly since this works correctly : 因此,看起来就像通过evaluate()方法返回对象一样,由于此方法可以正常工作,因此无法完全返回该对象:

casper.then(function () {
    var elmnt = this.evaluate(function () { return document.getElementsByName("symbol")[0]; });
    console.log(elmnt.options.length);
});

//Returns 148

So I can access options attributes as long as I don't read the array. 因此,只要不读取数组,就可以访问选项属性。 Strange no ? 奇怪吗?

It makes sense, because elmnt.options in the last snippet is an array full with undefined values. 这很有意义,因为最后一个片段中的elmnt.options是一个充满undefined值的数组。 So you know the number of elements, but not their values. 因此,您知道元素的数量,但不知道它们的值。 The reason is that DOM nodes cannot be passed from page context. 原因是无法从页面上下文传递DOM节点。 The docs say: 文档说:

Note: The arguments and the return value to the evaluate function must be a simple primitive object. 注意:参数和评估函数的返回值必须是一个简单的原始对象。 The rule of thumb: if it can be serialized via JSON, then it is fine. 经验法则:如果可以通过JSON序列化,那就很好。

Closures, functions, DOM nodes, etc. will not work! 闭包功能,DOM节点等等都不行!

So either you do everything inside of the page context ( evaluate ) or you get a representation of the DOM nodes that you want to work with. 因此,您可以在页面上下文中evaluate所有操作( evaluate ),或者获得要使用的DOM节点的表示形式。 Which I think is not what you want. 我认为这不是您想要的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM