从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=false
, ignore-ssl-errors=true
--ssl-protocol=any
和ignore-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()
函数。