範囲選択した文字列をクリップボードにコピーするブックマークレット(JavaScript)

今回は、ふだん私が使っている「Webページ内の範囲選択した文字列をクリップボードにコピーするブックマークレット」(JavaScript)を紹介します。同様のブックマークレットを探したのですが、見つからなかったので。あと、範囲選択した文字列の取得方法なども見つけるのが大変だったので、同じようなスクリプトの作成で困っている・悩んでいる方の参考になれば幸いです。


このブックマークレットは、範囲選択した文字列に加え、コピーした日時・ページタイトル・ページアドレス(URL)およびリンクタグも自動的に作成します。利用イメージは以下の通り。

ブックマークレットの利用イメージ(1)
ブックマークレットの利用イメージ(1)

ブックマークレットの利用イメージ(2)
ブックマークレットの利用イメージ(2)


もともとIE10で使っていたブックマークレットを、IE11用に修正したもの。しかし他のブラウザでも確認したところ、Google Chrome や Firefox 、Opera、Sleipnir でも動作しました。OSは Windows 7 Home Premium SP1 です。Windows 8 や Windows 10でも動作するかどうかは不明です。

また「Webページによっては正常に動作しない」場合もあります。あらかじめご了承ください。

なお、ブックマークレットの登録方法などは省略いたします。ブックマークレットの使用方法が分かっていらっしゃる方向けの内容、ということで。

※ちなみに iPhone、iPod touch、iPadなど iOS の Safari でも一応、動作はしますが、コピーは不可。あとサイズなど合わなかったりもするので、今回は iOS 非対応ということで。



さて、簡単に登録したい場合は、以下のリンクをお気に入りバー(IE)やブックマークバー(Chrome、Opera)、ブックマークツールバー(Firefox)などにドラッグ&ドロップしてください。

メモJS


ブックマークレットのJavaScriptの記述は以下の通り(すべて1行で。改行なし):


※「var re=/す: .*/;var DT=D.title.replace(re,"す:");」の部分は、ツイッターのツイートページ対策です(なぜかタイトルに本文も含まれてしまうため)。気になる方は「var DT=D.title;」と置き換えてください。


以下、今回のブックマークレットの核心部分となる、「範囲選択した部分の取得方法について」の簡単な解説です。

1)(通常部分の)範囲選択した部分を取得する
IE10では、範囲選択した部分を取得する場合「var str = document.selection.createRange();」として、取得できました。

しかし、IE11からは「selection」オブジェクトが廃止。代わりに「getSelection()」メソッドを使用する仕様に変更されました。
IE11 の互換性の変更点 (Windows)

ということでIE11では、範囲選択した部分を取得する場合「var str = window.getSelection();」として、取得することになります。


2)フォームのinput要素やtextarea要素の中の範囲選択された文字列を取得する
しかし「var str = window.getSelection();」の方法では、フォームのinput要素やtextarea要素の中の範囲選択された文字列が取得できません。

では、フォームのinput要素やtextarea要素の中の範囲選択された文字列を取得する方法は? 結論からいうと、以下のような記述となります。

var form_focused_elm = document.activeElement;if( !!form_focused_elm.value ){STR = form_focused_elm.value.substring( form_focused_elm.selectionStart, form_focused_elm.selectionEnd );}

[1] document.activeElement でフォーカスが当たっている要素を取得
[2] フォーカスが当たっている要素に「値」があるかを判定。ちなみに「if( form_focused_elm.value )」では、なぜか値がない(空っぽ)の場合も「真」と判定される場合(またはブラウザ)があるので、「if( !!form_focused_elm.value )」としています。
[3] 「値」があれば、範囲選択の先頭と末尾をチェックして、文字列を取得する


というわけで、1)と2)をまとめると、以下のようになります。

//範囲選択した部分を変数 STR に代入する
var STR="";var SEL=window.getSelection();if(SEL!=""){STR=SEL.toString();}else{var form_focused_elm= document.activeElement;if( !!form_focused_elm.value ){STR = form_focused_elm.value.substring( form_focused_elm.selectionStart, form_focused_elm.selectionEnd );}}


※なお、このスクリプトはブックマークレットのみ有効なので、ご注意を。テストページを作成して「ボタンをクリック」するなどして試そうとすると、「フォームのinput要素やtextarea要素の中の範囲選択された文字列の取得に失敗」します。というのも、ボタンをクリックした時点で「ボタンにフォーカスがあたってしまう」ためです(最初、これに気づかず、時間をロスしました……)。



最後に、今回のブックマークレットを作成するにあたり、参考になったWebページを紹介しておきます(感謝!)
window.getSelectionの仕様にハマる | 生涯一馬鹿で行こう!
JavaScriptでフォーカスのあたっている要素を取得する「document.activeElement」: 小粋空間
CodePen - Use execCommands to edit HTML content in your browser


> コメントを閲覧・投稿する(現在 0 )

コメント

コメントの投稿