casperjs: evaluating document.querySelector returns a null

女生的网名这么多〃 提交于 2019-12-06 02:36:44

问题


I'm using the waitForSelector() and captureSelector() methods in CasperJS to wait for and select an element using a CSS selector, then save a screenshot of it.

However, I'm finding that because the css background has been set to transparent, the screenshot turns out pretty ugly, so I'd like to set the background to white. I've made sure that I'm using document.querySelector in an evaluate() call, but that doesn't seem to work.

Here's my script (you can ignore everything before casper.start(..., I just included the beginning part for context for the next code snippet):

var casper = require("casper").create({
  verbose: true,
  clientScripts: ["libs/jquery-1.10.2.js"]
});
var utils = require("utils");

var requiredOptions = [ 'url', 'selector', 'filename' ];
var missingOptions = new Array();

for (var i = 0 ; i < requiredOptions.length ; i++) {
  var opt =  requiredOptions[i];
  if (!casper.cli.has(opt)) {
    missingOptions.push(opt);
  }
}

if (missingOptions.length > 0) {
  casper.die("\nMissing the following CLI options: " + missingOptions.join(", ") + "\n\nExiting.\n");
}

var url = casper.cli.get('url');
var selector = casper.cli.get('selector');
var filename = casper.cli.get('filename');

casper.start(url, function() {
  this.waitForSelector(selector, function then() {
    var element = this.evaluate(function() {
      return document.querySelector(selector);
    });
    console.log(element); // returns null
    element.style.backgroundColor = "white"; // throws TypeError: 'null' is not an object (evaluating 'element.style') 
    this.captureSelector("captures/" + filename, selector);
  }, function onTimeout() {
    this.die("URL timed out.");
  });
});

casper.run();

And this is the output I get when I pass in a url, selector, and filename to write the screenshot to:

yiqing:~/Repos/rectslice()$ casperjs slice.js --filename='screenshot.png' --url='https://github.com/n1k0/casperjs/issues/192' --selector='.discussion-bubble-inner'
null
TypeError: 'null' is not an object (evaluating 'element.style')                 
  /Users/yiqing/Repos/rectslice/slice.js:31 in then
  /Users/yiqing/Repos/rectslice:1329 in runStep
  /Users/yiqing/Repos/rectslice:332 in checkStep

Note: Yes, I am well aware that this screenshot turns out fine (in that the background is white)... I just decided to use any old url, since I'm only trying to illustrate that the document.query() call doesn't work as expected.

Also, not sure if the versions are relevant, but here they are anyway:

yiqing:~/Repos/rectslice()$ casperjs --version
1.0.2
yiqing:~/Repos/rectslice()$ phantomjs --version
1.9.0

回答1:


You are running into issues because you can't pass back DOM elements from evaluate(). You can work directly with the element inside of the evaluate block however.

casper.start(url, function() {
  this.waitForSelector(selector, function then() {
    this.evaluate(function(sel) {
      document.querySelector(sel).style.backgroundColor = "white";
    }, selector);
    this.captureSelector("captures/" + filename, selector);
  }, function onTimeout() {
    this.die("URL timed out.");
  });
});

casper.run();

I've tested this on CasperJS 1.1-beta1, but it should work with versions >= 1.0.0

Edit: Can pass back objects, but not DOM elements.



来源:https://stackoverflow.com/questions/17954923/casperjs-evaluating-document-queryselector-returns-a-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!