Nin*_*ili 67 javascript clipboard copy mobile-safari ios
我正在使用此功能将URL复制到剪贴板:
function CopyUrl($this){
var querySelector = $this.next().attr("id");
var emailLink = document.querySelector("#"+querySelector);
var range = document.createRange();
range.selectNode(emailLink);
window.getSelection().addRange(range);
try {
// Now that we've selected the anchor text, execute the copy command
var successful = document.execCommand('copy', false, null);
var msg = successful ? 'successful' : 'unsuccessful';
if(true){
$this.addClass("copied").html("Copied");
}
} catch(err) {
console.log('Oops, unable to copy');
}
// Remove the selections - NOTE: Should use
// removeRange(range) when it is supported
window.getSelection().removeAllRanges();
}
Run Code Online (Sandbox Code Playgroud)
在桌面浏览器上一切正常,但在我的函数成功返回的iOS设备上没有,但数据根本没有复制到剪贴板.造成这种情况的原因是什么?如何解决这个问题?
Mar*_*lli 116
看起来在选择范围和一些小黑客的帮助下,可以直接复制到iOS(> = 10)Safari上的剪贴板.我个人在iPhone 5C iOS 10.3.3和iPhone 8 iOS 11.1上进行了测试.但是,似乎有一些限制,它们是:
<input>
和<textarea>
元素中复制文本.<form>
,那么它必须是contenteditable
.readonly
(虽然你可能会尝试,这不是一个"官方"的方法记录任何地方).要涵盖所有这四个"要求",您必须:
<input>
或<textarea>
元素中.contenteditable
以及readonly
复制后能够还原它们的元素.contenteditable
到true
和readonly
到false
.contenteditable
和readonly
值.execCommand('copy')
.这将导致用户设备的插入符移动并选择所需元素中的所有文本,然后自动发出复制命令.用户将看到正在选择的文本,并且将显示带有选项/复制/粘贴选项的工具提示.
现在,这看起来有点复杂,只是发出一个复制命令太麻烦,所以我不确定这是Apple的预期设计选择,但是谁知道......同时,这当前有效在iOS> = 10.
有了这个说法,像这样的polyfill可用于简化此操作并使其跨浏览器兼容(感谢@Toskan在评论中的链接).
工作实例
总而言之,您需要的代码如下所示:
function iosCopyToClipboard(el) {
var oldContentEditable = el.contentEditable,
oldReadOnly = el.readOnly,
range = document.createRange();
el.contentEditable = true;
el.readOnly = false;
range.selectNodeContents(el);
var s = window.getSelection();
s.removeAllRanges();
s.addRange(range);
el.setSelectionRange(0, 999999); // A big number, to cover anything that could be inside the element.
el.contentEditable = oldContentEditable;
el.readOnly = oldReadOnly;
document.execCommand('copy');
}
Run Code Online (Sandbox Code Playgroud)
请注意,el
此函数的参数必须是a <input>
或a <textarea>
.
在iOS <10上,对Clipboard API的 Safari(实际上是安全措施)有一些限制:
copy
仅在有效选择上触发事件,cut
并且paste
仅在可聚焦的可编辑字段中触发事件.document.execCommand()
.请注意,"shorcut键"表示一些可点击(例如复制/粘贴操作菜单或自定义iOS键盘快捷键)或物理键(例如连接的蓝牙键盘).ClipboardEvent
构造函数.因此(至少截至目前),不可能使用Javascript以编程方式在iOS设备上复制剪贴板中的某些文本/值.只有用户才能决定是否复制某些内容.
但是,可以通过编程方式选择某些内容,这样用户只需点击选择中显示的"复制"工具提示即可.这可以使用与上面完全相同的代码来实现,只需删除execCommand('copy')
,这实际上是行不通的.
Mar*_*vic 46
我已经搜索了一些解决方案,我找到了一个实际可行的解决方案:http://www.seabreezecomputers.com/tips/copy2clipboard.htm
基本上,示例可能是这样的:
var $input = $(' some input/textarea ');
$input.val(result);
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
var el = $input.get(0);
var editable = el.contentEditable;
var readOnly = el.readOnly;
el.contentEditable = 'true';
el.readOnly = 'false';
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
el.setSelectionRange(0, 999999);
el.contentEditable = editable;
el.readOnly = readOnly;
} else {
$input.select();
}
document.execCommand('copy');
$input.blur();
Run Code Online (Sandbox Code Playgroud)
Vit*_*.us 23
这是我的跨浏览器实现
您可以通过运行以下代码段进行测试
例:
copyToClipboard("Hello World");
Run Code Online (Sandbox Code Playgroud)
copyToClipboard("Hello World");
Run Code Online (Sandbox Code Playgroud)
/**
* Copy a string to clipboard
* @param {String} string The string to be copied to clipboard
* @return {Boolean} returns a boolean correspondent to the success of the copy operation.
*/
function copyToClipboard(string) {
let textarea;
let result;
try {
textarea = document.createElement('textarea');
textarea.setAttribute('readonly', true);
textarea.setAttribute('contenteditable', true);
textarea.style.position = 'fixed'; // prevent scroll from jumping to the bottom when focus is set.
textarea.value = string;
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
const range = document.createRange();
range.selectNodeContents(textarea);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
textarea.setSelectionRange(0, textarea.value.length);
result = document.execCommand('copy');
} catch (err) {
console.error(err);
result = null;
} finally {
document.body.removeChild(textarea);
}
// manual copy fallback using prompt
if (!result) {
const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
const copyHotkey = isMac ? '?C' : 'CTRL+C';
result = prompt(`Press ${copyHotkey}`, string); // eslint-disable-line no-alert
if (!result) {
return false;
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
注意:当它不是由用户启动时(例如超时或任何异步事件),它将不起作用!
它必须来自受信任的事件,例如来自
click
按钮 事件的调用
Joh*_*rty 22
出于安全原因,iOS Safari仅允许容器document.execCommand('copy')
内的文本contentEditable
.
解决方法是检测iOS Safari并contentEditable
在执行前快速切换document.execCommand('copy')
.
以下函数应适用于所有浏览器/设备,并接受CSS Selector或HTMLElement:
function copyToClipboard(el) {
// resolve the element
el = (typeof el === 'string') ? document.querySelector(el) : el;
// handle iOS as a special case
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
// save current contentEditable/readOnly status
var editable = el.contentEditable;
var readOnly = el.readOnly;
// convert to editable with readonly to stop iOS keyboard opening
el.contentEditable = true;
el.readOnly = true;
// create a selectable range
var range = document.createRange();
range.selectNodeContents(el);
// select the range
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
el.setSelectionRange(0, 999999);
// restore contentEditable/readOnly to original state
el.contentEditable = editable;
el.readOnly = readOnly;
}
else {
el.select();
}
// execute copy command
document.execCommand('copy');
}
Run Code Online (Sandbox Code Playgroud)
input { font-size: 14px; font-family: tahoma; }
button { font-size: 14px; font-family: tahoma; }
Run Code Online (Sandbox Code Playgroud)
<input class="important-message" type="text" value="Hello World" />
<button onclick="copyToClipboard('.important-message')">Copy</button>
Run Code Online (Sandbox Code Playgroud)
Rod*_*igo 11
请检查我的解决方案.
它适用于Safari(在iPhone 7和iPad上测试)和其他浏览器.
window.Clipboard = (function(window, document, navigator) {
var textArea,
copy;
function isOS() {
return navigator.userAgent.match(/ipad|iphone/i);
}
function createTextArea(text) {
textArea = document.createElement('textArea');
textArea.value = text;
document.body.appendChild(textArea);
}
function selectText() {
var range,
selection;
if (isOS()) {
range = document.createRange();
range.selectNodeContents(textArea);
selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
textArea.setSelectionRange(0, 999999);
} else {
textArea.select();
}
}
function copyToClipboard() {
document.execCommand('copy');
document.body.removeChild(textArea);
}
copy = function(text) {
createTextArea(text);
selectText();
copyToClipboard();
};
return {
copy: copy
};
})(window, document, navigator);
// How to use
Clipboard.copy('text to be copied');
Run Code Online (Sandbox Code Playgroud)
https://gist.github.com/rproenca/64781c6a1329b48a455b645d361a9aa3 https://fiddle.jshell.net/k9ejqmqt/1/
希望对你有所帮助.
问候.
小智 6
从版本 13.4 开始,iOS Safari 支持现代异步剪贴板 API:
与 JavaScript 中的所有内容一样,新的 API 大约好 1000 倍,但您仍然需要大量的后备代码,因为您的许多用户将使用旧版本多年。
以下是如何将新的剪贴板 API 与原始问题中的代码一起使用:
function CopyUrl($this){
var querySelector = $this.next().attr("id");
var emailLink = document.querySelector("#"+querySelector);
if (navigator.clipboard) {
var myText = emailLink.textContent;
navigator.clipboard.writeText(myText).then(function() {
// Do something to indicate the copy succeeded
}).catch(function() {
// Do something to indicate the copy failed
});
} else {
// Here's where you put the fallback code for older browsers.
}
}
Run Code Online (Sandbox Code Playgroud)
我的解决方案是通过结合此页面上的其他答案创建的。
与其他答案不同,它不需要您在页面上已经有一个元素。它将创建自己的文本区域,然后清理混乱。
function copyToClipboard(str) {
var el = document.createElement('textarea');
el.value = str;
el.setAttribute('readonly', '');
el.style = {position: 'absolute', left: '-9999px'};
document.body.appendChild(el);
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
// save current contentEditable/readOnly status
var editable = el.contentEditable;
var readOnly = el.readOnly;
// convert to editable with readonly to stop iOS keyboard opening
el.contentEditable = true;
el.readOnly = true;
// create a selectable range
var range = document.createRange();
range.selectNodeContents(el);
// select the range
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
el.setSelectionRange(0, 999999);
// restore contentEditable/readOnly to original state
el.contentEditable = editable;
el.readOnly = readOnly;
} else {
el.select();
}
document.execCommand('copy');
document.body.removeChild(el);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
63133 次 |
最近记录: |