【JavaScript】 preやdiv要素内に行番号を付与する
更新日:2020/06/21
このサイトでは、サンプルコードを掲載している記事が多いです。
時々、サンプルコードに行番号を付与した方がいいのではないかと思う時があります。
そこでpreやdiv内に行番号を付与する方法をお伝えします。
スクリプトコード
preやdiv内の行が全て同じ高さのとき、次のコードで各行に行番号を付与できる。
JavaScript
( lineMax => {
window.addEventListener( "DOMContentLoaded" , ()=> {
const content = '.lnumber:before{content:"' + ( () => {
const buf = [];
for( let i = 1 ; i <= lineMax ; i ++ ) buf.push( i.toString() );
return buf;
})( ).join( "\\a " ) + '";}';
const styleTag = document.createElement("style");
styleTag.innerHTML = content;
document.getElementsByTagName("head")[0].appendChild(styleTag);
});
})( 300 );
次のCSSも必要。
css
.lnumber{
position: relative;
padding: 0 1em 0 55px;
}
.lnumber p{
margin: 0;
padding: 0;
}
.lnumber:before {
height: 100%;
width: 50px;
position: absolute;
left: 0;
top: 0;
word-wrap: break-word;
overflow: hidden;
color: green;
white-space: pre;
text-align: right;
background: white;
color: gray;
font-family: "arial";
border-right: 1px solid gray;
padding: 0 5px 0 0;
box-sizing: border-box;
}
使い方
使い方は、下の例のようにlnumberクラスを付与する。
<div style="border:1px solid black;">
<pre class="lnumber">
( lineMax => {
window.addEventListener( "DOMContentLoaded" , ()=> {
const content = '.lnumber:before{content:"' + ( () => {
const buf = [];
for( let i = 1 ; i <= lineMax ; i ++ ) buf.push( i.toString() );
return buf;
})( ).join( "\\a " ) + '";}';
const styleTag = document.createElement("style");
styleTag.innerHTML = content;
document.getElementsByTagName("head")[0].appendChild(styleTag);
});
})( 300 );
</pre>
</div>
実行すると、次のようにpre要素に行番号が付与されます。
<div style="border:1px solid black;"> <pre class="lnumber"> ( lineMax => { window.addEventListener( "DOMContentLoaded" , ()=> { const content = '.lnumber:before{content:"' + ( () => { const buf = []; for( let i = 1 ; i <= lineMax ; i ++ ) buf.push( i.toString() ); return buf; })( ).join( "\\a " ) + '";}'; const styleTag = document.createElement("style"); styleTag.innerHTML = content; document.getElementsByTagName("head")[0].appendChild(styleTag); }); })( 300 ); </pre> </div>
div要素でも同じことが可能です。
解説
疑似要素beforeのcontentに"\a"を指定すると改行します。
その特性を利用して、行番号を付与しています。
そのためJavaScriptを使用しなくても、cssで次のように指定すれば表示されます。
content: "1\a 2\a 3\a ・・・・・";
}
しかし入力した行数しか表示されません。
数百行に及ぶ行数を表示したい場合、手作業で入力するのは非常に困難です。
そこでJavaScriptで動的に、contentの値をセットしています。
もっと簡単に番号を付与できる『Google Code Prettify』
『Google Code Prettify』は、ソースコードを色分けしてくれるJavaScriptライブラリです。
手軽に行番号が付与されればいいなら、おススメです。
使い方
次のコードをheadタグ内に記述して、スクリプトを読み込みます。
<script async src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
行番号を付与したいコードを<pre class="prettyprint linenums"></pre>または<code class="prettyprint linenums"></code>内に記述します。
残念ながら<div></div>は使用できません。
Google Code Prettify使用例
<pre class="prettyprint linenums">
( lineMax => {
window.addEventListener( "DOMContentLoaded" , ()=> {
const content = '.lnumber:before{content:"' + ( () => {
const buf = [];
for( let i = 1 ; i <= lineMax ; i ++ ) buf.push( i.toString() );
return buf;
})( ).join( "\\a " ) + '";}';
const styleTag = document.createElement("style");
styleTag.innerHTML = content;
document.getElementsByTagName("head")[0].appendChild(styleTag);
});
})( 300 );
</pre>
実際に表示すると次のようになります。
cssの調整
デフォルトでは5行ごとに番号が振られています。
しかし10行目は、掲載しているサイトのスタイル属性の影響を受けてしまい、0しか見えていません。
『Google Code Prettify』は自動で専用のcssファイルを読み込んでくれるのですが、設定が不十分です。
そこで独自にcssを追加して調整します。
CSS
.prettyprint{ /* 枠線 */
border-left: 5px solid green;
padding: 0;
}
.prettyprint ol.linenums{
list-style:none;
counter-reset: linenums_count;
overflow: hidden;
position: relative;
padding:0;
margin:0;
}
.prettyprint ol.linenums > li{ /* 表示されるテキスト */
padding:0 5px 0 50px; /* 行番号の幅を変更するときは、*/
/* 4つめのpxを調整する */
}
.prettyprint ol.linenums > li:before{ /* 行番号 */
counter-increment: linenums_count;
content: counter(linenums_count);
width: 40px; /* 行番号の幅 */
text-align: right;
display: block;
position: absolute;
left: 0;
border-right: 2px solid #ccc;
border-top:1px solid #ccc;
padding-right:3px;
background: white;
}
CSSを適用すると、次のように表示されます。
注意点
『Google Code Prettify』の問題というよりもpreタグを使用するときの注意点ですが、『<』と『>』を使用する場合はエンティティに変換する必要があります。
具体的には、次のように書き換えます。
『<』→『<』
『>』→『>』
僕は最初手作業で書き換えていましたが、面倒に感じてきたのでエンティティをおこなうツールを作成しました。
HTMLエンティティ変換ツールのデフォルト状態は、スペースを変換してしまいpreタグの意味がなくなってしまうので、次の図のようにオプションを開いて、スペースとタグのチェックを外してください。
その後、変換したい文字列エリアにコードを貼り付けると、自動で変換結果が表示されます。
クリップボードへコピーを押すとコピーされるので、preタグ内に貼り付ければ完了です。
ぜひ使ってみてください。
行番号は必要か?
コードの解説するとき、行番号があると便利ですね。
ただコードを手直して行番号がズレると、記事を見直す必要があります。
手間に感じるということもありますが、それよりも修正忘れの方が怖いです。
そのため、行番号を使用しないで解説したほうが無難です。
説明に行番号が必要ないとすると、後は読んだ人がどう感じるか考える必要があります。
とはいえ考え方は千差万別なので、アンケートをとって判断するしかないのですが、現実的ではありません。
結局は自分がどう思うかで判断することになります。
行番号があると、その分だけ表示できる幅が狭くなりコードが見にくくなります。
そのため、僕は今のところ行番号は付与しません。
記事を書いたけれど自分は使わないとか…
我ながらひどいですね(反省はしない
更新日:2020/06/21
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。