ブックマークレットでブラウザに便利機能を追加してみよう

```ブックマークレット```という単語をご存知でしょうか？  
「ブックマーク」に似ていますよね！

このブックマークレットはブラウザのブックマーク機能を使って

* 選択した文字をクリックひとつで翻訳
* サイトのOGPを確認する
* 閲覧しているサイトのQRコード作成

などの便利機能をブラウザ追加することができます。

今回はこのブックマークレットが

**どんなことができるのか？**  
**どのように使用するのか？**  
**ブックマークレットの使用例**

についてご紹介したいと思います！

## ブックマークレットとは
>ブックマークレット (Bookmarklet) とは、ユーザーがウェブブラウザのブックマークなどから起動し、なんらかの処理を行う簡易>的なプログラムのことである[注釈 1]。携帯電話のウェブブラウザで足りない機能を補ったり、ウェブアプリケーションの処理を起動す>る為に使われることが多い。
[ブックマークレット - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%AC%E3%83%83%E3%83%88)

ブックマークレットとは、ブラウザのブックマーク機能のURL部分にプログラミング言語のJavaScriptで作られたプログラムを追加することで、ブックマークのクリックひとつでプログラムの処理を呼び出せる機能のことです。

## ブックマークレットと拡張機能の違い

ブックマークレットと似ている機能に、ブラウザ拡張機能があります。  
どちらもWebブラウザで使える便利な機能です。  
拡張機能を使用したことがある人は多いのではないのでしょうか？  
ブックマークレットは拡張機能と比べてどのような違いがあるのかというと

* クリックするだけで実行できる
* どんなブラウザでも実行できる
* ブックマークとして管理できる

という特徴があります。

## ブックマークレットの使い方

### ▼ブックマークレットの登録と実行方法
1. ブックマークバーで右クリック
2. ブックマークを追加する
3. ブックマーク追加画面のURL欄にJavaScriptのプログラムを追加
4. 追加されたブックマークレットをクリックしてプログラムを実行する

今回は例としてこちらのサンプルコードをブックマークレットに登録してみましょう！
```javascript
javascript: (function () {
  alert('ブックマークレット追加完了！');
})();
```

```javascript:```からコードを始めることでブラウザがブックマークレットということを認識してくれます。

![bSd5bZ36GLo1WQ2BA2qCiBaHHfRbJ9145tfiDMhy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667673/95762c4e-db3e-7752-a77c-779477c5355b.png)
![NHbgYoFywqd5vGnRy4dOgReA7t8rDM7pQyuSUqoZ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667673/fa0480e0-636e-152b-f876-3203686c5901.png)
![NLZ9rt3nVnY0uZUyg6GakuuzTWOeShBDKV3hdbng.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667673/6cbcf6aa-689d-1afe-ea4b-bc8d8266b7d5.png)
![Rig6xaMK0hfNTFRHj6Hhsqmp7NczZSkQPsqWubIr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667673/666f9603-3933-ef61-14f9-750de2d7e10b.png)

追加できたらブックマークレットをクリックして実行してみましょう。  
アラートが表示されればブックマークレットの登録は完了です！

## ブックマークレットを実際に作ってみました

### ▼選択した英語をクリックひとつでDeepL翻訳

```javascript
javascript: (function () {
  const selectedText = window.getSelection().toString();
  window.open(`https://www.deepl.com/translator#en/ja/${selectedText}`, '_blank');
})();
```

### ▼閲覧しているサイトの目次を生成

* hタグごとに目次を生成
* ページ内遷移リンクを生成

![スクリーンショット 2023-05-16 15.07.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667673/b46a5520-5f85-352c-5871-9752807c1f46.png)

（コードの質は気にしないでください。。。）
```javascript
javascript:(
  function(){
    function headingCheck() {
      let headingElements = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
      headingElements.forEach((element, index) => {
        let elementId = element.getAttribute('id');
        if (elementId) {
        } else {
          element.setAttribute('id', `heading${index}`)
        }
        tableItemDisplay(element);
      });
    };

    /* 画面内結果表示 */
    function tableContentDisplay() {
      const removeTag = document.getElementsByClassName('tableContent');
      if (removeTag.length !== 0) {
        removeTag.item(0).remove();
      };

      const bodyElement = document.getElementsByTagName('body').item(0);
      let tableContent = document.createElement('div');
      tableContent.classList.add('tableContent');
      tableContent.style.position = 'fixed';
      tableContent.style.zIndex = '9999';
      tableContent.style.top = "70px";
      tableContent.style.right = "0";
      tableContent.style.width = "100%";
      tableContent.style.maxWidth = "350px";
      tableContent.style.color = '#333';
      tableContent.style.backgroundColor = '#fff';
      tableContent.style.border = '3px solid #333';
      tableContent.innerHTML = `
      <ul></ul>
      <div class="close_btn">Close</div>
      `;
      bodyElement.appendChild(tableContent);
      const close_btn = document.querySelectorAll('.tableContent .close_btn').item(0);
      close_btn.style.cursor = 'pointer';
      close_btn.style.boxSizing = 'border-box';
      close_btn.style.width = '100%';
      close_btn.style.padding = '12px';
      close_btn.style.fontSize = '18px';
      close_btn.style.textAlign = 'center';
      close_btn.style.lineHeight = '1';
      close_btn.style.color = '#fff';
      close_btn.style.backgroundColor = '#333';
      close_btn.addEventListener('click', function() {
        tableContent.style.display = 'none';
      });
    };

    function tableItemDisplay(element) {
      const tableContent = document.querySelectorAll('.tableContent ul').item(0);
      tableContent.style.overflow = 'auto';
      tableContent.style.maxHeight = '500px';
      tableContent.style.margin = '0';
      tableContent.style.padding = '5px 0';
      let tableItem = document.createElement('li');
      tableItem.style.display = 'block';
      tableItem.style.boxSizing = 'border-box';
      tableItem.style.width = '100%';
      tableItem.style.minWidth = '300px';
      tableItem.style.fontSize = '12px';
      tableItem.style.fontWeight = 'bold';
      tableItem.style.backgroundColor = '#fff';
      let tagName = element.tagName;
      let tagNumber = tagName.replace('H', '');
      tableItem.style.padding = `5px 10px 5px ${10 * Number(tagNumber)}px`;
      tableItem.innerHTML = `<a href="#${element.getAttribute('id')}">${element.tagName} ${element.innerText}</a>`;
      tableContent.appendChild(tableItem);
    };

    tableContentDisplay();
    headingCheck();
  }
)();
```

## ブックマークレットの使用例

* 閲覧中サイトのPage Speed Insightsで計測
* 閲覧中サイトのOGPを確認する
* 横スクロールが発生する原因を特定する
* 閲覧しているサイトのQRコード作成
* マークダウン形式でサイトのタイトル+URLをコピーする

## まとめ

ブックマークレットでできることはJavaScriptを使ってできることです。  
ブラウザ拡張機能を作るのはちょっと敷居が高いなと感じる方は、
ぜひ、自分のブラウザに機能を追加してみて作業効率化や半自動化の1歩目をブックマークレットから初めてみるのはいかかでしょうか！