特定のサイト内を検索するブックマークレットの覚え書きです。
Googleのサイト内検索コマンド、
site:検索対象のサイト 検索ワード
を行うブックマークレット。
当初promptで作成。
(function () {
const hostname = location.hostname;
const text = window.prompt(hostname + "内を検索");
const space = "\u00A0";
const url =
"https://www.google.com/search?hl=ja&q=site:" +
hostname +
space +
encodeURIComponent(text);
window.open(url, "_blank");
})();
open()
が原因でブラウザのポップアップブロックが発生するためpromptでの作成を断念。
他にもユーザー入力には <dialog> 要素を使用することができます。
Window.prompt() - Web API | MDN
とのことなので、dialog
要素で作成。
概要
テンプレートリテラルで記述した<style>
や<dialog>
をhtml変換してbodyに挿入する。
ブログカード(カード型リンク)を作成するブックマークレットでやった手法を踏襲した。
既知の不具合
ダイアログのデザインはサイトのCSSが継承されると崩れる。
不足しているセレクターを補うか、優先度を上げることで対応。
条件分岐
文字列を選択しているかどうかを判定。
選択していなければdialog();
選択していればselectionString();
if (window.getSelection().toString() == "") {
dialog();
} else {
selectionString();
}
検索を実行する関数
location.hostname
で現在開いているURLのホスト名を取得。
location.hostname - Web API | MDN
ホスト名と検索ワードは"+"
で連結した。※
検索に支障のある特定の文字をencodeURIComponent()
でエンコード
encodeURIComponent() - JavaScript | MDN
function search(text) {
const hostname = location.hostname;
const url =
"https://www.google.com/search?hl=ja&q=site:" +
hostname +
"+" +
encodeURIComponent(text);
window.open(url, "_blank");
}
※半角スペースで連結する場合。
ブックマークレット作成サイトでは半角スペースが削除されるので、プログラム上で半角スペースを" "
とできなかった。
ブックマークレットに変換したあとで修正することもできるが、面倒なので半角スペースのCode Point\u{0020}
で半角スペースを明示した。
また、文字列リテラル中にはUnicodeエスケープシーケンスで、直接Code Pointを書くこともできます。 Code Pointは\u{Code Pointの16進数の値}のようにエスケープシーケンスとして記述できます。
文字列とUnicode · JavaScript Primer #jsprimer
JavaScript なスペースのあるHTMLの扱い - かもメモ
半角スペースをつかったタイプは以下。
function search(text) {
const hostname = location.hostname;
const space = "\u{0020}";
const url =
"https://www.google.com/search?hl=ja&q=site:" +
hostname +
space +
encodeURIComponent(text);
window.open(url, "_blank");
}
選択文字列を取得する関数
選択文字列をwindow.getSelection()
で取得
Javascript で選択されている文字列を取得するテスト。 getSelection メソッド使用。 – pulogu.net
for
で繰り返し処理※、window.getSelection()
の数はrangeCount
で取得。
※Firefoxは複数の文字列を選択可能なのでand検索ができる。
最後の+
記号をreplace(/\+$/, "")
で削除。
引数を渡してsearch関数を実行。
function selectionString() {
/** @type {string} */
let text = "";
/** @type {object} */
const selectionString = window.getSelection();
for (let index = 0; index < selectionString.rangeCount; index++) {
text += selectionString.getRangeAt([index]).toString() + "+";
}
text = text.replace(/.$/, "");
search(text);
}
選択文字列の連結に+
をつかった。
Google search: 演算子によって検索結果が微妙に違ってくる。 - GGCS ごたごた気流調査所
選択文字列の連結に半角スペースをつかったタイプは以下。
trimEnd()
で最後のスペース(\u{0020}
)を削除。
function selectionString() {
/** @type {string} */
let text = "";
const space = "\u{0020}";
/** @type {object} */
const selectionString = window.getSelection();
for (let index = 0; index < selectionString.rangeCount; index++) {
text += selectionString.getRangeAt([index]).toString() + space;
}
text = text.trimEnd();
search(text);
}
ダイアログを表示する関数
検索ワードを入力後、OKボタンで検索を実行する方法の他に、
検索ワードを入力後、Enterキーを押しても検索を実行させたかったので、dialog
要素とform
要素を連携する。
HTMLでダイアログを表現する | 前編 dialog要素の基本
HTMLのdialog要素とフォーム機能 - Hatena Developer Blog
JavaScriptでEnterキーが入力された時にSubmitする方法と無効化する方法を現役エンジニアが解説【初心者向け】 | TechAcademyマガジン
<dialog>: ダイアログ要素 - HTML: HyperText Markup Language | MDN
ダイアログを閉じるにはCancelボタンをクリック、またはダイアログにフォーカスがあればEscapeキー。(Escapeキーで閉じるのは仕様)
検索結果は別タブで開く。
window.open(url, "_blank");
HTMLの挿入位置を</body>
の上にした。
/** ダイアログの要素をHTMLとしてbodyに挿入 */
document.body.insertAdjacentHTML("beforeend", dialogElm);
afterbegin
、beforebegin
でもいいと思う。
innerHTML より insertAdjacentHTML を使う - Qiita
input要素にautofocus属性を明示した。
<dialog>内でautofocus属性がほぼ必須になる話
input要素の履歴を表示しない。
HTML 属性: autocomplete - HTML: HyperText Markup Language | MDN
検索を実行、またはCancelボタンのクリックでaddEventListener()
のclose
イベントを実行、dialog要素を削除。
dialog.addEventListener("close", function () {
dialog.remove();
});
HTMLDialogElement: close イベント - Web API | MDN
style
要素もdialog
要素の中にあるので同時に削除される。
CSSはプロパティ値をブラウザの初期値(ユーザーエージェントStyleSheet)に戻す?revert
を使用した。(理解不足)
Windows版の
- Chrome 113.0.5672.127
- Firefox 113.0.1
で確認。
コメントなし:
コメントを投稿