当前位置:   article > 正文

基于jQuery的打印插件——printThis.js使用说明文档

printthis
知识点解析:
1. 跨域操作的必要性
       结合printThis的实际情况,动态生成的iframe打印内容和当前页面属于同一基础域名下的两个不同的子域,正常情况下,这两个子域是不能相互通信的,而我们的需求是用网站头部引入的样式去渲染打印文本即iframe的表现样式,所以必须实现跨域操作。
2. document.domain实现同一基础域名下不同子域之间的跨域操作
         前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域。
       IE与其他浏览器的区别:我们的printthis插件是部署在第三方的页面中,是否设置了document.domain是为知的,而在IE浏览器中,只要设置了document.domain,访问iframe就会提示没有权限,如果IE中不设置document.domain是不会提示的,而非IE浏览器中不存在这样的问题,所以,我们需要先对页面进行检测。
3. printThis.js的组成部分及说明
3.1 入口配置文件
   入口配置文件各项参数说明
$.fn.printThis.defaults = {
debug: false, // 调试模式下打印文本的渲染状态
importCSS: true, // 为打印文本引入外部样式--link标签 ["<link rel='stylesheet' href='/static/jquery/forieprint.css' media='print'>","",""]
importStyle: false, // 为打印把文本书写内部样式 ["<style>#ceshi{}</style>","",""]
printContainer: true, // 设置为true,向文本中插入内容
loadCSS: "", // 为打印文本引入外部样式--路径 ["/static/jquery/forieprint.css","",""]
pageTitle: "", // 为打印文本中添加<titile>标签,标签内容将在打印出的文件顶部显示,这里会和打印原有标题冲突,建议谨慎使用。"<title>测试header</title>"
removeInline: false, // 清除body的默认样式,包括内外边距,字体等,目的是为了让渲染文本和打印文本保持一致
printDelay: 333, // 布局完打印页面之后与真正执行打印功能中间的间隔
header: null, // 在打印文本的body中添加header标签,这里的内容将在打印出的文件顶部居左显示 "<header>测试header</header>"
formValues: true, // 如果打印的目标源码中又表单内容就选择true,这里是为新的打印文本中的表单赋值
doctypeString: '<!DOCTYPE html>' // 添加文档声明,使得渲染和打印保持一致
};
3.2 成员函数printThis
    printThis()方法是jquery类的扩展“成员方法”
    该成员方法按照执行顺序可拆解为检测document.domain、填充iframe、打印三个部分。
    3.2.1 IE浏览器下检测页面是否设置了document.domain值
if (window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)) {//如果当前页面设置了document.domain的值&& 为ie浏览器
// Ugly IE hacks due to IE not inheriting document.domain from parent
// checks if document.domain is set by comparing the host name against document.domain
var iframeSrc = "javascript:document.write(\"<head><script>document.domain=\\\"" + document.domain + "\\\";</script></head><body></body>\")";
var printI = document.createElement('iframe'); //创建iframe节点
printI.name = "printIframe"; //设计节点的属性,name,id,className
printI.id = strFrameName;
printI.className = "MSIE";
document.body.appendChild(printI);//设置body的子元素为iframe
printI.src = iframeSrc;//将当前iframe的src属性设置成当前页面的域,保持iframe和当前页面的document.main保持一直,实现跨域通信
 
} else {//非ie下不存在问题
// other browsers inherit document.domain, and IE works if document.domain is not explicitly set
var $frame = $("<iframe id='" + strFrameName + "' name='printIframe' />");
$frame.appendTo("body");
}
3.2.2 填充iframe内容
       iframe的内容包括文档声明、<head>里面的内容(标题样式等)、<body>里面的内容,form表单
3.2.2.1 文档声明
       文档声明是为了保持打印和渲染的样式保持一直
// 添加DOCTYPE来解决印刷和渲染之间的风格差异
function setDocType($iframe,doctype){
var win, doc;
win = $iframe.get(0);
win = win.contentWindow || win.contentDocument || win; //取得子窗口的document对象
doc = win.document || win.contentDocument || win;
doc.open();
doc.write(doctype);//写入DOCTYPE
doc.close();
}
if(opt.doctypeString){//声明文档类型解决印刷与渲染之间的风格差异
setDocType($iframe,opt.doctypeString);
}
3.2.2.2 <head>
        head标签内容包括base和样式。
         base标签的作用是将“生成打印文件”的所有href链接全部链接成主域名+端口号,这样做的优点是去除死链接和原有代码中的无效链接。
        插件提供了三种方式为新生成的打印文本提供样式,归纳起来其实是两种,即外部样式和内部样式,外部样式加载的方式适用于样式代码较多的情况,内部样式代码加载适用于样式代码较少的情况。详细解释看下方的源码注解。
// 设置打印文本中的所有链接的url全部是主域名
$head.append('<base href="' + document.location.protocol + '//' + document.location.host + '">');//网络协议,域名+端口号
 
// 为打印文本添加新的外部样式--link
if (opt.importCSS) $("link[rel=stylesheet]").each(function() {// 如果importCSS.opt返回true即样式引入方式为link标签引入,执行循环体
var href = $(this).attr("href"); //获取link标签的href属性
if (href) {
var media = $(this).attr("media") || "all"; //获取link标签的media属性,这里应该设置为print
$head.append("<link type='text/css' rel='stylesheet' href='" + href + "' media='" + media + "'>")
}
});
 
// 为打印文本添加新的内部样式
if (opt.importStyle) $("style").each(function() {//如果opt.importStyle返回true即样式在页面中直接写入。执行循环体
$(this).clone().appendTo($head);//将<style>标签以及内容克隆到<head>标签下
//$head.append($(this));
});
 
//为打印文本添加文本titile
if (opt.pageTitle) $head.append("<title>" + opt.pageTitle + "</title>");//设置文档title名称
 
// 为打印文本添加新的外部样式--路径
if (opt.loadCSS) {//如果opt.loadCss返回true即样式以路径的方式引入
if( $.isArray(opt.loadCSS)) {//如果传参是多个路径,执行循环体
jQuery.each(opt.loadCSS, function(index, value) {
$head.append("<link type='text/css' rel='stylesheet' href='" + this + "'>");
});
} else {
$head.append("<link type='text/css' rel='stylesheet' href='" + opt.loadCSS + "'>");
}
}
 3.2.2.3 <body>
        body标签中主要是需要打印部分的内容,下面代码的意思是将源文件中的内容克隆并插入iframe中的body标签中。
// 在body中插入<header>标签
if (opt.header) $body.append(opt.header);//在body中插入<header>标签
 
// 在body里面插入div里面的内容
if (opt.printContainer) $body.append($element.outer());//在body里面插入div里面的内容
 
//插入为空
else $element.each(function() {
$body.append($(this).html());
});
// 返回原打印文本的所有代码
jQuery.fn.outer =
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/171372
推荐阅读
相关标签
  

闽ICP备14008679号