javascript casperjs:评估 document.querySelector 返回空值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17954923/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 10:12:48  来源:igfitidea点击:

casperjs: evaluating document.querySelector returns a null

javascriptdomphantomjscasperjsevaluate

提问by 3cheesewheel

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.

我在 CasperJS 中使用waitForSelector()captureSelector()方法来等待并使用 CSS 选择器选择一个元素,然后保存它的屏幕截图。

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

但是,我发现由于 cssbackground已设置为transparent,因此屏幕截图非常难看,因此我想backgroundwhite. 我已经确定document.querySelector评估()调用中使用,但这似乎不起作用。

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

这是我的脚本(你可以忽略之前的所有内容casper.start(...,我只包含了下一个代码片段的上下文的开头部分):

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:

这是我在传入 url、选择器和文件名以将屏幕截图写入时得到的输出:

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.

注意:是的,我很清楚这个截图结果很好(因为背景是白色的)......我只是决定使用任何旧的 url,因为我只是想说明document.query()调用不起作用预期的。

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

回答by hexid

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.

您遇到了问题,因为您无法从evaluate(). 但是,您可以直接使用评估块内的元素。

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

我已经在 CasperJS 1.1-beta1 上对此进行了测试,但它应该适用于 >= 1.0.0 的版本

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

编辑:可以传回对象,但不能传回 DOM 元素。