如何基于坐标单击元素以及如何使用 CasperJS 检索元素属性?

How to click on an element based on coordinates and how to retrieve element properties with CasperJS?

我想使用 CasperJS 获取对象的属性,例如我有这样的东西:

var casper = require('casper').create();
casper.start('http://www.seznam.cz', function() {
    if (this.exists('div#info')) {
        require('utils').dump(this.getElementInfo('div#info'));
    } 
    else {
        this.echo(' not found', 'ERROR');
    }
});
casper.run(); 

我可以在控制台中看到许多属性,例如元素的位置。现在鉴于此,是否有可能以某种方式获取这些坐标并执行例如 this.click(coordinates)?如果是,怎么办?

我也想知道如何获取其他属性,例如 parentNodechildNodes

I can see in console many attributes for example position of the element. Now given this, is it somehow possible to get these coordinates and perform for example this.click(coordinates)? If it is, how?

casper.getElementInfo(selector)这样的函数提供给定选择器匹配的第一个元素的坐标和尺寸。如果 CasperJS 不能使用这些,那就太奇怪了。

CasperJS 有多个模块用于不同的任务。其中之一是 mouse module. This module provide a click() 函数,它采用选择器或坐标来单击某处。

casper.then(function(){
    var info = this.getElementInfo('div#info');
    this.mouse.click(info.x+1, info.y+1);
});

+1 是必需的,以便实际单击元素而不是其边框。

I also would like to know hot to get another properties, like parentNode, childNodes.

这要困难得多。 CasperJS(和 PhantomJS)有两个上下文。外部上下文是您脚本中的代码,但不完全是。 casper.evaluate() 是 window 进入沙盒页面上下文。

传入casper.evaluate()的函数无法访问外部定义的变量。必须显式传递值。它们将在整个过程中被序列化为 JSON。所以当你想将 DOM 节点传递到页面上下文之外时,它们将失去意义,因为它们不是 JSON 可序列化的。

另一方面,您可以做的是永远不要传递在外部调用 parentNodechildNodes 时获得的 DOM 节点。仅在页面上下文中完全使用它们。例如,将它们存储在全局 window 对象中供以后使用,然后稍后在您的脚本中使用另一个 casper.evaluate() 来访问它们。

如果您实际上不需要实际节点,您可以检索这些节点的表示。 textContent 是一个很好的候选者:

var childContentsArray = casper.evaluate(function(){
    return [].map.call(document.querySelector("#someId").childNodes, function(child){
        return child.textContent;
    });
});