从jsdom迁移到phantomJS? (基本的DOM创build)

M. Bostock指出nodejs的jsdom对svg的支持不够,而且对我来说不支持getBBox() 。 另外,他build议切换到nodejs的PhantomJS。 我检查出来,但这种方法对我来说是新的。

我的nodejs + jsdom脚本创build了一个虚拟的DOM,我的d3js使用它,如下所示:

 var jsdom = require('jsdom'); jsdom.env( // creates virtual page "<html><body></body></html>", // create my DOM hook, [ 'http://d3js.org/d3.v3.min.js', // add my online dependencies ... '../js/d3.v3.min.js', // ... & local ones '../js/jquery-2.1.3.min.js'], function (err, window) { //my normal JS or nodejs code here ! } ); 

如何将这个nodejs + jsdom迁移到nodejs + PhantomJS?

既然你想从node.js做到这一点,你应该使用phantomjs-node ( phantom npm module)这样的PhantomJS桥接器。

当你没有在PhantomJS中打开一个页面时,你实际上是在一个about:空白页面上工作,你需要为底层的PhantomJS进程添加'–local-to-remote-url-access = yes'命令行选项,这样可以加载远程资源。 也许--web-security=falseignore-ssl-errors=true --ssl-protocol=anyignore-ssl-errors=true可能是必要的。

要将其他脚本注入到DOM中,需要为本地文件使用injectJs() ,为远程文件使用injectJs() 。 而且,你不能直接访问PhantomJS中的DOM,因为它有两个上下文。 沙盒页面上下文( page.evaluate() )无法访问外部定义的variables,所以如果需要的话,您需要明确地将它们传递给它们。

 var phantom = require('phantom'); var async = require('async'); function run(page, ph) { page.evaluate(function () { // page context: DOM code here return document.title; }, function (title) { // node code here console.log('Page title is ' + title); ph.exit(); }); } var remoteScripts = [ "http://d3js.org/d3.v3.min.js" ]; var localScripts = [ "../js/d3.v3.min.js", "../js/jquery-2.1.3.min.js" ]; phantom.create('--local-to-remote-url-access=yes', '--web-security=false', function (ph) { ph.createPage(function (page) { async.series(remoteScripts.map(function(url){ return function(next){ page.includeJs(url, function(){ next(); }); }; }), function(){ async.series(localScripts.map(function(url){ return function(next){ page.injectJs(url, function(){ next(); }); }; }), function(){ run(page, ph); }); }); }); }); 

您可以使用asynchronous将脚本列表加载到DOM中。 我使用了series()函数。