如何在PhantomJS中用远程javascript替换DOM节点

时间:2013-08-07 01:15:19

标签: javascript dom phantomjs

我是PhantomJS和javascript的新手,如果有一个简单的解决方案,请原谅我。

我使用PhantomJS来制作网站截图,我想用远程javascript中的动态内容替换某些DOM节点,如下所示:

<script language="JavaScript" src="http://server/dynamic.js" type="text/javascript"></script>

我的第一次尝试:

var page = require('webpage').create();

page.open('http://stackoverflow.com', function (status) {
    if (status !== 'success') {
        phantom.exit();
    }

    page.evaluate(function() {

        //// Case #1: what I really want
        // var s = '<script language="JavaScript" src="http://server/dynamic.js" type="text/javascript"></script>';

        //// Case #2: simple js test case
        // var s = '<script language="JavaScript" type="text/javascript">document.write("<p>THIS IS A TEST</p>");</script>';

        //// Case #3: very simple case
        var s = '<b>THIS IS A TEST</b>';

        var node = document.getElementById('mainbar');
        var pnode = node.parentNode;

        var newele = document.createElement('div');
        newele.innerHTML = s;

        pnode.replaceChild(newele, node);
    });

    page.render('test.jpg');

    phantom.exit();
});

对于简单的情况(案例#3),我只是用一些文本替换它,它工作正常,但不适用于任何一个javascript案例。似乎javascript在通过replaceChild()插入后没有被评估。我在page.render()之前尝试过page.reload(),但它没有帮助。

接下来,我尝试使用iframe创建新元素:

var newele = document.createElement('iframe');
newele.setAttribute('src', 'javascript:document.write("<p>THIS IS A TEST</p>");');

这适用于简单的js测试用例#2,但我无法弄清楚如何使iframe与我真正想要的一起工作(案例#1)。

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

我提出了一个可行的解决方案:

var newele = document.createElement('iframe');
newele.setAttribute('src', 'javascript:document.write("<script src=\'http://server/dynamic.js\'></script>");');

我也不得不拖延一下:

window.setTimeout(function () {
    page.render('test.jpg');
    phantom.exit();
}, 500);

这样可行,但对我来说感觉有点麻烦。我很想听听更好的解决方案。

答案 1 :(得分:0)

不,您可以在第一次调用评估之前(摘录)将您的javascript引用添加到此页面:

...
        page.open(url, function (status) {
            if (status !== 'success') {
                console.log('Error: Cannot load url. Status: {0}.'.format(status));
                phantom.exit(1);
            } else {
                page.injectJs('../../../code/common/jquery.min.js');
                // call evaluate once to change the dropdown:
                page.evaluate(function (myobj) {
                        // manipulate DOM here with jquery, or whatever you want.
                }, myobj);
...

请注意,您可以多次致电评估,这样您就可以从页面中提取内容,从页面调用javascript函数,修改DOM等。