code ブロックに「コピーボタン」を設置する

はじめに

  • 技術系ブログなどで、<code> ブロックに「コピーボタン」が設置されていることがある
  • コピーボタンは便利だ
  • ここ などを参考にして、Javascript で実装した

作業環境

  • Hugo で生成した HTML コードに対して動作を確認した
    • 他の静的 HTML ジェネレータの場合、querySelectorの部分を変える必要があるかも

コピーボタン

  • <code class="highlight">...</code> というコードブロックがあり、その内容をクリップボードにコピーする Javascript は次のとおり
function createCopyButton(highlightDiv) {
  const button = document.createElement("button");
  button.className = "copy-code-button";
  button.innerText = "Copy";
  button.addEventListener("click", () => copyCodeToClipboard(button, highlightDiv));
  highlightDiv.appendChild(button);
}

async function copyCodeToClipboard(button, highlightDiv) {
  const codeToCopy = highlightDiv.querySelector("pre.chroma > code[data-lang]").innerText.replace(/\n\n/g,"\n");
  await navigator.clipboard.writeText(codeToCopy).then (() => {
    button.blur();
    button.innerText = "Copied!";
    setTimeout(function() {
      button.innerText = "Copy";
    }, 2000); 
  });
}

document.querySelectorAll(".highlight")
  .forEach(highlightDiv => createCopyButton(highlightDiv));
  • コピーボタンのデザインを決める css コードは次のとおり
    • このコードを style.css などに追加する
.highlight {
  position: relative;
}

.copy-code-button {
  position: absolute;
  z-index: 2;
  right: 0;
  top: 0;
  font-size: 13px;
  font-weight: 700;
  line-height: 14px;
  letter-spacing: 0.5px;
  width: 65px;
  color: var(--text-color);
  background-color: var(--grey);
  border: 1px solid var(--black02);
  border-top-left-radius: 0;
  border-top-right-radius: 5px;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 5px;
  white-space: nowrap;
  padding: 4px 4px 5px 4px;
  margin: 0 0 0 1px;
  cursor: pointer;
  opacity: 0.5;
}

.copy-code-button:hover,
.copy-code-button:focus,
.copy-code-button:active,
.copy-code-button:active:hover {
  opacity: 0.8;
}

.copyable-text-area {
  position: absolute;
  height: 0;
  z-index: -1;
  opacity: .01;
}

.highlight .copy-code-button {
  visibility: hidden;
}

.highlight:hover .copy-code-button {
  visibility: visible;
}

さいごに

  • このサイトにも設置できた
print("Hello World")
Posted :