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();
}
데스크톱 브라우저에서는 모든 것이 제대로 작동하지만 내 함수가 성공적으로 반환되는 iOS 장치에서는 작동하지 않지만 데이터는 클립 보드에 전혀 복사되지 않습니다. 이 문제의 원인은 무엇이며 어떻게이 문제를 해결할 수 있습니까?
최신 정보! iOS> = 10
선택 범위와 약간의 해킹 덕분에 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 .
이 말한다면, 같은 polyfills 이 하나 이 작업을 단순화하고 (감사 호환 브라우저 교차하게 사용될 수 @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');
}
el
이 함수 의 매개 변수는 <input>
또는 여야합니다 <textarea>
.
이전 답변 : 이전 iOS 버전
에 아이폰 OS <10 받는 사람 (실제로 보안 조치입니다) 사파리에 대한 몇 가지 제한이 클립 보드 API는 :
- 이 화재
copy
는 유효한 선택과 이벤트를cut
하고paste
에만 초점을 맞춘 편집 가능한 필드에. - .NET이 아닌 바로 가기 키를 통한 OS 클립 보드 읽기 / 쓰기 만 지원합니다
document.execCommand()
. "바로 가기 키"는 클릭 가능한 일부 (예 : 복사 / 붙여 넣기 작업 메뉴 또는 사용자 정의 iOS 키보드 단축키) 또는 물리적 키 (예 : 연결된 블루투스 키보드)를 의미합니다. ClipboardEvent
생성자를 지원하지 않습니다 .
따라서 (적어도 현재로서는) Javascript를 사용하여 iOS 기기의 클립 보드에있는 일부 텍스트 / 값을 프로그래밍 방식으로 복사 할 수 없습니다 . 사용자 만이 복사 여부를 결정할 수 있습니다.
그러나 프로그래밍 방식으로 무언가를 선택할 수 있으므로 사용자는 선택 항목에 표시된 "복사"도구 설명 만 누르기 만하면됩니다. 이것은 위와 똑같은 코드로 달성 할 수 있습니다 execCommand('copy')
. 실제로 작동하지 않을.
몇 가지 솔루션을 검색했고 실제로 작동하는 솔루션을 찾았습니다. 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();
문제 : iOS Safari document.execCommand('copy')
는 contentEditable
컨테이너 내의 텍스트 만 허용 합니다 .
솔루션 : iOS Safari를 감지 contentEditable
하고 document.execCommand('copy')
.
아래 기능은 모든 브라우저에서 작동합니다. CSS 선택기 또는 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');
}
input { font-size: 14px; font-family: tahoma; }
button { font-size: 14px; font-family: tahoma; }
<input class="important-message" type="text" value="Hello World" />
<button onclick="copyToClipboard('.important-message')">Copy</button>
이것은 내 크로스 브라우저 구현입니다.
아래 스 니펫을 실행하여 테스트 할 수 있습니다.
예:
copyToClipboard("Hello World");
/**
* 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;
}
Demo: <button onclick="copyToClipboard('It works!\nYou can upvote my answer now :)') ? this.innerText='Copied!': this.innerText='Sorry :(' ">Click here</button>
<p>
<textarea placeholder="(Testing area) Paste here..." cols="80" rows="4"></textarea>
</p>
참고 : 시간 초과 또는 비동기 이벤트와 같이 사용자가 시작하지 않으면 작동하지 않습니다!
click
버튼 의 이벤트에서 호출 된 것과 같은 신뢰할 수있는 이벤트에서 가져와야 합니다.
내 솔루션을 확인하십시오.
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');
https://gist.github.com/rproenca/64781c6a1329b48a455b645d361a9aa3 https://fiddle.jshell.net/k9ejqmqt/1/
도움이되기를 바랍니다.
문안 인사.
내 솔루션은이 페이지의 다른 답변을 결합하여 만들어졌습니다.
다른 답변과 달리 페이지에 이미 요소가 있어야 할 필요는 없습니다. 자체 텍스트 영역을 만들고 나중에 엉망을 정리합니다.
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);
}
좋은 것, 여기에 누군가가 관심이있는 경우를 대비 한 typescript 리 팩터가 있습니다 (ES6 모듈로 작성 됨).
type EditableInput = HTMLTextAreaElement | HTMLInputElement;
const selectText = (editableEl: EditableInput, selectionStart: number, selectionEnd: number) => {
const isIOS = navigator.userAgent.match(/ipad|ipod|iphone/i);
if (isIOS) {
const range = document.createRange();
range.selectNodeContents(editableEl);
const selection = window.getSelection(); // current text selection
selection.removeAllRanges();
selection.addRange(range);
editableEl.setSelectionRange(selectionStart, selectionEnd);
} else {
editableEl.select();
}
};
const copyToClipboard = (value: string): void => {
const el = document.createElement('textarea'); // temporary element
el.value = value;
el.style.position = 'absolute';
el.style.left = '-9999px';
el.readOnly = true; // avoid iOs keyboard opening
el.contentEditable = 'true';
document.body.appendChild(el);
selectText(el, 0, value.length);
document.execCommand('copy');
document.body.removeChild(el);
};
export { copyToClipboard };
이것은 읽기 전용 입력 요소로 나를 위해 일했습니다.
copyText = input => {
const isIOSDevice = navigator.userAgent.match(/ipad|iphone/i);
if (isIOSDevice) {
input.setSelectionRange(0, input.value.length);
} else {
input.select();
}
document.execCommand('copy');
};
iOS에서 테스트 한 후 클립 보드에 복사하는 iOS 및 기타 브라우저 용 기능 : 5c, 6,7
/**
* Copies to Clipboard value
* @param {String} valueForClipboard value to be copied
* @param {Boolean} isIOS is current browser is Ios (Mobile Safari)
* @return {boolean} shows if copy has been successful
*/
const copyToClipboard = (valueForClipboard, isIOS) => {
const textArea = document.createElement('textarea');
textArea.value = valueForClipboard;
textArea.style.position = 'absolute';
textArea.style.left = '-9999px'; // to make it invisible and out of the reach
textArea.setAttribute('readonly', ''); // without it, the native keyboard will pop up (so we show it is only for reading)
document.body.appendChild(textArea);
if (isIOS) {
const range = document.createRange();
range.selectNodeContents(textArea);
const selection = window.getSelection();
selection.removeAllRanges(); // remove previously selected ranges
selection.addRange(range);
textArea.setSelectionRange(0, valueForClipboard.length); // this line makes the selection in iOS
} else {
textArea.select(); // this line is for all other browsers except ios
}
try {
return document.execCommand('copy'); // if copy is successful, function returns true
} catch (e) {
return false; // return false to show that copy unsuccessful
} finally {
document.body.removeChild(textArea); // delete textarea from DOM
}
};
contenteditable = true에 대한 위의 답변. 나는 div에만 속한다고 생각합니다. 그리고 <textarea>
적용되지 않습니다.
isIOS 변수는 다음과 같이 확인할 수 있습니다.
const isIOS = navigator.userAgent.match(/ipad|ipod|iphone/i);
이것이 나를 위해 일한 것입니다. 코드는 모든 최신 브라우저에서 테스트되었으며 작동합니다.
function copyToClipboard(textToCopy) {
var textArea;
function isOS() {
//can use a better detection logic here
return navigator.userAgent.match(/ipad|iphone/i);
}
function createTextArea(text) {
textArea = document.createElement('textArea');
textArea.readOnly = true;
textArea.contentEditable = true;
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 copyTo() {
document.execCommand('copy');
document.body.removeChild(textArea);
}
createTextArea(textToCopy);
selectText();
copyTo();
}
The idea is to create a fake text area, add it to DOM, set contentEditable & readOnly as true. Create a range to select the desired element and add it to the window’s selection. Set the selection range for the entire element. And then run execCommand('copy'). You may notice a huge number (999999) inside setSelectionRange() method. Well, it is to cover anything that could be inside the element. Read more about range from MDN Docs: https://developer.mozilla.org/en-US/docs/Web/API/Range
Test run (works in the following device/browser combination)
iPhone (iOS >= 10) - Safari, Chrome
Android - Chrome, FF
Mac - Chrome, FF, Safari
Windows - Chrome, IE, FF
I have not mentioned versions specifically because I tested on the latest versions available to me at the time of writing this post. Here's a detailed write of the same: https://josephkhan.me/javascript-copy-clipboard-safari/
<input id="copyIos" type="hidden" value="">
var clipboard = new Clipboard('.copyUrl');
//兼容ios复制
$('.copyUrl').on('click',function() {
var $input = $('#copyIos');
$input.val(share_url);
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
clipboard.on('success', function(e) {
e.clearSelection();
$.sDialog({
skin: "red",
content: 'copy success!',
okBtn: false,
cancelBtn: false,
lock: true
});
console.log('copy success!');
});
} else {
$input.select();
}
//document.execCommand('copy');
$input.blur();
});
참고URL : https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios
'Development Tip' 카테고리의 다른 글
virtualenv에서 "matplotlib.pyplot을 plt로 가져 오기"할 수 없습니다. (0) | 2020.11.12 |
---|---|
정적 소멸자 (0) | 2020.11.12 |
npm 오류! (0) | 2020.11.12 |
XML을 생성하는 가장 좋은 방법은 무엇입니까? (0) | 2020.11.12 |
캡슐화 및 추상화를 이해하는 간단한 방법 (0) | 2020.11.12 |