[解決済み] iOSでJavascriptを使用してクリップボードにコピーする
質問
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
になることはありません (試すことはできますが、これはどこにも文書化されていない正式な方法です)。 - 要素内のテキストは選択範囲内でなければなりません。
これら4つの"要件"をすべてカバーするには、以下のようになります。
-
コピーするテキストを
<input>
または<textarea>
要素を使用することができます。 -
の古い値を保存します。
contenteditable
とreadonly
をコピーした後、それらを復元できるようにするためです。 -
変更
contenteditable
をtrue
でありreadonly
からfalse
. - を作成します。 の範囲 を使用して目的の要素を選択し、ウィンドウの選択範囲に追加します。
- を設定します。 の選択範囲 を要素全体に対して設定します。
-
以前の
contenteditable
とreadonly
の値を指定します。 -
実行する
execCommand('copy')
.
これにより、ユーザーのデバイスのキャレットが移動し、目的の要素のすべてのテキストを選択し、自動的にコピーコマンドを発行します。ユーザーは、テキストが選択されていることを確認し、選択/コピー/貼り付けのオプションを持つツールチップが表示されます。
さて、これは少し複雑で、単にコピー コマンドを発行するには手間がかかりすぎるように見えるので、これが Apple が意図したデザイン選択であったかどうかは分かりませんが、誰にも分かりません... その間に、この は iOS >= 10 で動作しています。 .
このため この のようなポリフィルを使えば、このアクションを簡略化し、クロスブラウザに対応させることができます (ありがとうございます。 トスカン に感謝します)。
動作例
まとめると、必要なコードは以下のようになります。
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 バージョン
以下のように iOS 10 には、Safari のためにいくつかの制限 (これは実際にはセキュリティ対策です) があります。 クリップボードAPI :
-
発火する
copy
イベントを発生させ、有効な選択範囲とcut
とpaste
は、フォーカスされた編集可能なフィールドでのみ使用されます。 -
ショートカットキーによる OS のクリップボードの読み書きをサポートするだけであり
document.execCommand()
. ショートカット キーとは、クリック可能なキー (例: コピー/貼り付けのアクション メニュー、iOS のカスタム キーボード ショートカット) または物理キー (例: 接続された bluetooth キーボード) を意味することに留意してください。 -
をサポートしません。
ClipboardEvent
コンストラクタをサポートしていません。
ということで、(少なくとも今の時点では) iOS デバイスで Javascript を使ってクリップボードのテキスト/値をプログラム的にコピーすることはできません。 . 何かをコピーするかどうかを決定できるのは、ユーザーだけです。
しかし、プログラム的に何かを選択することは可能です。
そのため、ユーザーは選択部分に表示される "コピー" ツールチップを押すだけでよいのです。これは上記と全く同じコードで実現でき、単に
execCommand('copy')
を削除するだけで、上記と全く同じコードで実現できます。これは確かにうまくいきません。
関連
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] ファイルのコピー方法について教えてください。
-
[解決済み] scpを使ってリモートからローカルにフォルダをコピーするにはどうしたらいいですか?
-
[解決済み】JavaScriptの比較では、どちらの等号演算子(== vs ===)を使うべきですか?
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
-
[解決済み] Javascriptで動的に命名されたメソッドを呼び出すにはどうすればよいですか?
-
[解決済み] jqueryはjavascriptのライブラリなのかフレームワークなのか?[クローズド]
-
[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] クリックボタンでクリップボードにコピー
-
[解決済み] チェックボックスが選択されているかどうかを確認するjQuery
-
[解決済み] React js 親コンポーネントから子コンポーネントの状態を変更する
-
[解決済み] javascript includes() 大文字小文字を区別しない
-
[解決済み] コールバック地獄とは何か、RXはそれをどのように、そしてなぜ解決するのか?
-
[解決済み] Prototypeを使ってtextareaを自動サイズ調整するには?
-
[解決済み] Node.jsのES6クラスをrequireで作る
-
[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?
-
[解決済み] Chrome拡張機能:popup.htmlを強制終了させる
-
[解決済み] navigator.clipboardが未定義である