みっちぇのWebデザイン研究所

はてなブログのカスタマイズを中心に、ウェブデザインについて研究するブログ

コード横にコピーボタンを設置する方法【コピペでOK!】

最終更新:2021年11月12日

f:id:micche-labo:20211112115933j:plain

こんにちは。久しぶりにJavaScriptの記事です。
長ったらしいコードを手でコピーするのはなかなか大変だと思って、ずっと実装したかったコピーボタンの設置をしました。

コピペで是非どうぞ!

コードエリアにコピーボタン設置

全部記事を手直しするのは大変かつ面倒なので、JavaScriptを使用して一気に処理します。
判別用のidを付与し、pre分forEachで繰り返してボタンを設置します。
ツールチップ(クリック時に表示)は時間経過で消えるように設定します。

JavaScript

2021.11.12 コードをwindow.onload = function(){};addEventListener('DOMContentLoaded',function(){},!1)に変更しました。

<script type="text/javascript">
// DOMをロードしたら読み込み
addEventListener('DOMContentLoaded', function () {

//記事部分取得
const entryContent = document.getElementsByClassName('entry-content');

if (entryContent) {
  // pre取得
  const preArea = document.querySelectorAll(".entry-content > pre");

  // 繰り返し処理
  preArea.forEach((pre, index) => {
  // preにid付与
  pre.setAttribute("id", "copyArea");
  // btn作る
  const copyBtn = document.createElement("button");
  copyBtn.setAttribute("id", "copybtn"); //id付与
  copyBtn.textContent = "コピー"; //テキスト挿入
  pre.insertAdjacentElement("beforebegin", copyBtn);//copyBtn挿入

  // pre内テキスト取得
  const copyText = pre.textContent;

  // copy関数
  function copy() {
    navigator.clipboard.writeText(copyText).then(function () {
      // コピーに成功した場合の処理
      copyBtn.classList.add("toolChip"); //ツールチップ用クラス付与

      // 時間経過でツールチップ非表示
      setTimeout(() => {
        copyBtn.classList.remove("toolChip");
      }, 1500);
    });
  }

  // ボタンクリックで、上で定めたcopy関数実行
  copyBtn.addEventListener("click", copy);
  });
 }
}
}, !1);
</script>

設置場所

デザイン設定 => カスタマイズ => ヘッダ => タイトル下 にペーストしてください。

コピーボタンとツールチップのデザイン・位置調整

コピーボタンをpreエリアの右上に設置したようみせかけるためのcssです。
今回、preエリアをdivタグで囲ったりしていないので、位置調整はmarginでしています。
ブレイクポイントを設けて、デバイスで見たときにボタンが変な位置にこないよう調整はしていますが、全てのデバイスで確認しているわけではないのでご了承くださいませ。

CSS

/*preエリア*/
.entry-content pre {
    white-space: pre;
    text-overflow: inherit;
    overflow-y: scroll;
    word-wrap: normal;
    line-height: 1.3;
    font-size: 0.8rem;
    padding: 2.2em 1em .6em;
    margin: 2em auto;
    position: relative;
    background: #ffffff;
    border: none;
    width: auto;
    max-width: 600px;
}
/*コピーボタン*/
button#copybtn {
    display: block;
    position: relative;
    font-size: 0.8em; /*文字サイズ*/
    border: none; /*デフォルトの枠消す*/
    margin-bottom: -4.3em; /*位置調整*/
    margin-left: auto; /*右寄せ*/
    z-index: 1; /*重なり順。preエリアの上に被せる*/            
    height: 30px; /*ボタンの高さ*/
    cursor: pointer; /*カーソルをポインターに*/
    /*トランジションの設定*/
    -webkit-transition: all 0.3s ease;
    transition: all 0.3s ease;
}

/*PCでの見た目*/
@media screen and (min-width: 1200px) {
    button#copybtn {
        margin-right: 7.5em; /*位置調整*/
        opacity: .6; /*ホバー前は透け感あり*/
    }
    button#copybtn:hover {
        opacity: 1; /*ホバーで透け感なし*/
    }
}

/*ツールチップ*/
button#copybtn.toolChip::after {
    content: "コピーしました!"; /*ツールチップ内の文字*/
    font-size: 0.7rem; /*文字サイズ*/
    position: absolute;
    display: inline-block;
    width: 100px; /*横幅*/
    height: 30px; /*縦幅*/
    line-height: 30px; /*高さと揃える*/
    /*位置調整*/
    bottom: -130%;
    right: 100%;
    -webkit-transform: translateX(50%);
            transform: translateX(50%);
    background: #bfeaf5; /*背景色*/
    border-radius: 4px; /*角を丸める*/
    /*影をつける*/
    -webkit-box-shadow: 0 1px 2px -1px rgba(0, 89, 255, 0.144), 0 2px 4px -2px rgba(0, 132, 255, 0.116);
            box-shadow: 0 1px 2px -1px rgba(0, 89, 255, 0.144), 0 2px 4px -2px rgba(0, 132, 255, 0.116);
}

button#copybtn.toolChip::before {
    /*吹き出しの三角部分*/
    border: 8px solid transparent;
    border-bottom: 8px solid #bfeaf5;
    /*位置調整*/
    position: absolute;
    right: 100%;
    -webkit-transform: translateX(50%);
            transform: translateX(50%);
    bottom: -10px;
    /*中身はなし*/
    content: "";
}

設置場所

デザイン設定 => カスタマイズ => デザインCSS に貼り付けてください。
すでにいろいろ文字が入っていると思うので、その下に追加してください。

おまけ:htmlとかcssとかバッジ表示したいとき

::beforeでつけられます。
はてなブログdata-langというカスタムデータがつくので、それを参照してcssを設定してあげると、文字とデザインが設定できます。

.entry-content pre::before {
    display: inline-block;
    position: absolute;
    height: 1.4em;
    line-height: 1.4em;
    padding: 0.2em .6em;
    top: 0;
    left: 0;
    content: attr(data-lang);
    background: #ddd;
}

.entry-content pre[data-lang="html"]::before {
    background: #f39800;
}

.entry-content pre[data-lang="sass"]::before {
    background: #f078a2;
}

.entry-content pre[data-lang="css"]::before {
    background: #ffdf88;
}

.entry-content pre[data-lang="javascript"]::before {
    background: #75c9e4;
}

.entry-content pre[data-lang="php"]::before {
    background: #75c9e4;
}

.entry-content pre[data-lang="sh"]::before {
    background: #ddd;
}

まとめ

たぶんこれで、当ブログとおなじような動きになると思います。
ただ、JavaScriptで一旦webページが全て読み込み切ってからボタン生成を行うので、すぐにボタンが表示されないのが痛いところ…

余力ある方はボタン手動で付けた方がよいかもです。

2021.11.12 コード修正しました。
ページ全部読み込んでから作る方法だと重たくて耐えれなかったので、DOMツリーを読み込んだら表示する方法に変更しました。

詳細はMDN Web Doc参照。

Window: DOMContentLoaded イベント developer.mozilla.org