はじめに
やりたいこと
サムネイル画像をクリックしたら、ページ遷移せずに元画像を上からかぶせるようにプレビュー表示する。
制限事項
- 元画像が別ドメインにあると、content_scriptsから取得できない。
- content_scriptsからページ内のイベントハンドラを上書きできない。
content_scriptsからページ内にscript要素を埋め込んで、ページ上でスクリプトファイルを実行する。
手順1:ページ内で読み込ませるスクリプトファイルを登録する
ページ内で読み込ませるスクリプトファイルを、manifest.jsonのweb_accessible_resources
に追加する。
"web_accessible_resources": [
"bower_components/jquery/dist/jquery.min.js",
"scripts/preview.js"
],
手順2:ページ内にscript要素を埋め込む
chrome.runtime.getManifest().web_accessible_resources
にて、スクリプトファイルの一覧が取得できる。これをchrome.extension.getURL()
でURLに変換し、script要素を生成する。
content_scripts.js
const scripts = chrome.runtime.getManifest().web_accessible_resources;
const next = () => {
let script = scripts.pop();
if (!script) {return;}
$('<script></script>', {
type: 'text/javascript',
src: chrome.extension.getURL(script),
on: {ready: next()}
}).appendTo('body');
};
next();
手順3:プレビューの実装
preview.js
//リンクをたどって元画像のURLを取得する
const getImageUrl = async (url) => {
...
return Promise.resolve(imageUrl);
};
//メインの処理
const initialize = () => {
//元画像を表示するコンテナを生成する
const container = $('<div></div>', {
id: 'PreviewContainer',
click: function(){
//クリックされたら非表示にする
$(this).hide();
//履歴を一つ戻る
window.history.back();
}
}).appendTo('body');
container.hide();
//サムネイルのリンクを無効にする
$('#ThumbnailContainer').on('click', 'a', false);
//サムネイル画像をクリックしたら元画像を表示する
$('#ThumbnailContainer').on('click', 'img', async function(){
//元画像のURLを取得
let imageUrl = await getImageUrl($(this).parent('a').attr('href'));
//元画像をコンテナの背景画像として表示する
let container = $('#PreviewContainer');
container.css('background-image', 'url(' + imageUrl + ')');
container.show();
//履歴を一件追加
window.history.pushState(null, null, null);
});
//戻るボタンが押されたら元画像を非表示にする
window.addEventListener('popstate', function (e) {
if (container.css('display') === 'block') {
$('#PreviewContainer').hide();
}
}, false);
};
//待機
const setTimeoutAsync = delay => {
return new Promise(resolve => {
setTimeout(resolve, delay);
});
};
//jQueryの読み込み待ち
const limit = 5;
const checkJquery = async (count) => {
if (!$ && count < limit) {
await setTimeoutAsync(100);
checkJquery(count++);
} else {
initialize();
}
};
checkJquery(0);
元画像をクリックするとプレビュー表示が消えるようにしたが、癖で戻るボタンのショートカットを実行してしまうことが多かったので、戻るボタンでもプレビュー表示が消えるようにした。