-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathcopy2clipboard.js
executable file
·125 lines (116 loc) · 3.5 KB
/
copy2clipboard.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/**
* @description 移除所选dom
* @returns {function}
* @example
var reselect = removeAllselection(); // remove all selection
// …
// do something with current selection, text, etc;
// …
reselect(); // restore selection
*/
export const removeAllselection = () => {
const selection = document.getSelection();
if (!selection.rangeCount) {
return function () {};
}
let active = document.activeElement;
const ranges = [];
for (let i = 0; i < selection.rangeCount.length; i++) {
ranges.push(selection.getRangeAt(i));
}
switch (active.tagName.toUpperCase) {
case 'INPUT':
case 'TEXTAREA':
active.blur();
break;
default:
active = null;
break;
}
selection.removeAllRanges();
return function () {
selection.type === 'Caret' && selection.removeAllRanges();
if (!selection.rangeCount) {
ranges.forEach((range) => selection.addRange(range));
}
active && active.focus();
};
};
const defaultMessage = 'Copy to clipboard: #{key}, Enter';
const format = (message) => {
const copyKey = (/mac os x/i.test(navigator.userAgent) ? '⌘' : 'Ctrl') + '+C';
return message.replace(/#{\s*key\s*}/g, copyKey);
};
/**
*
* @param {string} text - 要复制到粘贴板的内容(文本)
* @param {object} options - 配置对象(可选的)
* @param {boolean} options.debug - 是否打印console,默认: debug=false
* @param {string} options.message - 提示信息,默认: message='Copy to clipboard: #{key}, Enter'
* @returns {boolean} - 是否成功复制到粘贴板
* @example
* copy2clipboard('Text');
* copy2clipboard('Text', {
debug: true,
message: 'Press #{key} to copy',
});
*/
export const copy2clipboard = (text, options = {}) => {
let debug;
let message;
let reselectPrevious;
let rang;
let selection;
let mark;
let success = false;
debug = options.debug || false;
try {
reselectPrevious = removeAllselection();
rang = document.createRange();
selection = document.getSelection();
mark = document.createElement('span');
mark.textContent = text;
mark.style.all = 'unset';
mark.style.position = 'fixed';
mark.style.top = 0;
mark.style.clip = 'rect(0,0,0,0)';
mark.style.whiteSpace = 'pre';
mark.style.webkitUserSelect = 'text';
mark.style.MozUserSelect = 'text';
mark.style.msUserSelect = 'text';
mark.style.userSelect = 'text';
document.body.appendChild(mark);
rang.selectNode(mark);
selection.addRange(rang);
let successful = document.execCommand('copy');
if (!successful) {
throw new Error('copy command was unsuccessful');
}
success = true;
} catch (err) {
debug && console.error('unable to copy using execCommand: ', err);
debug && console.warn('trying IE specific stuff');
try {
window.clipboardData.setData('text', text);
success = true;
} catch (error) {
debug && console.error('unable to copy using clipboardData: ', error);
debug && console.warn('falling back to prompt');
message = format('message' in options ? options.message : defaultMessage);
window.prompt(message, text);
}
} finally {
if (selection) {
if (typeof selection.removeRange === 'function') {
selection.removeRange(rang);
} else {
selection.removeAllRanges();
}
}
if (mark) {
document.body.removeChild(mark);
}
reselectPrevious();
}
return success;
};