node.js - 从 jsdom 迁移到 phantomJS ? (基本 DOM 创建)

标签 node.js d3.js phantomjs jsdom

米。 Bostock 指出 nodejs 的 jsdom 对 svg 的支持不完整,而且对我来说至关重要的是,它不支持 getBBox()。此外,他建议切换到 nodejs 的 PhantomJS。我检查了一下,但这种方法对我来说是新的。

我的 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 这样的 PhantomJS 桥接器(幻影 npm 模块)。

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

要将其他脚本注入(inject) 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() 函数。

关于node.js - 从 jsdom 迁移到 phantomJS ? (基本 DOM 创建),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29770240/

相关文章:

php - 设置 haProxy 以在 Appfog 上切换多个应用程序的内容

javascript - Blazor,从 Javascript 创建的 DOM 元素获取输入值

javascript - 获取条形图中每个 y 轴的唯一最大值

python - Selenium PhantomJS 抛出 EelementNotVisible,而 Firefox 在组合框选择期间完全正常

javascript - 如何将 Node.js PhantomJS 包装器中的事件从页面发布到 Node ?

ruby-on-rails - 如何在 Capybara 中模拟两次快速点击提交按钮?

node.js - 为什么类型检查器认为这是错误的类型以及如何处理?

javascript - 如何向该数组添加对象?

python - 从 python spawn 子进程接收连续输出不起作用

javascript - 一旦父节点在 d3 图中折叠,需要将子节点的链接转移到父节点