はじめに
最近引っ越しを考えているのですが、気になるのが引っ越し先の回線速度です。
回線事業者のサイトで契約できるプランを調べることができるのですが、このとき郵便番号の入力が必要になります。
しかし、賃貸情報サイトには住所だけしか書かれておらず、郵便番号が簡単には分かりません。
そこで拡張機能の勉強も兼ねて、住所から郵便番号を調べるChrome拡張機能を作ってみました。
作成した拡張機能はこちらで公開しています。
使い方
実装
住所から郵便番号を調べる(逆引き)する処理はZIPCODAさんが公開しているWebAPIを使わせていただいています。
今回私が作成したのは上記のWebAPIを呼び出すためのUIだけです。
サイト読み込み時の処理
すべてのサイトに対してあらかじめ読み込み時に吹き出しのスタイルと閉じるボタンの処理を挿入します。
これはmanifest.json
で設定できます。
"content_scripts": [
{
"matches": ["<all_urls>"],
"css": ["main.css"],
"js": ["main.js"],
"all_frames": true
}
]
content_scripts
はサイトの読み込み時にCSSやスクリプトを挿入することを設定できます。(詳細な実行タイミングは公式ドキュメントを参照してください。)
matches
を<all_urls>
にするとすべてのサイトを対象にすることができます。
今回はmain.css
とmain.js
を挿入します。
main.css
main.css
には吹き出しのスタイルを記載しています。
吹き出しの作り方はサルワカさんを参考にさせていただきました。
#postal-code-lookup-balloon {
all: initial;
position: absolute;
display: inline-block;
margin-top: 1em;
padding: 7px 10px;
width: 300px;
color: #555;
font-size: 16px;
background: #fff;
border: solid 3px #555;
box-sizing: border-box;
z-index: 10000;
}
#postal-code-lookup-balloon:before {
all: initial;
content: "";
position: absolute;
top: -24px;
left: 15%;
margin-left: -15px;
border: 12px solid transparent;
border-bottom: 12px solid #fff;
z-index: 10002;
}
#postal-code-lookup-balloon:after {
all: initial;
content: "";
position: absolute;
top: -30px;
left: 15%;
margin-left: -17px;
border: 14px solid transparent;
border-bottom: 14px solid #555;
z-index: 10001;
}
挿入先のサイトで設定されているスタイルの影響を受けないようにするためall:initial;
でスタイルをリセットしています。
main.js
main.js
には吹き出しを削除する関数を記載しています。吹き出しのxボタンを押したときに呼び出します。
// 吹き出しを閉じる
const postalCodeLookupCloseBalloon = () => {
const oldballoon = document.getElementById("postal-code-lookup-balloon");
oldballoon?.remove();
};
右クリックメニュー選択時の処理
右クリックメニューから「郵便番号を逆引き」を選択するとbackground.js
のchrome.contextMenus.onClicked.addListener
が動きます。
// 右クリックメニュー選択時に実行
chrome.contextMenus.onClicked.addListener((info, tab) => {
// どの項目が選択されたのか判定
if (info.menuItemId === "lookup_postal_code") {
chrome.scripting.executeScript({
target: { tabId: tab.id },
func: () => {
(async () => {
// 選択範囲の座標を取得
const selection = document.getSelection();
const range = selection.getRangeAt(0);
const clientRect = range.getBoundingClientRect();
// すでに吹き出しが存在する場合、吹き出しを削除
const oldballoon = document.getElementById(
"postal-code-lookup-balloon"
);
oldballoon?.remove();
// 吹き出しを作成
const balloon = document.createElement("div");
// あらかじめ挿入してあるスタイルのIDを指定
balloon.id = "postal-code-lookup-balloon";
// 吹き出しの座標を選択範囲の直下に設定
balloon.style.left = `${window.scrollX + clientRect.x}px`;
balloon.style.top = `${
window.scrollY + clientRect.y + clientRect.height
}px`;
// 吹き出しの閉じるボタンを作成
const button = document.createElement("button");
button.className = "postal-code-lookup-balloon-button";
button.textContent = "x";
// あらかじめ挿入してある関数を指定
button.onclick = postalCodeLookupCloseBalloon;
balloon.appendChild(button);
// 結果表示用のdivを作成
const content = document.createElement("div");
content.className = "postal-code-lookup-balloon-content";
balloon.appendChild(content);
// ZIPCODA APIを実行
// https://zipcoda.net/doc
const address = selection.toString();
const params = new URLSearchParams({ address });
const res = await fetch(`https://zipcoda.net/api?${params}`, {
method: "GET",
});
if (res.ok) {
// 結果を吹き出しに追加
const data = await res.json();
for (const item of data.items) {
const zip1 = item.zipcode.substring(0, 3);
const zip2 = item.zipcode.substring(3);
const address = item.address;
const p = document.createElement("p");
p.className = "postal-code-lookup-balloon-p";
p.textContent = `${zip1}-${zip2}: ${address}`;
content.appendChild(p);
}
} else {
// エラーメッセージを吹き出しに追加
const data = await res.json();
console.error("postal-code-lookupエラー", data);
const p = document.createElement("p");
p.className = "postal-code-lookup-balloon-p";
p.textContent = data.message;
content.appendChild(p);
}
// 吹き出しをdomに追加
document.body.appendChild(balloon);
})();
},
});
}
});
感想
初めてChromeの拡張機能を作ってみて、Webの知識が少しあれば意外と簡単だということが分かりました。
手軽に便利なものが作れるためフロントエンドの勉強にちょうどいいと思います。