だてブログ

ねことテクと趣味のブログ

ソースコードの行番号を選択できないようにする方法

経緯

ブログでソースコードを公開したり、自作でソースコードを公開するプログラムを組む際、行番号だけを選択できないようにしたかった。 (Githubソースコードのように)

しかし下のようにしたら、見た目の上では選択できないようにできたものの、行番号ごと、行全体をコピーしてみると、裏では選択が行番号を含め、行全体が選択されてしまった。

<pre><code>
<table>
  <tbody>
    <tr>
      <td style="user-select:none;">1</td>
      <td>#test1 test1 test1</td>
    </tr>
    <tr>
      <td style="user-select:none;">2</td>
      <td>#test2 test2 test2</td>
    </tr>
    <tr>
      <td style="user-select:none;">3</td>
      <td>#test3 test3 test3</td>
    </tr>
    <tr>
      <td style="user-select:none;">4</td>
      <td>#test4 test4 test4</td>
    </tr>
      <td style="user-select:none;">5</td>
      <td>#test5 test5 test5</td>
    </tr>         
  </tbody>
<table>
</code></pre>

そこで、CSSjavascriptを使ってなんとかできないか試して見た。

試したこと

unselectable=“on”

<td style="user-select:none;" unselectable="on">1</td>

=> 単体をマウスでなぞると選択できないが、その行全体を選択するかその外からマウスでなぞると、行番号も選択できてしまう。

position:absolute;やz-indexを使って分離させる。

<td style="user-select:none; position:absolute; z-index:10;">1</td>
<td style="position:relative; z-index:1; padding-left:10px;">#test1 test1 test1</td>

=>DOMに文字列が存在しているせいか、行番号も選択できてしまう。

結論

「その対象に擬似セレクタ"before"をつけて、その内容を"content: attr(data-◯◯);“として、対象タグにdata-〇〇="行番号"のアトリビュートをつける。」

<style>
  td:nth-child(odd)::before{ /* 奇数番目のtd */
    content: attr(data-test);
  }
</style>
...
<pre><code>
<table>
  <tbody>
    <tr>
      <td style="user-select:none;" data-test="1"></td>
      <td>#test1 test1 test1</td>
    </tr>
    <tr>
      <td style="user-select:none;" data-test="2"></td>
      <td>#test2 test2 test2</td>
    </tr>
    <tr>
      <td style="user-select:none;" data-test="3"></td>
      <td>#test3 test3 test3</td>
    </tr>
    <tr>
      <td style="user-select:none;" data-test="4"></td>
      <td>#test4 test4 test4</td>
    </tr>
      <td style="user-select:none;" data-test="5"></td>
      <td>#test5 test5 test5</td>
    </tr>         
  </tbody>
<table>
</code></pre>

… 結局、GithubやGistのソースコードを参考にしました。