位置: IT常识 - 正文

聊一聊浏览器打印 - window.print(浏览器你)

编辑:rootadmin
聊一聊浏览器打印 - window.print 前言

推荐整理分享聊一聊浏览器打印 - window.print(浏览器你),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:浏览器d,浏览器咋打不开怎么样打开,浏览器我,浏览器见,浏览器打开,浏览器d,浏览器打开,浏览器打开,内容如对您有帮助,希望把文章链接给更多的朋友!

一般信息填写类的需求页面,都会增设「预览」和「打印」功能。我们会通过编写 DOM 及样式来绘制出预览视图,而打印则是基于预览来生成 PDF 文件。

浏览器原生 API window.print() 可以用于打印当前窗口(window.document)视图内容。调用此方法会产生一个打印预览弹框,用户可以根据具体设置来得到打印结果。

接下来将从 code 层面带领大家熟悉「打印」的使用。

一、打印样式

默认情况下,基于页面上的内容,会将元素,布局和样式都进行打印;

如果仅想在打印上设置特殊样式,可以通过以下方式:

1.使用打印样式表:

<link href="print.css" media="print" rel="stylesheet" />

2.使用媒介查询:

@media print {p{color: lavender;background: #ccc;}h1{color: lightblue;background: #ccc;}}

3.使用内联 media 属性

<style media="print"> p{color: lavender;background: #ccc;}h1{color: lightblue;background: #ccc;} </style>

默认情况下,元素的背景色不会被打印,可通过设置属性来支持:

div{// Chrome、Safari 等 webkit 浏览器内核-webkit-print-color-adjust: exact;// 火狐print-color-adjust: exact;color-adjust: exact;} 二、打印指定区域内容

默认情况下,调用 window.print() 会对整个 document.body 进行打印,当需要打印指定容器内容时,可以通过以下几种方式:

1. 对容器进行打印<body><div id="container"><p>这是一个段落</p><h1>这是一个标题</h1></div><input type="button" value="打印此页面" onclick="printpage()" /><script> const printpage = () => {let newstr = document.getElementById("container").innerHTML;let oldstr = document.body.innerHTML;document.body.innerHTML = newstr;window.print();document.body.innerHTML = oldstr;} </script></body> 2. 对容器内的部分内容进行打印

当只需要打印容器内某一部分内容时,可以通过注释标识进行截取。

<body><div id="container"><!--startprint--><p>这是一个段落</p><!--endprint--><h1>这是一个标题</h1></div><input type="button" value="打印此页面" onclick="printpage()" /><script> const printpage = () => {let oldStr = window.document.body.innerHTML; // 获取body的内容let start = "<!--startprint-->"; // 开始打印标识, 17个字符let end = "<!--endprint-->"; // 结束打印标识let newStr = oldStr.substr(oldStr.indexOf(start) + 17); // 截取开始打印标识之后的内容newStr = newStr.substring(0, newStr.indexOf(end)); // 截取开始打印标识和结束打印标识之间的内容window.document.body.innerHTML = newStr; // 把需要打印的指定内容赋给bodywindow.print(); // 调用浏览器的打印功能打印指定区域window.document.body.innerHTML = oldStr; // body替换为原来的内容} </script></body> 3. 监听打印前后事件聊一聊浏览器打印 - window.print(浏览器你)

通过监听打印前后事件,对不需要进行打印的元素进行隐藏和放开隐藏。

<body><div id="container"><p>这是一个段落</p><h1 id="title">这是一个标题</h1></div><input type="button" value="打印此页面" onclick="printpage()" /><script> const printpage = () => {window.print();}window.onbeforeprint = function() {// 将一些不需要被打印的元素隐藏document.getElementById('title').style.display = 'none';}window.onafterprint = function() {// 放开隐藏的元素document.getElementById('title').style.display = 'block';} </script></body> 4. iframe

上面几种方式都在当前窗口进行打印,并且都需要更改 document.body 内容,这会出现视图切换,带来的体验不是太好。

下面我们借助 iframe 来实现打印,并且不影响当前视窗的内容展示。

<body><div id="container"><p>这是一个段落</p><h1 id="title">这是一个标题</h1></div><input type="button" value="打印此页面" onclick="printpage()" /><script> const printpage = () => {const printContent = document.querySelector('#container').innerHTML;const iframe = document.createElement('iframe');iframe.setAttribute('style', 'position: absolute; width: 0; height: 0;');document.body.appendChild(iframe);const iframeDoc = iframe.contentWindow.document;// 设置打印展示方式 - 横向展示iframeDoc.write('<style media="print">@page {size: landscape;}</style>');// 向 iframe 中注入 printContent 样式iframeDoc.write(`<link href="./print.css" media="print" rel="stylesheet" />`);// 写入内容iframeDoc.write('<div>' + printContent + '</div>');setTimeout(function(){iframe.contentWindow?.print();document.body.removeChild(iframe);}, 50);} </script></body>

值得注意的是,iframe 是一个新的 window 窗口,不会复用当前窗口的样式,需要为 iframe 注入打印内容所需的样式。

三、强行插入分页

当需要自定义打印分页时机时,可通过如下方式将指定 DOM 设为分割点。

1.在指定元素前添加分页符

@media print {h1 {page-break-before: always;}}

2.在指定元素后添加分页符

@media print {h1 {page-break-after: always;}} 四、打印设置

1.设置打印布局

@media print {@page {/* 纵向展示(高度展示内容更多) *//* size: portrait;*//* 横向(宽度展示内容更大) */size: landscape;/* 打印的边距 上右下左 */margin: 1cm 2cm 1cm 2cm;}}

注意,一旦设置为 size: landscape,在打印时将不能切换展示模式,包括纸张类的设置。

五、最佳实践(React)1. 背景:

有一个信息填写页面,支持进行预览和打印,预览是一个 Dialog 弹框,打印取自于预览的内容。因此,在打印前,需要将预览内容呈现在 DOM 树上。

2. 思路:点击打印,将预览 Dialog open state 设置为 true,Dialog 渲染到 DOM 树上;执行 setTimeout 延迟任务,在 Dialog 渲染在 DOM 树上后对其隐藏(disabled: none),目的是实现视图上不展示 Dialog;创建 iframe,并将 Dialog 内容及其样式,写入 iframe.document 中;执行 iframe.contentWindow.print() 进行打印;打印完成后做一些重置处理:移除 iframe、将 Dialog 隐藏逻辑去掉、将 Dialog open state 置为 false;这样,在不影响现有页面内容的展示,同时实现了打印 Dialog 内容。3. 实现:const printFocus = () => { // 打印事件// 1. 挂载要打印的内容setPreviewOpen(true);setTimeout(() => { // 延迟,等待 Dialog 渲染在 DOM 树上// 2. 隐藏要打印的内容const container = document.querySelector('.preview-wrapper');container.setAttribute('style', 'display: none;');// 3. 创建 iframeconst iframe = document.createElement('iframe');const printContent = container.innerHTML;iframe.setAttribute('style', 'position: absolute; width: 0; height: 0;');document.body.appendChild(iframe);const doc = iframe.contentWindow.document;// 4. 写入内容// doc.write('<style media="print">@page {size: landscape;}</style>');doc.write(`<link href="./preview-focus.css" media="print" rel="stylesheet" />`);doc.write('<div>' + printContent + '</div>');const link = doc.getElementsByTagName('link')[0];link.onload = () => { // 样式文件加载完毕后打印// 5. 执行打印iframe.contentWindow?.print();// 6. 重置工作document.body.removeChild(iframe);setPreviewOpen(false);container?.removeAttribute('style');}}, 0);} 六、如果干预打印分页

通常我们会遇到这种情况:在打印内容多于一页时会自动进行分页,若分页的分割点恰巧是一行文字,就会出现文字被切割分别显示在上下两页。

尽管我们可以通过 CSS 属性 page-break-before: always; 来干预分页,但页面内容并非固定的,如何将这个属性恰巧应用在分割点的 DOM 元素之上呢?

下面有一个思路可以参考一下:

1.为可能会被分割的元素设置自定义属性,用于查找访问; 2.根据打印视窗的每页高度,粗估一个高度值,作为页面分割的参考; 3.遍历可分割元素,判断它们是否处于页面分割位置(top < pageHeight && botton > pageHeight); 4.若处于页面分割位置,为此 DOM 设置分割属性 page-break-before: always;。

代码实现:

<!-- 自定义属性标识 --><div key={index} data-ident="page-break" className="module-paragraph"><script> // 1、获取可能会被分页符分割的元素const pageBreakEles = container?.querySelectorAll("[data-ident = 'page-break']") || [];// 2、定义打印页面的高度,假设粗估后为 877pxconst printPageHeight = 877;// 3、匹配元素,是否处于页面分割线位置Array.from(pageBreakEles).forEach(ele => {const { top, bottom } = ele.getBoundingClientRect();// 根据高度计算元素处于第几页const currentPage = Math.floor(top / printPageHeight);// 处于分页符位置的元素,设置分割属性if ((top - currentPage * printPageHeight) < printPageHeight && (bottom - currentPage * printPageHeight) > printPageHeight) {(ele as HTMLElement).style.setProperty('page-break-before', 'always');}}); </script> 最后

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。 有需要的小伙伴,可以点击下方卡片领取,无偿分享

本文链接地址:https://www.jiuchutong.com/zhishi/297402.html 转载请保留说明!

上一篇:zabbix_server命令 zabbix服务器守护进程(zabbix server端口)

下一篇:js查找数组中符合条件的元素(js查找数组所有符合条件数据)

  • 华为nova5是不是水滴屏(华为nova6se怎么样)

    华为nova5是不是水滴屏(华为nova6se怎么样)

  • 华为手机相机打不开是怎么回事(华为手机相机打开后不能拍照)

    华为手机相机打不开是怎么回事(华为手机相机打开后不能拍照)

  • 华为手机页面天气日期不在了怎么办(华为手机页面天气预报)

    华为手机页面天气日期不在了怎么办(华为手机页面天气预报)

  • 嗨来电扣不扣费(嗨来电收费吗收多少钱)

    嗨来电扣不扣费(嗨来电收费吗收多少钱)

  • 为什么拨打对方的手机老说在通话中(为什么拨打对方电话说正在忙)

    为什么拨打对方的手机老说在通话中(为什么拨打对方电话说正在忙)

  • 淘宝评论置顶多久更新(淘宝评论置顶多久有效)

    淘宝评论置顶多久更新(淘宝评论置顶多久有效)

  • 内蒙古户户通e04授权丢失怎么处理(户户通eo1)

    内蒙古户户通e04授权丢失怎么处理(户户通eo1)

  • 候补订单一般什么情况下会成功(候补订单一般什么时候出来)

    候补订单一般什么情况下会成功(候补订单一般什么时候出来)

  • 台电和台积电是一个吗(台电和台积电是什么关系)

    台电和台积电是一个吗(台电和台积电是什么关系)

  • 硬盘写入速度(下载速度超过硬盘写入速度)

    硬盘写入速度(下载速度超过硬盘写入速度)

  • 手机ot g什么意思

    手机ot g什么意思

  • 抖音上显示可能认识的人是什么意思(抖音上显示可能会火的视频)

    抖音上显示可能认识的人是什么意思(抖音上显示可能会火的视频)

  • 微信被加入黑名单后怎么才可以加对方(微信被加入黑名单怎么加回来)

    微信被加入黑名单后怎么才可以加对方(微信被加入黑名单怎么加回来)

  • 小米手机耗电快是什么原因(小米手机耗电快换电池有用吗)

    小米手机耗电快是什么原因(小米手机耗电快换电池有用吗)

  • 苹果8p访问限制找不到(苹果8p访问限制功能在哪里)

    苹果8p访问限制找不到(苹果8p访问限制功能在哪里)

  • 苹果双卡短信怎么区分(苹果双卡短信怎么发)

    苹果双卡短信怎么区分(苹果双卡短信怎么发)

  • word怎么弄成左右两页(word怎么弄成左右两页并排打印)

    word怎么弄成左右两页(word怎么弄成左右两页并排打印)

  • 华为荣耀4手环怎么接电话(华为荣耀4手环怎么更换表带)

    华为荣耀4手环怎么接电话(华为荣耀4手环怎么更换表带)

  • 决策支持系统属于什么系统(决策支持系统属于数据处理吗)

    决策支持系统属于什么系统(决策支持系统属于数据处理吗)

  • airpods怎么升级(airpods怎么升级?)

    airpods怎么升级(airpods怎么升级?)

  • 设置不拉黑拒绝收信息(不拉黑对方怎么可以拒接电话)

    设置不拉黑拒绝收信息(不拉黑对方怎么可以拒接电话)

  • 苹果手机的开发者选项在哪里打开(苹果手机的开发人员选项在哪找)

    苹果手机的开发者选项在哪里打开(苹果手机的开发人员选项在哪找)

  • qq黄钻有哪些功能(qq黄钻有哪些功能可以玩)

    qq黄钻有哪些功能(qq黄钻有哪些功能可以玩)

  • 微云怎么取消自动续费(怎么关掉微云自动续费)

    微云怎么取消自动续费(怎么关掉微云自动续费)

  • mac删除快捷键(苹果mac删除快捷键)

    mac删除快捷键(苹果mac删除快捷键)

  • 收到退税款怎么入账
  • 附加税申报免抵税额什么意思
  • 节税是什么意思
  • 企业发生的印花税计入什么科目
  • 减免增值税计入
  • 销售收入与营业费用的配比
  • 企业城建税教育费附加和地教费的税率是多少
  • 罚款收据与通用的区别
  • 研发过程中材料费计入
  • 上市公司限制性股票行权时间限制多久
  • 咨询服务费没有发票
  • 超市预付款应做在哪个会计科目?
  • 非金融机构借款计入什么科目
  • 增值税专用发票和普通发票的区别
  • 外管证交税需要带什么材料
  • 未提足折旧的房产,推倒重置的财务处理到底有没有差异
  • 残保金申报有什么用
  • windows10专业
  • 数人侵权行为的类型
  • win11打开图片
  • 补缴的耕地占用税怎么做账
  • 工程结算书和竣工结算书
  • negro 什么意思
  • redis网络模型 框架图
  • codewriter怎么运行
  • 利润分配弥补亏损会计分录
  • jquery版本
  • php绘制图片
  • Centos6.5和Centos7 php环境搭建方法
  • 税金及附加和营业收入有关系吗
  • php实现多语言切换
  • cancel怎么关
  • 增值税电子普通发票和专票的区别
  • python中if语句的用法
  • python中如何创建字典
  • 个税申报怎样作废
  • 购货发票属于是什么凭证
  • 同时运行多个MySQL服务器的方法
  • sql删除表中的某一行
  • 支付增值税税控系统技术维护费用
  • 电算化会计档案论文答辩自述稿
  • 高速公路费如何开票
  • 购买性支出和转移性支出的区别
  • 衍生工具什么意思
  • 废弃土地怎么认定
  • 上年度固定资产费用化了,财报怎么算
  • 车辆使用费怎么算
  • 外贸公司是不是什么都做的?
  • 房地产企业沙盘模拟
  • 企业如何优化管理
  • 企业预缴增值税税率
  • 电商的成本构成包括
  • 网银退回是什么意思
  • 住宿费报账怎么写
  • 删除sql server2019
  • sql语句如何将一列数据值相加
  • 怎么看mac的硬盘型号
  • Mac系统怎么设置开机密码
  • macbook air一键恢复出厂设置
  • xp系统里的打印机怎么设置的和新7
  • macbook graphpad
  • centos7 login账号
  • windows 8.1 with update (multiple editions)
  • 支持iphone
  • win7如何设置多个显示器
  • linux学啥
  • 电脑主板驱动
  • python必学的os模块详解
  • 网页跳转的实现方法
  • nodejs child_process
  • dos批命令
  • html中<
  • 批处理命令读取文件内容
  • c++ 编程
  • json遍历对象集合
  • 12366纳税服务平台人工时间
  • 计提税金的公式
  • 福建失业金领取几个月
  • 免抵税额在增值税申报表附表
  • 湖北省税务局网站授权
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设