返回
从 clipboard.js 核心代码一窥浏览器复制功能的秘密
前端
2023-09-26 09:37:32
当我们谈论如何在浏览器中实现文本复制功能时,首先需要了解的是,浏览器本身就提供了一些 API 可以帮助我们实现这个功能。其中最常用的 API 就是 document.execCommand('copy')。这个 API 可以让浏览器复制选定的文本到剪贴板。
clipboard.js 就是一个基于这个 API 的库,它提供了更简单、更方便的方法来复制文本。我们只需要在需要复制文本的元素上添加一个 data-clipboard-text 属性,然后调用 clipboard.js 的方法,就可以轻松地复制文本。
为了更好地理解 clipboard.js 的工作原理,我们来看一下它的核心代码:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['exports'], factory);
} else if (typeof exports !== 'undefined') {
factory(exports);
} else {
root.ClipboardJS = factory({});
}
}(this, function (exports) {
var ClipboardJS = function (target, options) {
if (!target) {
throw new Error('Target required');
}
this.target = target;
this.text = target.getAttribute('data-clipboard-text');
this.options = Object.assign({}, ClipboardJS.defaults, options);
this.handlers = [];
this._bindClick();
};
ClipboardJS.defaults = {
container: document.body,
trigger: 'click',
text: null,
html: null,
target: null,
action: null,
emitter: null,
template: '<button type="button" class="btn btn-primary" data-clipboard-action="copy" title="Copy to clipboard">{text}</button>'
};
ClipboardJS.prototype.bind = function () {
var that = this;
this.handlers = [];
this._bindClick();
};
ClipboardJS.prototype._bindClick = function () {
var that = this;
this.handlers.push(
addEventListener(this.target, this.options.trigger, function (e) {
that.selectTarget();
that._copyText();
e.preventDefault();
})
);
};
ClipboardJS.prototype._copyText = function () {
var that = this;
var selectedText = window.getSelection().toString();
var success = false;
if (!this.options.text && !this.options.html) {
this.options.text = this.target.getAttribute('data-clipboard-text');
}
if (this.options.text) {
success = _copyToClipboard(this.options.text);
} else if (this.options.html) {
success = _copyToClipboard(this.options.html);
} else if (selectedText) {
success = _copyToClipboard(selectedText);
}
if (success) {
this.emit('success');
} else {
this.emit('error');
}
document.body.removeEventListener('keydown', this._keydown);
};
function _copyToClipboard(text) {
var tempElem = document.createElement('textarea');
tempElem.style.position = 'absolute';
tempElem.style.left = '-99999px';
tempElem.style.top = '-99999px';
tempElem.value = text;
document.body.appendChild(tempElem);
tempElem.select();
var success = document.execCommand('copy');
document.body.removeChild(tempElem);
return success;
}
ClipboardJS.prototype.remove = function () {
var handler;
while (handler = this.handlers.shift()) {
handler.removeEventListener();
}
};
ClipboardJS.prototype.emit = function (type) {
var handler;
if (typeof type !== 'string') {
throw new Error('Type must be a string');
}
type = new CustomEvent(type);
if (typeof this.options.emitter === 'function') {
this.options.emitter(type);
} else {
while (handler = this.handlers.shift()) {
handler.dispatchEvent(type);
}
}
};
exports.ClipboardJS = ClipboardJS;
return ClipboardJS;
}));
从这段代码中,我们可以看到 clipboard.js 的核心功能就是通过调用 document.execCommand('copy') 来复制文本。这个 API 可以让浏览器复制选定的文本到剪贴板。
success = _copyToClipboard(text);
我们重点看一下 _copyToClipboard 函数。这个函数首先创建一个临时元素(一个 textarea 元素),然后将需要复制的文本设置为这个临时元素的 value。接下来,它将这个临时元素添加到文档中,并将其选中。最后,它调用 document.execCommand('copy') 来复制选定的文本到剪贴板。
success = document.execCommand('copy');
复制完成后,它会将临时元素从文档中移除。
document.body.removeChild(tempElem);
最后,它返回一个布尔值,表示复制操作是否成功。
return success;
通过阅读 clipboard.js 的核心代码,我们可以了解到如何在浏览器中实现文本复制功能的原理。我们也可以了解到 clipboard.js 是如何使用这个原理来实现文本复制功能的。