Posted at

Chrome拡張機能:サムネイルをクリックしたらページ遷移せずに元画像を表示する

More than 1 year has passed since last update.


はじめに


やりたいこと

サムネイル画像をクリックしたら、ページ遷移せずに元画像を上からかぶせるようにプレビュー表示する。


制限事項


  • 元画像が別ドメインにあると、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);


元画像をクリックするとプレビュー表示が消えるようにしたが、癖で戻るボタンのショートカットを実行してしまうことが多かったので、戻るボタンでもプレビュー表示が消えるようにした。