B-Teck!

お仕事からゲームまで幅広く

はてなブログのコードブロックをコピーできるようにする

ブログにコードブロックを置いたときに、コピーボタンがほしいとずっと思ってた。
N番煎じすぎるけど一応メモしておく。

コード

CSS

管理画面 > デザイン > デザインCSSに以下を追記する。

:root {
  --btn-bg: #2d2d2d;
  --btn-bg-hover: #3d3d3d;
  --btn-bg-copied: #4a4a4a;
}

pre.code {
  position: relative;
}

.copy-button {
  position: absolute;
  top: 4px;
  right: 4px;
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  background: var(--btn-bg);
  color: #fff;
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
  opacity: 0;
  transition: all 0.3s;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

pre.code:hover .copy-button {
  opacity: 1;
}

.copy-button:hover {
  background: var(--btn-bg-hover);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
}

.copy-button:active {
  transform: translateY(2px);
  box-shadow: none;
}

.copy-button.copied {
  background: var(--btn-bg-copied);
}

JavaScript

管理画面 > デザイン > フッタ のHTMLに以下を貼り付ける

<script>
  document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('pre.code').forEach(codeBlock => {
      const button = document.createElement('button');
      button.className = 'copy-button';
      button.textContent = 'Copy';

      button.addEventListener('click', async () => {
        const code = codeBlock.querySelector('code')?.textContent || codeBlock.textContent;
        const text = code.replace(/(Copy|✓ Copied)$/, '').trim();

        await navigator.clipboard.writeText(text);

        button.textContent = '✓ Copied';
        button.classList.add('copied');

        setTimeout(() => {
          button.textContent = 'Copy';
          button.classList.remove('copied');
        }, 2000);
      });

      codeBlock.appendChild(button);
    });
  });
</script>