打印DIV内容的最佳方法是什么?
当前回答
下面的代码复制了查询选择器目标的所有相关节点,复制了它们在屏幕上看到的样式,因为许多用于css选择器目标的父元素将会丢失。如果有很多带有很多样式的子节点,这将导致一些延迟。
理想情况下,你应该有一个打印样式表,但这是为用例,没有打印样式表插入,你希望打印在屏幕上看到。
如果您在此页的浏览器控制台中复制以下项目,它将打印此页上的所有代码片段。
+function() {
/**
* copied from https://stackoverflow.com/questions/19784064/set-javascript-computed-style-from-one-element-to-another
* @author Adi Darachi https://stackoverflow.com/users/2318881/adi-darachi
*/
var copyComputedStyle = function(from,to){
var computed_style_object = false;
//trying to figure out which style object we need to use depense on the browser support
//so we try until we have one
computed_style_object = from.currentStyle || document.defaultView.getComputedStyle(from,null);
//if the browser dose not support both methods we will return null
if(!computed_style_object) return null;
var stylePropertyValid = function(name,value){
//checking that the value is not a undefined
return typeof value !== 'undefined' &&
//checking that the value is not a object
typeof value !== 'object' &&
//checking that the value is not a function
typeof value !== 'function' &&
//checking that we dosent have empty string
value.length > 0 &&
//checking that the property is not int index ( happens on some browser
value != parseInt(value)
};
//we iterating the computed style object and compy the style props and the values
for(property in computed_style_object)
{
//checking if the property and value we get are valid sinse browser have different implementations
if(stylePropertyValid(property,computed_style_object[property]))
{
//applying the style property to the target element
to.style[property] = computed_style_object[property];
}
}
};
// Copy over all relevant styles to preserve styling, work the way down the children tree.
var buildChild = function(masterList, childList) {
for(c=0; c<masterList.length; c++) {
var master = masterList[c];
var child = childList[c];
copyComputedStyle(master, child);
if(master.children && master.children.length > 0) {
buildChild(master.children, child.children);
}
}
}
/** select elements to print with query selector **/
var printSelection = function(querySelector) {
// Create an iframe to make sure everything is clean and ordered.
var iframe = document.createElement('iframe');
// Give it enough dimension so you can visually check when modifying.
iframe.width = document.width;
iframe.height = document.height;
// Add it to the current document to be sure it has the internal objects set up.
document.body.append(iframe);
var nodes = document.querySelectorAll(querySelector);
if(!nodes || nodes.length == 0) {
console.error('Printing Faillure: Nothing to print. Please check your querySelector');
return;
}
for(i=0; i < nodes.length; i++) {
// Get the node you wish to print.
var origNode = nodes[i];
// Clone it and all it's children
var node = origNode.cloneNode(true);
// Copy the base style.
copyComputedStyle(origNode, node);
if(origNode.children && origNode.children.length > 0) {
buildChild(origNode.children, node.children);
}
// Add the styled clone to the iframe. using contentWindow.document since it seems the be the most widely supported version.
iframe.contentWindow.document.body.append(node);
}
// Print the window
iframe.contentWindow.print();
// Give the browser a second to gather the data then remove the iframe.
window.setTimeout(function() {iframe.parentNode.removeChild(iframe)}, 1000);
}
window.printSelection = printSelection;
}();
printSelection('.default.prettyprint.prettyprinted')
其他回答
我修改了@BillPaetski答案使用querySelector,添加可选的CSS,删除强制H1标签,并使标题可选地指定或从窗口拉出。它也不再自动打印,并公开内部内容,以便它们可以在包装器函数中切换或随你喜欢。
仅有的两个私有变量是tmpWindow和tmpDoc,尽管我相信标题,css和elem访问可能会有所不同,但应该假设所有函数参数都是私有的。
Code:function PrintElem(elem, title, css) {
var tmpWindow = window.open('', 'PRINT', 'height=400,width=600');
var tmpDoc = tmpWindow.document;
title = title || document.title;
css = css || "";
this.setTitle = function(newTitle) {
title = newTitle || document.title;
};
this.setCSS = function(newCSS) {
css = newCSS || "";
};
this.basicHtml5 = function(innerHTML) {
return '<!doctype html><html>'+(innerHTML || "")+'</html>';
};
this.htmlHead = function(innerHTML) {
return '<head>'+(innerHTML || "")+'</head>';
};
this.htmlTitle = function(title) {
return '<title>'+(title || "")+'</title>';
};
this.styleTag = function(innerHTML) {
return '<style>'+(innerHTML || "")+'</style>';
};
this.htmlBody = function(innerHTML) {
return '<body>'+(innerHTML || "")+'</body>';
};
this.build = function() {
tmpDoc.write(
this.basicHtml5(
this.htmlHead(
this.htmlTitle(title) + this.styleTag(css)
) + this.htmlBody(
document.querySelector(elem).innerHTML
)
)
);
tmpDoc.close(); // necessary for IE >= 10
};
this.print = function() {
tmpWindow.focus(); // necessary for IE >= 10*/
tmpWindow.print();
tmpWindow.close();
};
this.build();
return this;
}
Usage:
DOMPrinter = PrintElem('#app-container');
DOMPrinter.print();
虽然@BC的答案最好打印一页。
但要打印多页A4大小的同时按ctrl+P以下解决方案可能会有所帮助。
@media print{
html *{
height:0px!important;
width:0px !important;
margin: 0px !important;
padding: 0px !important;
min-height: 0px !important;
line-height: 0px !important;
overflow: visible !important;
visibility: hidden ;
}
/*assing myPagesClass to every div you want to print on single separate A4 page*/
body .myPagesClass {
z-index: 100 !important;
visibility: visible !important;
position: relative !important;
display: block !important;
background-color: lightgray !important;
height: 297mm !important;
width: 211mm !important;
position: relative !important;
padding: 0px;
top: 0 !important;
left: 0 !important;
margin: 0 !important;
orphans: 0!important;
widows: 0!important;
overflow: visible !important;
page-break-after: always;
}
@page{
size: A4;
margin: 0mm ;
orphans: 0!important;
widows: 0!important;
}}
如果你想拥有原始文档的所有样式(包括内联样式),你可以使用这种方法。
复制完整的文档 将body替换为要打印的元素。
实现:
class PrintUtil {
static printDiv(elementId) {
let printElement = document.getElementById(elementId);
var printWindow = window.open('', 'PRINT');
printWindow.document.write(document.documentElement.innerHTML);
setTimeout(() => { // Needed for large documents
printWindow.document.body.style.margin = '0 0';
printWindow.document.body.innerHTML = printElement.outerHTML;
printWindow.document.close(); // necessary for IE >= 10
printWindow.focus(); // necessary for IE >= 10*/
printWindow.print();
printWindow.close();
}, 1000)
}
}
我编写了一个插件来解决这种情况。我对现有的插件不满意,开始做一些更广泛/可配置的东西。
https://github.com/jasonday/printThis
只需使用PrintJS
let printjs = document.createElement("script");
printjs.src = "https://printjs-4de6.kxcdn.com/print.min.js";
document.body.appendChild(printjs);
printjs.onload = function (){
printJS('id_of_div_you_want_to_print', 'html');
}
推荐文章
- 我如何使用Jest模拟JavaScript的“窗口”对象?
- 如何使Bootstrap 4卡在卡列相同的高度?
- 我如何等待一个承诺完成之前返回一个函数的变量?
- 在JavaScript中根据键值查找和删除数组中的对象
- 使嵌套JavaScript对象平放/不平放的最快方法
- 使用域集图例引导
- 如何以及为什么'a'['toUpperCase']()在JavaScript工作?
- 音频停止功能
- 有Grunt生成index.html不同的设置
- 如何禁用谷歌翻译从HTML在Chrome
- 文档之间的区别。addEventListener和window。addEventListener?
- 如何检查动态附加的事件监听器是否存在?
- 防止在ASP中缓存。NET MVC中使用属性的特定操作
- 如何写setTimeout与参数Coffeescript
- 将JavaScript字符串中的多个空格替换为单个空格