Phantomjs 不会使用自定义样式呈现页脚
Posted
技术标签:
【中文标题】Phantomjs 不会使用自定义样式呈现页脚【英文标题】:Phantomjs doesn't render footers with a custom styles 【发布时间】:2013-07-04 08:54:21 【问题描述】:我有以下例子:
var page = require('webpage').create(),
system = require('system');
if (system.args.length < 3)
console.log('Usage: printheaderfooter.js URL filename');
phantom.exit(1);
else
var address = system.args[1];
var output = system.args[2];
page.viewportSize = width: 600, height: 600 ;
page.paperSize =
format: 'A4',
margin: "1cm"
footer:
height: "1cm",
contents: phantom.callback(function(pageNum, numPages)
if (pageNum == numPages)
return "";
return "<h1 class='footer_style'>Footer" + pageNum + " / " + numPages + "</h1>";
)
;
page.open(address, function (status)
if (status !== 'success')
console.log('Unable to load the address!');
else
window.setTimeout(function ()
page.render(output);
phantom.exit();
, 200);
);
在上面的示例中,我使用了在我的 css 文件中如下所示的 footer_style 类:
.footer_style
text-align:right;
但不幸的是,这不起作用。我正在尝试创建 pdf 文件,如下所示:
./phantomjs rasterize.js index.html test.pdf
【问题讨论】:
【参考方案1】:我们知道类不起作用,但内联样式可以。我们可以做的是用计算的样式替换类。
这是一个函数,它将获取一段 html,使用 html 在正文中创建一个临时元素,使用类计算每个元素的样式,内联添加计算的样式并返回新的 html。
function replaceClassWithStyle(html)
return page.evaluate(function(html)
var host = document.createElement('div');
host.innerHTML = html;
document.body.appendChild(host); // if not appended, values will be blank
var elements = host.getElementsByTagName('*');
for (var i in elements)
if (elements[i].className)
elements[i].setAttribute('style', window.getComputedStyle(elements[i], null).cssText);
document.body.removeChild(host);
return host.innerHTML;
, html);
然后只需在页脚中调用此函数:
page.paperSize =
footer:
contents: phantom.callback(function(pageNum, numPages)
if (pageNum == numPages)
return "";
return replaceClassWithStyle("<h1 class='footer_style'>Footer" + pageNum + " / " + numPages + "</h1>");
)
;
您需要将所有这些都移到 page.open()
中。
我测试过了,页脚向右对齐。
【讨论】:
这看起来像是呈现页眉/页脚的理想解决方案,但在 v1.9.7 中,这似乎在 appendChild 之后“清空”了 document.body。可能是一个 PhantomJS 错误。你在哪个版本中测试过这个?【参考方案2】:我为 PhantomJS 1.9.7 更新了 mak's excellent answer。
此版本修复:
规避“空白”为父文档的错误 (PhantomJS 1.9.7) 嵌套样式时的样式混淆(改为进行深度优先遍历) 标签没有类时也可以使用/**
* Place HTML in the parent document, convert CSS styles to fixed computed style declarations, and return HTML.
* (required for headers/footers, which exist outside of the HTML document, and have trouble getting styling otherwise)
*/
function replaceCssWithComputedStyle(html)
return page.evaluate(function(html)
var host = document.createElement('div');
host.setAttribute('style', 'display:none;'); // Silly hack, or PhantomJS will 'blank' the main document for some reason
host.innerHTML = html;
// Append to get styling of parent page
document.body.appendChild(host);
var elements = host.getElementsByTagName('*');
// Iterate in reverse order (depth first) so that styles do not impact eachother
for (var i = elements.length - 1; i >= 0; i--)
elements[i].setAttribute('style', window.getComputedStyle(elements[i], null).cssText);
// Remove from parent page again, so we're clean
document.body.removeChild(host);
return host.innerHTML;
, html);
【讨论】:
【参考方案3】:根据我过去的经验,phantomjs 不支持自定义页眉/页脚中的样式。
我发现的唯一解决方案是应用这样的内联样式:
var page = require('webpage').create(),
system = require('system');
if (system.args.length < 3)
console.log('Usage: printheaderfooter.js URL filename');
phantom.exit(1);
else
var address = system.args[1];
var output = system.args[2];
page.viewportSize = width: 600, height: 600 ;
page.paperSize =
format: 'A4',
margin: "1cm",
footer:
height: "1cm",
contents: phantom.callback(function(pageNum, numPages)
return "<h1 style='text-align:right'>Footer" + pageNum + " / " + numPages + "</h1>";
)
;
page.open(address, function (status)
if (status !== 'success')
console.log('Unable to load the address!');
else
window.setTimeout(function ()
page.render(output);
phantom.exit();
, 200);
);
注意:margin: "1cm"
后面的代码中缺少逗号
【讨论】:
是的,我知道这个解决方案,但我需要通过使用 css 类来实现它以上是关于Phantomjs 不会使用自定义样式呈现页脚的主要内容,如果未能解决你的问题,请参考以下文章