前言
今天领导给了个需求,需要配合其他项目组给一个公共组件的npm进行,公共组件打印,打印操作由这个npm包来操作。(经过开会商讨,最后决定配置一个path路径,来展示页面,然后我负责在公共这里打印相应页面内容。)在这之初都是好着的,首先进行配置,这里只需要一个input框来给后端传值就可以了,这一步没什么好讲的,
正传
好了 正头戏开始了,通过请求在mounted中发送请求,获取到配置好的 path路径,开始我想着用路由进行编写后来发现过于麻烦,选择了iframe标签来进行编写,(这里再说一下留下来的需求,需要弹窗然后展示其他组要展示的内容)这里选择了iframe ,然而iframe的src值如果不是本项目页面的话 是会报跨域的,so(幸好我们是同一个域名同一个端口号) 这里我对src 路径的最前面的地址进行处理,编写一个 获取域名以及端口号等的一个过滤方法,方法如下:
// 获取http域名
urlhttp() {
console.log(window.location.href, "window.location.href");
// 截取域名前面的部分
const url = window.location.href.split("://")[1];
const urlhttp = window.location.href.split("://")[0];
const urlArr = url.split("/");
const urlStr = urlArr[0];
const urlStrArr = urlStr.split(".");
const urlStrArrLen = urlStrArr.length;
const urlStrArrLenLast = urlStrArrLen - 1;
const urlStrArrLenLastStr = urlStrArr[urlStrArrLenLast];
const urlStrArrLenLastStrLen = urlStrArrLenLastStr.length;
const urlStrArrLenLastStrLenLast = urlStrArrLenLastStrLen - 1;
const urlStrArrLenLastStrLenLastStr = urlStrArrLenLastStr[urlStrArrLenLastStrLenLast];
const urlStrArrLenLastStrLenLastStrNum = Number(urlStrArrLenLastStrLenLastStr);
if (urlStrArrLenLastStrLenLastStrNum) {
this.urlStr = urlStrArr[urlStrArrLenLastStrLenLastStrNum];
} else {
this.urlStr = urlStrArr[urlStrArrLenLastStrLenLastStr];
}
console.log(urlhttp + urlStr, "urlStr");
// 截取域名带http+域名
this.urlhttpStr = urlhttp + "://" + urlStr;
console.log(this.urlhttpStr, "urlhttpStr");
},
通过次方法,对页面域名进行格式化,其中window.location.href 获取的是当前地址框的所有地址,然后通过.split(" : / / " )[1];等进行数据的获取,最终得到:http://localhost:8080 这种地址,
从而拼接起来我配置的 iframe的src地址拼接后,弹窗展示了相应的页面,
然后在弹窗上给一个打印按钮(重头戏来了) 我先对iframe标签进行ref的设置,从而获取该节点,然后我将
const contentWindow = iframe.contentWindow.document;
节点进行赋值,拿到后直接打印该节点,
调用 contentWindow.print(); 方法,发现打印信息不全的情况,然后我通过翻阅资料方得知 会有样式排版等一些问题导致至此,所以次方法pass,过,后又发现可以通过创建新的页面进行展示打印,然后我调用
const printWindow = window.open("", "_blank");
printWindow.document.write(`
<html>
<body>
</body>
</html>
`);
去创建新页面,在新页面中执行打印方法
printWindow.document.close();
printWindow.print();
然后发现打印后,我iframe中的打印的东西消失了,然后我便复制一个子节点然后再用子节点打印
const childElementcopy = childElement.cloneNode(true); // 复制元素
发现奏效了,但是没有css样式,我开始便利子节点的样式文章来源:https://www.toymoban.com/news/detail-553884.html
Array.from(sourceComputedStyle).forEach(style => {
const value = sourceComputedStyle.getPropertyValue(style);
printElement.style.setProperty(style, value);
});
但是次方法未奏效,尝试了好多办法后,我查看元素时候发现 style标签我可以直接copy旗下所有元素啊 然后便复制了一份,一起加入打印的新页面,至此完成次需求,下面是全部代码文章来源地址https://www.toymoban.com/news/detail-553884.html
async submitPrint() {
const iframe = this.$refs.myIframe;
console.log(this.$refs.myIframe, "this.$refs.myIframe");
const contentWindow = iframe.contentWindow.document;
const head = contentWindow.querySelector("head")
// 访问iframe的子元素
const childElement = contentWindow.getElementById(this.printLocation) || contentWindow.getElementsByClassName(this.printLocation)[0]
//this.printLocation是我后配置的要打印模块的id
console.log(childElement);
const childElementcopy = childElement.cloneNode(true); // 复制html元素
const headcopy = head.cloneNode(true); // 复制css 样式元素元素
const printWindow = window.open("", "_blank");
// 在前确保先监听
printWindow.document.write(`
<html>
<body>
</body>
</html>
`);
const printBody = printWindow.document.querySelector("body");
const printhead = printWindow.document.querySelector("html");
printhead.appendChild(headcopy);
printBody.appendChild(childElementcopy);
printWindow.onafterprint = function() {
// 在打印对话框关闭后执行的逻辑
console.log("打印对话框已关闭");
// 判断用户是否点击了取消按钮
var printResult = window.matchMedia("print");
if (printResult.matches) {
console.log("用户点击了取消按钮");
// 执行取消打印的相关逻辑
printWindow.close(); // 关闭新页面
} else {
console.log("用户点击了打印按钮");
// 执行打印操作的相关逻辑
printWindow.close(); // 关闭新页面
}
};
setTimeout(() => {
printWindow.document.close();
printWindow.print();
}, 500);
// const printBody = printWindow.document.querySelector('body');
// const printhead = printWindow.document.querySelector('html');
// printhead.appendChild(headcopy);
// printBody.appendChild(childElementcopy);
// printWindow.document.close();
// printWindow.print();
// 监听新窗口的onload事件,在加载完成后执行打印操作
},
对你有帮助的话请点赞收藏,你的鼓励我会收到的
到了这里,关于vue 打印html <iframe>标签(内容打印)超详细的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!