【问题标题】:Understanding the evaluate function in CasperJS理解 CasperJS 中的评估函数
【发布时间】:2014-06-14 03:08:01
【问题描述】:

我想了解在哪种情况下我应该或必须使用evaluate 函数。

我已阅读有关 CasperJS 的 evaluate 函数的 API 文档,但我不确定在哪种情况下我应该使用此函数。 DOM 上下文是什么意思?有人可以举个例子吗?

【问题讨论】:

    标签: phantomjs casperjs


    【解决方案1】:

    CasperJS 文档很好地描述了 casper.evaluate() 的作用。

    回顾一下:您传递了一个将在 DOM 上下文中执行的函数(您也可以将其称为页面上下文)。您可以将一些原语作为参数传递给该函数并返回一个原语。请记住,您传递给evaluate 的这个函数必须是自包含的。它不能使用在此函数之外定义的变量或函数。


    CasperJS 为日常任务提供了许多很好的函数,但是当您需要自定义函数来做某事时,您可能会遇到这种情况。 evaluate 基本上是可以做的

    1. 从页面中检索一些值以在您的脚本中根据它采取行动
    2. 以某种方式操作页面,而不是单击或填写表单
    3. 第 1 点和第 2 点的组合。

    示例

    您可能需要一个通用函数来从复选框中获取checked 属性。 CasperJS 目前只提供getElementAttribute 功能,在这种情况下将无法使用。

    function getChecked(cssSelector){
        return document.querySelector(cssSelector).checked;
    }
    
    if (casper.evaluate(getChecked, selector)){
        // do something
    } else {
        // do something else
    }
    

    在大多数情况下,这只是您想要使用的偏好。如果您在每个 li 元素上都有一个带有 data-uid 的用户列表,那么您至少有 2 种可能性来检索 uid。

    仅限 Casper:

    var uids = casper.getElementsAttribute('ul#user-list > li', 'data-uid');
    

    Casper 评估:

    var uids = casper.evaluate(function(){
        return Array.prototype.map.call(document.querySelectorAll('ul#user-list > li'), function(li){ return li["data-uid"]});
    });
    

    关于操纵一切皆有可能,但取决于你想做什么。假设您想截取网页的屏幕截图,但有些元素您不想在那里。或者您可以将自己的 CSS 添加到文档中。

    移除元素:

    function removeSelector(cssSelector){
        var elements = document.querySelectorAll(cssSelector);
        Array.prototype.forEach.call(elements, function(el){
            el.parent.removeChild(el);
        });
    }
    casper.evaluate(removeSelector, '.ad'); // if it would be that easy :)
    

    通过 CSS 改变网站外观:

    function applyCSS(yourCss){
        var style = document.createElement("style");
        style.innerHTML = yourCss;
        document.head.appendChild(style);
    }
    casper.evaluate(applyCSS, 'body { background-color: black; }'); // non-sense
    

    CasperJS 建立在 PhantomJS 之上,因此继承了它的一些怪癖。 page.evaluate() 的 PhantomJS 文档是这样说的:

    注意:evaluate 函数的参数和返回值必须是简单的原始对象。经验法则:如果可以通过 JSON 序列化就可以了。

    闭包、函数、DOM 节点等将起作用!

    【讨论】:

    • 文档在哪里说 Casper.eval() 只会返回一个原语?浪费了很多时间无法弄清楚这一点 - 试图返回一个对象。
    • @nikkwong 所有函数都只返回一个对象。该对象可能是一个可能包含许多对象的实际数组。唯一的一点是,所有这些都必须是可序列化的。
    • 抱歉我来晚了,但是@ArtjomB.,你是说评估可以返回数组对象?因为我遇到了这个错误,我不知道为什么。
    • @Q.H.是的,您可以返回原始数组。我见过your question。看来您还没有在这里阅读我的答案的最后一部分。 DOM 节点不是原始的,所以它失败了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多