如何将文本复制到剪贴板(多浏览器)?
相关:Trello如何访问用户的剪贴板?
如何将文本复制到剪贴板(多浏览器)?
相关:Trello如何访问用户的剪贴板?
当前回答
我找到了以下解决方案:
按下键处理程序创建一个“pre”标记。我们设置要复制到此标记的内容,然后在此标记上进行选择并在处理程序中返回true。这将调用Chrome的标准处理程序并复制选定的文本。
如果需要,您可以为恢复先前选择的函数设置超时。我在MooTools上的实现:
function EnybyClipboard() {
this.saveSelection = false;
this.callback = false;
this.pastedText = false;
this.restoreSelection = function() {
if (this.saveSelection) {
window.getSelection().removeAllRanges();
for (var i = 0; i < this.saveSelection.length; i++) {
window.getSelection().addRange(this.saveSelection[i]);
}
this.saveSelection = false;
}
};
this.copyText = function(text) {
var div = $('special_copy');
if (!div) {
div = new Element('pre', {
'id': 'special_copy',
'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
});
div.injectInside(document.body);
}
div.set('text', text);
if (document.createRange) {
var rng = document.createRange();
rng.selectNodeContents(div);
this.saveSelection = [];
var selection = window.getSelection();
for (var i = 0; i < selection.rangeCount; i++) {
this.saveSelection[i] = selection.getRangeAt(i);
}
window.getSelection().removeAllRanges();
window.getSelection().addRange(rng);
setTimeout(this.restoreSelection.bind(this), 100);
} else return alert('Copy did not work. :(');
};
this.getPastedText = function() {
if (!this.pastedText) alert('Nothing to paste. :(');
return this.pastedText;
};
this.pasteText = function(callback) {
var div = $('special_paste');
if (!div) {
div = new Element('textarea', {
'id': 'special_paste',
'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
});
div.injectInside(document.body);
div.addEvent('keyup', function() {
if (this.callback) {
this.pastedText = $('special_paste').get('value');
this.callback.call(null, this.pastedText);
this.callback = false;
this.pastedText = false;
setTimeout(this.restoreSelection.bind(this), 100);
}
}.bind(this));
}
div.set('value', '');
if (document.createRange) {
var rng = document.createRange();
rng.selectNodeContents(div);
this.saveSelection = [];
var selection = window.getSelection();
for (var i = 0; i < selection.rangeCount; i++) {
this.saveSelection[i] = selection.getRangeAt(i);
}
window.getSelection().removeAllRanges();
window.getSelection().addRange(rng);
div.focus();
this.callback = callback;
} else return alert('Failed to paste. :(');
};
}
用法:
enyby_clip = new EnybyClipboard(); // Init
enyby_clip.copyText('some_text'); // Place this in the Ctrl+C handler and return true;
enyby_clip.pasteText(function callback(pasted_text) {
alert(pasted_text);
}); // Place this in Ctrl+V handler and return true;
在粘贴时,它会创建一个文本区域,并以相同的方式工作。
PS:也许这个解决方案可以用于创建没有Flash的完整跨浏览器解决方案。它适用于Firefox和Chrome。
其他回答
我喜欢这个:
<input onclick="this.select();" type='text' value='copy me' />
如果用户不知道如何在操作系统中复制文本,那么他们很可能也不知道如何粘贴。因此,只需自动选择它,剩下的留给用户。
我在从Excel(类似Excel)构建自定义网格编辑以及与Excel的兼容性方面遇到了同样的问题。我必须支持选择多个单元格、复制和粘贴。
解决方案:创建一个文本区域,您将在其中插入数据,供用户复制(当用户选择单元格时为我),设置焦点(例如,当用户按下Ctrl键时)并选择整个文本。
因此,当用户按下Ctrl+C时,他/她会复制他/她选择的单元格。测试后,只需将文本区域调整为一个像素(我没有测试它是否能在显示器上工作:无)。它在所有浏览器上都能很好地工作,并且对用户是透明的。
粘贴-你可以这样做(不同于你的目标)-关注文本区域并使用onpaste捕捉粘贴事件(在我的项目中,我使用单元格中的文本区域进行编辑)。
我不能粘贴一个例子(商业项目),但你明白了。
如果您想要一个真正简单的解决方案(集成时间不到5分钟),并且开箱即用看起来很好,那么Clippy是一些更复杂解决方案的一个不错的替代方案。
它是由GitHub的一位联合创始人撰写的。Flash嵌入代码示例如下:
<object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
width="110"
height="14"
id="clippy">
<param name="movie" value="/flash/clippy.swf"/>
<param name="allowScriptAccess" value="always"/>
<param name="quality" value="high"/>
<param name="scale" value="noscale"/>
<param NAME="FlashVars" value="text=#{text}"/>
<param name="bgcolor" value="#{bgcolor}"/>
<embed
src="/flash/clippy.swf"
width="110"
height="14"
name="clippy"
quality="high"
allowScriptAccess="always"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer"
FlashVars="text=#{text}"
bgcolor="#{bgcolor}"/>
</object>
记住用需要复制的文本替换#{text},用颜色替换#{bgcolor}。
以下方法适用于Chrome、Firefox、Internet Explorer和Edge以及Safari的最新版本(2016年10月发布的第10版增加了复制支持)。
创建一个文本区域,并将其内容设置为要复制到剪贴板的文本。将文本区域附加到DOM。在文本区域中选择文本。调用document.execCommand(“copy”)从dom中删除文本区域。
注意:您不会看到文本区域,因为它是在Javascript代码的同一同步调用中添加和删除的。
如果您自己执行此操作,请注意以下事项:
出于安全原因,这只能从事件处理程序(如单击)调用(与打开窗口一样)。首次更新剪贴板时,Internet Explorer将显示权限对话框。Internet Explorer和Edge将在文本区域聚焦时滚动。execCommand()在某些情况下可能抛出。除非您使用文本区域,否则换行符和制表符可能会被吞入。(大多数文章似乎都建议使用div)当显示Internet Explorer对话框时,文本区域将可见,您需要隐藏它,或使用Internet Explorer特定的剪贴板数据API。在Internet Explorer中,系统管理员可以禁用剪贴板API。
下面的函数应该尽可能干净地处理以下所有问题。如果您发现任何问题或有任何改进建议,请留言。
// Copies a string to the clipboard. Must be called from within an
// event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+,
// Firefox 42+, Safari 10+, Edge and Internet Explorer 10+.
// Internet Explorer: The clipboard feature may be disabled by
// an administrator. By default a prompt is shown the first
// time the clipboard is used (per session).
function copyToClipboard(text) {
if (window.clipboardData && window.clipboardData.setData) {
// Internet Explorer-specific code path to prevent textarea being shown while dialog is visible.
return window.clipboardData.setData("Text", text);
}
else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
var textarea = document.createElement("textarea");
textarea.textContent = text;
textarea.style.position = "fixed"; // Prevent scrolling to bottom of page in Microsoft Edge.
document.body.appendChild(textarea);
textarea.select();
try {
return document.execCommand("copy"); // Security exception may be thrown by some browsers.
}
catch (ex) {
console.warn("Copy to clipboard failed.", ex);
return prompt("Copy to clipboard: Ctrl+C, Enter", text);
}
finally {
document.body.removeChild(textarea);
}
}
}
https://jsfiddle.net/fx6a6n6x/
我找到了以下解决方案:
按下键处理程序创建一个“pre”标记。我们设置要复制到此标记的内容,然后在此标记上进行选择并在处理程序中返回true。这将调用Chrome的标准处理程序并复制选定的文本。
如果需要,您可以为恢复先前选择的函数设置超时。我在MooTools上的实现:
function EnybyClipboard() {
this.saveSelection = false;
this.callback = false;
this.pastedText = false;
this.restoreSelection = function() {
if (this.saveSelection) {
window.getSelection().removeAllRanges();
for (var i = 0; i < this.saveSelection.length; i++) {
window.getSelection().addRange(this.saveSelection[i]);
}
this.saveSelection = false;
}
};
this.copyText = function(text) {
var div = $('special_copy');
if (!div) {
div = new Element('pre', {
'id': 'special_copy',
'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
});
div.injectInside(document.body);
}
div.set('text', text);
if (document.createRange) {
var rng = document.createRange();
rng.selectNodeContents(div);
this.saveSelection = [];
var selection = window.getSelection();
for (var i = 0; i < selection.rangeCount; i++) {
this.saveSelection[i] = selection.getRangeAt(i);
}
window.getSelection().removeAllRanges();
window.getSelection().addRange(rng);
setTimeout(this.restoreSelection.bind(this), 100);
} else return alert('Copy did not work. :(');
};
this.getPastedText = function() {
if (!this.pastedText) alert('Nothing to paste. :(');
return this.pastedText;
};
this.pasteText = function(callback) {
var div = $('special_paste');
if (!div) {
div = new Element('textarea', {
'id': 'special_paste',
'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
});
div.injectInside(document.body);
div.addEvent('keyup', function() {
if (this.callback) {
this.pastedText = $('special_paste').get('value');
this.callback.call(null, this.pastedText);
this.callback = false;
this.pastedText = false;
setTimeout(this.restoreSelection.bind(this), 100);
}
}.bind(this));
}
div.set('value', '');
if (document.createRange) {
var rng = document.createRange();
rng.selectNodeContents(div);
this.saveSelection = [];
var selection = window.getSelection();
for (var i = 0; i < selection.rangeCount; i++) {
this.saveSelection[i] = selection.getRangeAt(i);
}
window.getSelection().removeAllRanges();
window.getSelection().addRange(rng);
div.focus();
this.callback = callback;
} else return alert('Failed to paste. :(');
};
}
用法:
enyby_clip = new EnybyClipboard(); // Init
enyby_clip.copyText('some_text'); // Place this in the Ctrl+C handler and return true;
enyby_clip.pasteText(function callback(pasted_text) {
alert(pasted_text);
}); // Place this in Ctrl+V handler and return true;
在粘贴时,它会创建一个文本区域,并以相同的方式工作。
PS:也许这个解决方案可以用于创建没有Flash的完整跨浏览器解决方案。它适用于Firefox和Chrome。