在 page.evaluateJavaScript 函数中使用 PhantomJS 变量

Use PhantomJS variable inside of the page.evaluateJavaScript function

我正在使用 PhantomJS 截取仪表板的屏幕截图并将其保存为 PNG 文件。这很好用,但是当我添加一些额外的参数(linedFromdTo)并想在 page.evaluateJavaScript() 中使用它们时,它不起作用。有没有办法在 JavaScript 函数中使用 PhantomJS 变量?

var page = require('webpage').create(),
system = require('system'),
address, output, size, line, dFrom, dTo;

address = system.args[1];
output = system.args[2];
line = "All";
dFrom = null; 
dTo = null;

if (system.args.length > 2)
{
   line = system.args[3];
   dFrom = system.args[4];
   dTo = system.args[5];        
}

page.viewportSize = { width: 1200, height: 1800 };

page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
         page.evaluate(function () { 
             var body = document.body; 
             body.style.backgroundColor = '#fff'; 
             body.querySelector('div#nav-section').style.display = 'none'; 
             body.querySelector('div#to-hide-btns').style.display = 'none';
             body.querySelector('div#main-section').style.overflow = 'hidden'; 
        });
        page.evaluateJavaScript(function () {
            selectedLine = line;
            dateFrom = dFrom;
            dateTo = dTo; 
            onCriteriaChange();
        });
        window.setTimeout(function () {
            page.render(output, {format: 'png', quality: '100'});
            console.log('done');
            phantom.exit();
        }, 2000);
    }
})

如果我把它改成这样就可以了:

page.evaluateJavaScript(function () {
    selectedLine = "S01";
    dateFrom = "3/1/2015";
    dateTo = "3/10/2015"; 
    onCriteriaChange();
});

page.evaluate() 及其兄弟姐妹是进入沙盒页面上下文的大门。您传递给它的函数无法访问外部定义的变量。您需要明确地将这些值传递到页面上下文中:

page.evaluate(function(line, dFrom, dTo) {
    selectedLine = line;
    dateFrom = dFrom;
    dateTo = dTo; 
    onCriteriaChange();
}, line, dFrom, dTo);

你也不能传递任意对象。它们需要可序列化:

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.

Closures, functions, DOM nodes, etc. will not work!