【问题标题】:How to click on an element based on coordinates and how to retrieve element properties with CasperJS?如何根据坐标单击元素以及如何使用 CasperJS 检索元素属性?
【发布时间】:2015-04-17 18:55:42
【问题描述】:

我想使用 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

【问题讨论】:

    标签: javascript dom click casperjs


    【解决方案1】:

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

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

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

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

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

    我也想知道热门获得其他属性,如parentNodechildNodes

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

    传递给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;
        });
    });
    

    【讨论】:

    • 好吧,我知道我正在研究 Page 和 Casperjs 上下文之间的区别,只有一个问题是获取孩子的类名属性的某种方式吗?我确实尝试返回 child.className,但这不起作用。
    • element.childrenelement.childNodes 之间存在差异。 childNodes 还将包括没有 className 的 TextNode。除此之外,它应该可以工作。
    • 你提到我可以在另一个评估中使用对象来访问它们,我有一些链接:var search = 'div'; var 属性 = 'id'; var divs = casper.evaluate(function(search){ return elements = utils.findAll(search); }, search); var divIDS2 = casper.evaluate(function(divs, atribute){ divs.map(function(e) { return e.getAttribute(atribute); }); }, divs, 属性);我确实知道如何在一个函数评估中获取所有 div 的 id,但我不知道如何在两个评估函数中获取它。
    • 正如我所说,您不能将 DOM 节点传递到页面上下文之外。所以不要在第一个casper.evaluate() 中返回它们,而是将它们设置为windowcasper.evaluate(function(search){ window.myelements = __utils__.findAll(search); }, search);。然后,您可以稍后在第二个 casper.evaluate() 呼叫中访问 window.myelements。问题是,你为什么要这样做?在这种情况下,将其拆分为多个 evaluate() 调用不会有任何收获。
    • 我知道功能是相同的,但我正在尝试实现一种算法,它比较元素的许多属性并将它们存储在某个变量中,这比一个评估函数中的许多 if 更具可读性。
    猜你喜欢
    • 2020-09-20
    • 1970-01-01
    • 2020-09-05
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多