BETA

ブックマークレット作成のイロハ

投稿日:2018-12-18
最終更新:2019-04-18

記事を大幅アップデートしました。

はじめに

ブックマークレットに関して持っている知識をまとめてみようと思い立ちました。
最近あまり作ったりしていないんですが…。

ブックマークレットとは

ユーザーがウェブブラウザのお気に入りなどに設置されたブックマークレットをクリックすると、ブックマークレットに記述されたJavaScriptの小さなプログラムが、ウェブブラウザで起動する。
ブックマークレット - Wikipediaより

javascript:から始まるURIがあり、HTML内で以下のように用いることができます。

<a href="javascript:(()=>{alert('Hey!')})()">Say</a>    

このURIをブックマークに登録し、そのブックマークをクリックすることで、javascript:に続くスクリプトがそのページで実行される、というものです。
Webブラウザのコンソールで実行するイメージです。

何ができる?

コンソールでできるJavaScriptを用いたことなら基本的に何でもできると思います。
Webページのデータを参照することも、書き換えることもできます。

外部のAPIを用いることもできますが、やったことないので詳しくはわかりません。

テンプレート

javascript:(()=>{/* ここに書きます */})()  
// 全体を即時関数で包むことで、Webページの変数を上書きしないようにしています  

// jQueryを用いたページで、  
javascript:const $ = 'ほげ?';  
// とかしたら大変です。  

// ただの即時関数なので、下のように引数をもたせることもできます  
javascript:((str)=>{ alert(str) })('HOGE')  

配布したりするときのために、<script src="path.js"></script>をHTMLに追加して、path.jsにスクリプトを書くという方法もあるらしいです。

実例

以下、見やすいようにインデントを付けていますが、実際は1行で、空白もエスケープします。
(最近のWebブラウザならエスケープは自動でやってくれると思うけど)。

WebページへのMarkdown形式のリンクを取得

javascript:(()=>{  
    prompt(  
        'コピーしてください',  
        `[${document.title}](${location.href})`  
    )  
})()  

window.prompt('', 'コピーさせたい文字列')は出力の定番だと思います。

Webページの画像を列挙

javascript:(()=>{  
    open().document.body.innerHTML = ''  
        + '<ol>'  
        + [...document.getElementsByTagName('img')]  
            .map(v => v.src)  
            .map(v => [ v, new URLSearchParams({ 'image_url': v }) ])  
            .map(v => `  
                <li>  
                    <a href="${v[0]}" target="_blank"><img src="${v[0]}"></a>  
                    <a href="https://www.google.co.jp/searchbyimage?${v[1].toString()}" target="_blank">Google画像検索</a>  
                </li>  
            `)  
            .join('')  
        + '</ol>'  
})()  

getElementsByTagNameで画像を取得し、スプレッド構文で配列にし、map()で加工していきます。

列挙するだけだと面白みがないので、Google画像検索へのリンクも貼り付けておきました。
そのための、new URLSearchParamsです(めっちゃ便利)。

open()はwindowが返ってくるので、そのまま.documentとつないでしまっています。

検索ツール

javascript:((def, engines) => {  
  const searchTerms = prompt('検索語句を入力してください…');  

  if (searchTerms !== null) {  
    const select = prompt('検索するサイトをニックネームでお呼び出しください…').trim() || def;  
    select  
      .split(/\s/)  
      .map(v => engines[v] || '')  
      .filter(v => v)  
      .map(v => v.replace('{}', encodeURIComponent(searchTerms.trim())))  
      .forEach(v => { open(v, '_blank') })  
      ;  
  }  
})(  
  ':gg',  
  {  
    'gg': 'https://www.google.com/',  
    'wk': 'https://ja.wikipedia.org/wiki/',  
    'qi': 'https://qiita.com/',  
    'qr': 'https://qrunch.io/',  

    ':gg': 'https://www.google.com/search?q={}',  
    ':wk': 'https://ja.wikipedia.org/w/index.php?search={}',  
    ':qi': 'https://qiita.com/search?q={}',  
    ':qr': 'https://qrunch.io/search?q={}',  
  }  
)  

この記事で作ったものの改良版(というより簡略版?)です。

window.prompt()は入力にも便利です。
また、即時関数の引数として検索エンジン等のデータを書くことで、見やすくなっています。

Webページとの競合

気づかれたかもしれませんが、どのブックマークレットでも、Webページを編集していません。
というのも、Webページとの競合がめんどうなのです。

例えば、

<!DOCTYPE html>  
<meta charset=utf-8>  
<title>Hello, World!</title>  
<style>  
    p {  
        display: none !important;  
    }  
</style>  
<body lang=ja>  
    <h1>Hello, World!</h1>  
    <p>こんにちは、世界!</p>  

というWebページで、

javascript:(()=>{document.body.innerHTML += `<p>${prompt()}</p>`})()  

というブックマークレットを起動させるとします。
…何が起こるか、わかりますよね。

<p>を追加はしても、表示されません。
表示もするには、style="display: block !important;"としなければなりません。

…。
やってられるか!

javascript:(()=>{  
    const $ifr = document.createElement('iframe');  
    $ifr.style.cssText = `  
        position: fixed;  
        top: 0;  
        left: 0;  
        z-index: 999;  

        height: 100vh;  
        width: 100vw;  

        background-color: white;  
        border: none;  
    `;  
    document.body.appendChild($ifr);  

    $ifr.addEventListener('load', () => {  
        $ifr.contentDocument.body.innerHTML += `<p>${prompt()}</p>`;  
    })  
})()  

(Google Chromeでは動きません)。

…やってられるか!

おわりに

世の中の人はどうやって作ってるんでしょうね(半ギレ)。
あとで追記するかもです。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@okayuの大して技術的ではないブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!