ただこのコードはiOS 10以降で動かなくなっている事に気付きました。 以下のコードエリアには同じスクリプトを適用してあるので、クリックして実際にコピーできるか確かめてみてください。
$('#pre1').click(function(){
var input = document.createElement('textarea');
document.body.appendChild(input);
input.value = this.innerText;
input.select();
document.execCommand('copy');
document.body.removeChild(input);
alert('copied!');
});
確認するのが面倒な方のために具体的にどのような問題が起きるか説明すると、 (1)クリックした瞬間にフォーカスがあらぬ方向に吹っ飛び、(2)クリップボードへのコピーもできない状態になります。
この時一体どのような事が起きているかというと、 (1)iOS 10以降ではtextareaが書き込み可能状態だとフォーカスが移ってしまい、 (2)textareaの編集が禁じられているため選択状態にできず、クリップボードへのコピーに失敗しているのです。
この問題を解決するにはそれらのオプションを解除する必要があります。 StackOverflow にドンピシャの回答があったので載せてみます。
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');
}
この関数を使うとJavaScriptでクリップボードにコピーするコードは以下のように書く事ができます。 以下のコードエリアには同じスクリプトを適用してあるので、クリックして実際にコピーできるか確かめてみてください。
$('#pre2').click(function(){
var input = document.createElement('textarea');
document.body.appendChild(input);
input.value = this.innerText;
copyToClipboard(input);
document.body.removeChild(input);
alert('copied!');
});
ところでdisplay none; を付ければフォーカスを移動せずに済むように思うかも知れませんが、 これはtextareaを選択状態にする事ができませんでした。 また文字列ではなく画像をクリップボードにコピーするのも駄目なようです。
StackOverflowを参照すれば解決できる問題ではあるのですが、 再び仕様が変化した時にどのように対応すれば良いのか思い出しやすいように記事にしてみました。 JavaScriptは時間が経つと急に動かなくなったりするので大変です…。
0 件のコメント:
コメントを投稿