コピーアイコン付きコードブロック
(ワンクリックでコピー)
Javascriptが苦手な私でもできました!
Javascriptが苦手な私でもできました!
コピーアイコン付きコードブロック(ワンクリックでコピー)
コードは、毎回ドラッグして範囲選択しなくても済むように、「コピー」ボタンをクリックするだけでコード全体をコピーできる仕組みを追加しました。
これが解決できればなあ-
必要なのはこの「3つだけ」
実装の全体像は、次の3ステップだけです。
正直なところ、JavaScriptは得意ではありません。しかし、
「.code-block という枠の中に、copy-btn クラスのボタンと <pre><code> がある」
というルールさえ守れば、あとは用意したコードをそのまま使い回せる「部品」になります。
そう考えると、少しがんばって導入する価値は十分にあると感じました。
コードブロックを決まった形でマークアップする
<button type="button" class="btn btn-sm btn-outline-secondary copy-btn">
コピー
</button>
<pre class="mb-0"><code>...</code></pre> </div>
ポイント
.code-block というdivを追加
その中に
- button.copy-btn(コピー用ボタン)
- <pre><code>…</code></pre>
という構成にするだけです。
今後、どのコードもこの「型」にしておけば、同じJSで全部コピーできます。
コードの右上にコピーボタンをつける
.code-block {
position: relative;
}
.code-block pre {
background-color: #f8f9fa; /* Bootstrapのbg-lightっぽい色 */
border: 1px solid #dee2e6;
border-radius: 0.5rem;
padding: 1rem;
font-size: 0.9rem;
}
.code-block .copy-btn {
position: absolute;
top: 0.5rem;
right: 1.5rem;
padding: 0.15rem 0.5rem;
font-size: 0.75rem;
}
見た目が整って、「右上に小さめの[コピー]ボタン」がついたコード枠になります。
JavaScript:コピペだけで動くコピー処理
</body>の直前あたりに入れます。
<script>
document.addEventListener('DOMContentLoaded', function () {
const copyButtons = document.querySelectorAll('.code-block .copy-btn');
copyButtons.forEach(function (button) {
button.addEventListener('click', function () {
const codeBlock = button.closest('.code-block');
const codeElement = codeBlock.querySelector('pre code');
// innerText でコードのテキストだけ取得
const textToCopy = codeElement.innerText;
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(textToCopy)
.then(function () {
const originalLabel = button.innerText;
button.innerText = 'コピーしました';
button.disabled = true;
setTimeout(function () {
button.innerText = originalLabel;
button.disabled = false;
}, 1500);
})
.catch(function (err) {
console.error('コピーに失敗しました:', err);
alert('コピーに失敗しました。すみません…');
});
} else {
// 古いブラウザ用の簡易フォールバック
const textarea = document.createElement('textarea');
textarea.value = textToCopy;
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
const originalLabel = button.innerText;
button.innerText = 'コピーしました';
button.disabled = true;
setTimeout(function () {
button.innerText = originalLabel;
button.disabled = false;
}, 1500);
} catch (err) {
console.error('コピーに失敗しました:', err);
alert('コピーに失敗しました。すみません…');
}
document.body.removeChild(textarea);
}
});
});
});
<script>
ポイント
やっていることは:
- ページが開いたら .code-block .copy-btn を全部探す
- ボタンがクリックされたら、そのボタンの一番近くの <pre><code>…</code></pre> を探す
- その中身をコピー
- 成功したらボタンの表示を一瞬「コピーしました」に変える
だけです。
理解しきれなくても
「.code-block という枠の中に copy-btn ボタンと <pre><code> がある」
というルールさえ守れば、ずっと使い回せる部品になります。
スマホでの表示
スマホでコードを確認しましたら、画面の右側にほんの少しだけ表示されているだけでした。ただ、下に「スクロール」が表示されていて、左から右へスワイプすると全体のコードを確認できます。
最初に画面を見たときは、メディアクエリでスマホの見え方は修正したほうがいいのかなと思いましたが、これが「今は標準仕様」だそうです。無理に折り返すより読みやすいということです。
最後にワンポイント
記事に HTMLコードを書くときの「 < 」と「 > 」の扱い
ここは間違えると コードが全部消えたり、ブログが壊れたり するところです。
つまり何をすればいいか(書き方)
普通の文章内で「 < 」と「 > 」を使う場合
絶対に変換する必要があります。
- 【NG】
- 【OK】
<pre><code> の中に書く場合
基本的に < > のまま書いてOK です。
なぜなら、 <pre><code> ブロックが
「これはコードですよ」とブラウザに伝える役割をするためです。
例
<pre><code><section id="hero" class="hero section light-background">
<div class="d-none d-md-block fv-hero position-relative">
...
</div>
</section>
</code></pre>