/**
* 声明Symbol的变量是为了设置类的私有方法或者变量
*/
const IFRAME = Symbol('iframe');
const LINK_LIST = Symbol('linkList');
const INIT = Symbol('init');
const GET_LINK = Symbol('getLink');
const GET_DOM = Symbol('getDOM');
const ADD_EVENT = Symbol('addEvent');
const CREATE_IFRAM = Symbol('createIframe');
const CREATE_LINK = Symbol('createLink');
const CREATE_CONTENT = Symbol('createContent');
/**
* @description: 打印文档中的特定区域
* @param {string || object} eventSource 事件源(触发事件的源)
* @param {string || object} target 目标源(打印内容)
* @param {string} title 打印标题
* @param {string} args 打印需要的样式文件
* 注意:除了前两个参数,剩余的都为样式文件,即link标签中的href路径
*/
class PrintSpecificPartOfDoc {
constructor(eventSource, target, title, ...args) {
this.eventSource = this[GET_DOM](eventSource);
this.target = this[GET_DOM](target);
this.title = title;
this[IFRAME] = null;
this[LINK_LIST] = [];
args.forEach(href => {
let link = document.createElement('link');
link.setAttribute('href', href);
this[LINK_LIST].push(link);
})
this[ADD_EVENT](this.eventSource, 'click', () => {
this[INIT]();
})
};
/**
* @description: 初始化事件
*/
[INIT]() {
this[CREATE_IFRAM]();
this[CREATE_LINK]();
this[CREATE_CONTENT]();
/**
* 添加延时器的目的:为了解决首次打印的时候,样式未加载完成的时候,就已经触发打印事件
*/
setTimeout(() => {
this[IFRAME].contentWindow.print();
}, 50)
};
/**
* @description: 创建iframe标签
*/
[CREATE_IFRAM]() {
// 判断iframe标签是否存在是为了避免多次创建影响性能
if (!this[IFRAME]) {
let iframe = document.createElement('iframe');
iframe.setAttribute('id', 'printIframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
}
};
/**
* @description: 创建打印需要的样式
*/
[CREATE_LINK]() {
this[IFRAME] = document.getElementById('printIframe');
let styleSheets = [...this[LINK_LIST], ...this[GET_LINK]()];
let doc = this[IFRAME].contentWindow.document;
let head = doc.getElementsByTagName('head')[0];
let title = document.createElement('title');
title.innerHTML = this.title;
head.appendChild(title);
styleSheets.forEach(styleSheet => {
head.appendChild(styleSheet);
})
};
/**
* @description: 创建打印的内容区域
*/
[CREATE_CONTENT]() {
let doc = this[IFRAME].contentWindow.document;
let body = doc.querySelector('body');
body.innerHTML = '';
body.appendChild(this.target.cloneNode(true));
};
/**
* @description: 获取打印的样式
*/
[GET_LINK]() {
const styles = document.getElementsByTagName('head')[0].getElementsByTagName('link');
let printCss = [];
for (let i = 0; i < styles.length; i++) {
let attr = styles[i].getAttribute('media');
if (attr == 'all' || attr == 'print') printCss.push(styles[i].cloneNode(true));
}
return printCss;
};
/**
* @description: 获取DOM
* @param {string || object} el domID || DOM
* @return {object} dom对象
*/
[GET_DOM](el) {
if (typeof el !== 'string' && typeof el !== 'object') {
throw new TypeError(`The "${el}" is not a String or Object!`);
}
return typeof el === 'string' ? document.getElementById(el) : el;
};
/**
* @description: 添加事件
* @param {object} node DOM节点
* @param {string} type 事件类型
* @param {function} fn 事件回调
*/
[ADD_EVENT](node, type, fn) {
if (node.addEventListener) {
node.addEventListener(type, fn, false);
} else if (node.attachEvent) {
node.attachEvent('on' + type, function () {
fn.call(node, window.event);
})
}
};
}
原生js打印功能
最新推荐文章于 2024-07-18 15:44:51 发布