Перейти с jsdom на phantomJS? (базовое создание DOM)

М. Босток указал, что jsdom nodejs имеет неполную поддержку svg и, что критично для меня, не поддерживает getBBox(). Также он посоветовал перейти на PhantomJS от nodejs. Я проверил, но подход для меня новый.

Мой скрипт 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?


person Hugolpz    schedule 21.04.2015    source источник
comment
Как вы думаете, можно ли добавить ссылку на рекомендацию М. Бостока (относительно jsdom и phantomjs)?   -  person turdus-merula    schedule 18.06.2017
comment
Да, конечно. Просто отредактируйте.   -  person Hugolpz    schedule 18.06.2017
comment
Я имел в виду тебя - у меня нет ссылки, я думал, что ты есть :)   -  person turdus-merula    schedule 19.06.2017
comment
Там groups.google.com/forum/#!msg/d3 -js/JyldAkWkTvI/n8thanJeGvAJ ! @user1475331   -  person Hugolpz    schedule 26.06.2017


Ответы (1)


Поскольку вы хотите сделать это из node.js, вам следует использовать мост PhantomJS, например phantomjs-node. (модуль фантом npm).

Когда вы не открываете страницу в PhantomJS, вы фактически работаете с пустой страницей about:, вам нужно добавить параметр командной строки «--local-to-remote-url-access=yes» для основного процесса PhantomJS, так что удаленные ресурсы могут быть загружены. Возможно, --web-security=false, --ssl-protocol=any и ignore-ssl-errors=true могут понадобиться.

Чтобы внедрить дополнительные скрипты в DOM, вам нужно использовать injectJs() для локальных файлов и includeJs() для удаленных файлов. Кроме того, вы не можете получить прямой доступ к DOM в PhantomJS, поскольку он имеет два контекста. Контекст изолированной страницы (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().

person Artjom B.    schedule 21.04.2015
comment
Возможно, вам придется использовать более новую версию PhantomJS, например 2.0, если 1.9.x не предоставляет всего, что вам нужно. - person Artjom B.; 21.04.2015
comment
Спасибо. Я начинаю копаться в Phantomjs благодаря вашим советам по началу работы. - person Hugolpz; 22.04.2015
comment
Примечание. Я только что перечислил 3 зависимости для этого вопроса, хотя на самом деле у меня есть ~ 12 зависимостей, которые нужно собрать, это быстро будет выглядеть грязно. Я готов оценить масштабируемость, ремонтопригодность и читабельность PhantomJS, поскольку мне придется держать товарищей по команде в курсе. Любая передача массива URL-адресов, похожих на jsdom? (Проверил ваши ссылки, ничего подобного не нашел!) - person Hugolpz; 22.04.2015
comment
Когда я копаюсь в Phontomjs, я лучше понимаю ваш пост и ценю его как глобальный обзор и учебник. Потрясающий ! :) - person Hugolpz; 22.04.2015
comment
Я добавил версию с асинхронной загрузкой. - person Artjom B.; 22.04.2015
comment
if может сделать это немного короче. Примечание: ваш ответ уже заслуживает подтверждения или 3 голосов, но я хочу оставить место открытым, если кто-то придет с другим пакетом моста npm. - person Hugolpz; 22.04.2015
comment
Давайте продолжим обсуждение в чате. - person Hugolpz; 22.04.2015
comment
Ответ подтвержден! Спасибо за отличный ответ :) - person Hugolpz; 24.04.2015