highlight.jsにコピー機能を追加し、<pre><code>タグ内のコードを
クリップボードにコーピーする「コピーボタン」を自動生成する + 行番号を付ける


highlight.js は、Webページ上に表示したソースコードなどに色を付ける(ハイライト)ためのJavaScriptライブラリです。
このライブラリにコピー機能を追加し、<pre><code>タグ内のコードをコピーするボタンを自動生成する方法および行番号を付ける方法を紹介します。
引用サイト:>highlight.jsにコピー機能を追加する方法>highlight.jsに行番号を追加する方法

1. highlight.jsおよびhighlight CSSの設置2. 自動でコピーボタン追加するjavascript3. CSSによるコピーボタンの装飾
4. <pre><code>タグコード5. これまでのHTMLまとめ

<pre><code>タグ内コードをコピーするコピーボタンの自動生成および行番号を付ける方法

<pre><code>タグ内コードをコピーするコピーボタンの自動生成および行番号を付ける手順はつぎのとおりです。

1. highlightjsのjsファイルおよびCSSファイルの設置

highlightjsのjsおよびCSSファイルをcdnjsを利用し、<head>内に配置します。 合せて、highlight.jsを初期起動します。

<!-- highlightjs 本体 -->
<link rel="stylesheet"
      href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/highlight.min.js"></script>
<script>
 hljs.initHighlightingOnLoad(); //highlight.js初期起動
</script>

行番号を付けたい場合は、つぎのhighlightjs-line-numbersJSファイルを追加します。
合せて、highlightjs-line-numbers.jsを初期起動します。

<!-- hilightjs 行番号js -->
<script src="//cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.1.0/highlightjs-line-numbers.min.js"></script>
<script>
 hljs.initLineNumbersOnLoad();  //highlightjs-line-numbers.js初期起動
</script>

2. 自動でコピーボタン追加および行番号の付与javascript

つぎのコピーボタン追加Javascript を </ body>の直前に配置します。


            /*  コピーボタン追加および文字列のクリップボードにコピー プラグイン
                * querySelector等で取得した要素(element)を渡すと、
                * その要素の文字列をクリップボードにコピーします。
                * ユーザーが事前に選択していた内容には影響を与えません。
                * 戻り値はコピーが成功したかどうか(true/false)
            */
            let copyToClipboard = (element) => {
                let ranges = [];
                let selection = window.getSelection();
                let range = document.createRange();
                let result = false;
                for (let i = 0; i < selection.rangeCount; i += 1) {
                    ranges[i] = selection.getRangeAt(i);
                }
                range.selectNodeContents(element);
                selection.removeAllRanges();
                selection.addRange(range);
                result = document.execCommand("copy");
                selection.removeAllRanges();
                for (let i = 0; i < ranges.length; i += 1) {
                    selection.addRange(ranges[i]);
                }
                return result;
            };

            let body = document.querySelector("body");
            let active = [];
            body.addEventListener("click", (e) => {
                try {
                    const target = e.target;
                    if (!target.classList.contains('copy-button')) return;

                    const pre = target.closest("pre");
                    let result = false;
                    if (active.indexOf(target) !== -1) return;
                    if (pre) {
                        result = copyToClipboard(pre);
                        target.innerText = (result ? "COPIED!" : "FAILED!");
                        target.classList.add((result ? "success" : "failed"));
                        active.push(target);
                        setTimeout(() => {
                            let index = active.indexOf(target);
                            target.className = "copy-button";
                            target.innerText = "COPY";
                            if (index !== -1) active.splice(index, 1);
                        }, 2000);
                    }
                } catch (e) {
                    //error 
                }
            });
            hljs.addPlugin({
                'after:highlightBlock': ({ block, result }) => {
                    result.value = `${result.value}`;
                }
            });

行番号を付けたい場合はつぎの行番号Javascript を追加します。


/* 行番号プラグイン */
    hljs.addPlugin({
        'after:highlightBlock': ({ block, result }) => {
            result.value = result.value.replace(/^/gm,'<span class="row-number"></span>');
        }
    });

3. コピーボタンおよび行番号の装飾CSS

つぎのコピーボタンの装飾のCSSを、上記1.のhighlight.jsおよびhighlight CSSのつぎに配置します。


/* コピーボタン 装飾 */
pre{
    position:relative;
    margin-top:80px;
}
.copy-button{
    color:#888;
    font-size:.6rem;
    display:inline-block;
    padding:8px 16px;
    margin-right:20px;
    box-shadow:0px 2px 5px 0px rgba(0,0,0,0.16), 0px 2px 6px 0px rgba(0,0,0,0.12);
    border:2px solid #666;
    cursor: pointer;
    background-color: #fff;
    transition: all .2s ease;
    position:absolute;
    right:0;
    top:-20px;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    
}
.copy-button.success{border-color:#00C851;background-color:#c8e6c9;color:#007E33;}
.copy-button.failed{border-color:#ff4444;background-color:#ffcdd2;color:#CC0000;}
.copy-button:hover{
    box-shadow:0px 2px 5px 0px rgba(0,0,0,0.3), 0px 2px 10px 0px rgba(0,0,0,0.12);
}

行番号を付けたい場合はつぎの行番号装飾CSSを追加します。


/* 行番号 修飾 */
td.hljs-ln-numbers {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
 
    text-align: center;
    color: gray;
    border-right: 1px solid #FFcc66; /*#CCC;*/
    vertical-align: top;
    padding-right: 5px;
 
    /* your custom style here */
}
 
/* for block of code */
td.hljs-ln-code {
    padding-left: 10px !important;
}

4. コピー対象データ域を<pre><code>タグコードで記述

divタグで囲み<pre><code>タグコードを<body>内に記述します。
この<pre><code>タグコード内に、上記2.javascriptで、右下のようにコピーボタンが自動配置されます。
また、上記3.CSSでコピーボタンの装飾が行われます。
1ページ内に<pre><code>タグコードが複数配置しても、 コピーボタンはすべてに自動生成されます。


<div>
<pre><code  class="html">

.......

</code></pre>
</div>

<pre><code>タグ内コードのデホルトの表示例は、下図のとおりです。
好みにより、上記3. コピーボタンの装飾CSS(.copy-button)を変更しカスタマイズしてください。


図-1 <pre><code>タグ内コードのデホルトの表示例(行番号なし)


図-2 <pre><code>タグ内コードのデホルトの表示例(行番号付き)

<pre><code>タグ内コードの配置応用例として、jQuery ui タグメニュー内に配置することも可能です。


<!-- jQuery js css -->
<script src="https://code.jquery.com/jquery-1.12.4.min.js"integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">

<!-- jQuery ui tabs menu -->
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script>
  $(function() {
    $( "#tabs01" ).tabs();
  });
 </script>

</head>
<body>


<!-- jQuery ui タブメニュー -->
<DIV id="tabs01" style="width:800px" class="fancybox-bshadow contents">
  <ul>
    <li><a href="#incTabs01-1">サンプル1の1</a></li>
    <li><a href="#incTabs01-2">サンプル1の2</a></li>
   </ul>
<div class="contents" id="incTabs01-1" style="background:#f5f5f5;padding:0px;margin:0px;width:800px;height:100%;overflow:auto;">
<pre><code class="html">

・・・・・・・・・・・

</code></pre>
</div>
<div class="contents" id="incTabs01-2" style="background:#f5f5f5;padding:0px;margin:0px;width:800px;height:100%;overflow:auto;">
<pre><code class="html">

・・・・・・・・・・・

</code></pre>
</div>
</DIV>

5. これまでのHTMLまとめ

これまでのサンプルコードをまとめ、つぎのとおりサンプルHTMLを作成します。
highlight.jsにコピー機能を追加し、<pre><code>タグ内のコードをクリップボードにコーピーする「コピーボタン」を自動生成するのまとめサンプルHTMはつぎのとおり、基本編とjQuery ui タグメニュー編の2つのサンプルを作成しました。



1. highlight.jsおよびhighlight CSSの設置2. 自動でコピーボタン追加するjavascript3. CSSによるコピーボタンの装飾
4. <pre><code>タグコード5. これまでのHTMLまとめTOP





 最終更新日:2021. 3.21(初版)