M. Bostock指出nodejs的jsdom对svg的支持不完全,而且对我来说很关键,不支持getBBox().此外,他建议切换到nodejs的PhantomJS.我检查了但这种方法对我来说是新的. 我的nodejs jsdom脚本创建了一个虚拟
我的nodejs jsdom脚本创建了一个虚拟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(幻影npm模块)这样的PhantomJS桥.如果你没有在PhantomJS中打开一个页面,你实际上是在about:blank页面中工作,你需要为底层的PhantomJS进程添加’–local-to-remote-url-access = yes’命令行选项,以便可以加载远程资源.也许–web-security = false,–ssl-protocol = any和ignore-ssl-errors = true可能是必要的.
要将其他脚本注入DOM,您需要将injectJs()
用于本地文件,将includeJs()
用于远程文件.此外,您无法直接访问PhantomJS中的DOM,因为它有两个上下文.沙盒页面上下文(page.evaluate()
)无法访问外部定义的变量,因此如果需要,您需要显式传递它们.
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); }); }); }); });
您可以使用async将脚本列表加载到DOM中.我使用了series()函数.