ブログでよく見かける「読了までの時間」を、JavaScriptで文字数を取得して出力させてみます。
文字数をカウントする要素は任意のものに変更できるので、ブログ以外でも使えます。ので、参考にしてみてください。
.length
JavaScriptの.lengthは、配列の要素の数を設定・取得するプロパティです。
elements.innerHTML.length;
このプロパティは、for文
を書く際ループの繰り返しごとに配列の長さがチェックする時にも使われます。
for (let i = 0; i < data.length; i++) {
viewPosts.innerHTML += data[i].date
}
この記事では for文
を使っていませんが、APIを使う時に頻出するので覚えとくといいです。
文字数をカウントするサンプル
早速サンプルです。
表示されている「この記事は約3分で読めます。」と「以下の文章は1582文字です。」は、JavaScriptで出力させています。
ダミーの記事
日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。
ブログでよく見るこの2つのオブジェクトをJavaScriptで出力させるのが、この記事のスニペットです。
実装の手順と方法
スニペットのご紹介の前に、実装の手順と方法について簡単にご説明します。
最初に、設置したい場所へHTMLをコピペします。
<ul id="postpoint"></ul>
<p class="dummyTitle"><span>ダミーの記事</span></p>
<p id="countPost">日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。</p>
もしくは、この記事のJavaScriptのコードを使って指定の要素として文字数をカウントしたい場合は、対象の要素に「countPost」のid名を付与すればOKです。
次に、JavaScriptのコードをページに記述します。
コードは <body>〜</body>
で、</body>
の閉じタグ(クロージングタグ)の前に記述しましょう。
document.addEventListener('DOMContentLoaded', function() {
const MINUTE_READ_CHAR = 500; // 500文字=1分でカウント
var getElm = document.getElementById('countPost'); // 出力させる要素
var putElm = document.getElementById('postpoint'); // カウントする要素
var strNoHtmlTag = '';
var iReadTime = '';
var strSetHtml = '';
var textCount = getElm.innerHTML.length; // 文字数のカウント
if(getElm != null){
// 文字列の抜き出し
strNoHtmlTag = getElm.innerHTML.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g,'');
// 文字数を秒数でカウント
iReadTime = Math.floor( strNoHtmlTag.length / MINUTE_READ_CHAR );
if( iReadTime == 0 ){
// 1分未満は1分に変更
iReadTime = 1;
}
// タグ作成
strSetHtml = '<li class="readAllTime">この記事は<span>約' + iReadTime + '分</span>で読めます。</li>';
textDis = '<li class="textCount">以下の文章は<span>' + textCount + '</span>文字です。</li>';
// タグ埋め込み
putElm.innerHTML= putElm.innerHTML + strSetHtml;
putElm.innerHTML= putElm.innerHTML + textDis;
}
});
最後にCSSを記述します。
/* 読む時間と文字数 */
ul#postpoint {
list-style: none;
padding: 0;
border: none;
margin: 0 0 25px;
}
ul#postpoint li {
padding-left: 25px;
position: relative;
}
ul#postpoint li:before {
font-family: "Font Awesome 5 Free";
font-weight: 900;
font-size: 1em;
position: absolute;
left: 0;
width: 20px;
text-align: center;
line-height: 2.6;
}
ul#postpoint li span {
font-weight: 600;
font-size: 1.4rem;
padding-left: 3px;
padding-right: 3px;
letter-spacing: 0.02rem;
}
/* アイコンはFontawesome */
li.readAllTime:before {
content: "\f252";
}
li.textCount:before {
content: "\f891";
}
/* 文字数を取得する要素 */
p#countPost {
max-height: 400px;
overflow-y: scroll;
margin: 0;
border: solid 2px #ddd;
padding: 20px 25px;
background: #FFF;
border-radius: 0 0 3px 3px;
}
p.dummyTitle {
background: #dddddd;
text-align: center;
color: #313131;
margin: 0;
padding: 15px 0 12px;
font-size: 1.3rem;
font-weight: 500;
letter-spacing: 0.05rem;
position: relative;
border-radius: 3px 3px 0 0;
}
/* スクロールバー */
p#countPost::-webkit-scrollbar {
width: 12px;
}
p#countPost::-webkit-scrollbar-thumb {
background: #313131;
border-radius: 9999px;
}
この記事のサンプルのような見た目にしない場合は、上記のコードは記述しなくてOKです。
CSSはレイアウトを整えているだけなので、ここは飛ばしてもOKです。
ざっくりとしたコードの解説
コードはHTML・JavaScript・CSSの3種です。順に解説していきます。
HTML
HTMLは、「postpoint」のid名を持つ「分数と文字数を出力する要素」と、文字数のカウント対象になる「countPost」のid名を持つ要素の2つです。
<ul id="postpoint"></ul>
<p class="dummyTitle"><span>ダミーの記事</span></p>
<p id="countPost">日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。</p>
このid名「postpoint」と「countPost」は、JavaScriptのコードと連動しているので、id名を変える場合はJavaScriptのコードもその名前で変更する必要があります。
「postpoint」の要素は、JavaScriptで li
タグを出力させるので、ul
タグで記述しています。
JavaScript
JavaScriptは、冒頭に文字数のカウントルール(サンプルでは500文字を1分で換算)を設定して、次にHTMLのid名で要素を取得します。
document.addEventListener('DOMContentLoaded', function() {
const MINUTE_READ_CHAR = 500; // 500文字=1分でカウント
var getElm = document.getElementById('countPost'); // 出力させる要素
var putElm = document.getElementById('postpoint'); // カウントする要素
var strNoHtmlTag = '';
var iReadTime = '';
var strSetHtml = '';
var textCount = getElm.innerHTML.length; // 文字数のカウント
if(getElm != null){
// 文字列の抜き出し
strNoHtmlTag = getElm.innerHTML.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g,'');
// 文字数を秒数でカウント
iReadTime = Math.floor( strNoHtmlTag.length / MINUTE_READ_CHAR );
if( iReadTime == 0 ){
// 1分未満は1分に変更
iReadTime = 1;
}
// タグ作成
strSetHtml = '<li class="readAllTime">この記事は<span>約' + iReadTime + '分</span>で読めます。</li>';
textDis = '<li class="textCount">以下の文章は<span>' + textCount + '</span>文字です。</li>';
// タグ埋め込み
putElm.innerHTML= putElm.innerHTML + strSetHtml;
putElm.innerHTML= putElm.innerHTML + textDis;
}
});
要素の取得が完了したら文字列を整形していき、文字列のカウントと分数への計算が行われ、最後にそれぞれ要素へ出力します。
複数行のコードですが、分解して見ると簡単な記述内容です。
CSS
CSSはレイアウトを整える記述で、そこまで多くない記述量です。
/* 読む時間と文字数 */
ul#postpoint {
list-style: none;
padding: 0;
border: none;
margin: 0 0 25px;
}
ul#postpoint li {
padding-left: 25px;
position: relative;
}
ul#postpoint li:before {
font-family: "Font Awesome 5 Free";
font-weight: 900;
font-size: 1em;
position: absolute;
left: 0;
width: 20px;
text-align: center;
line-height: 2.6;
}
ul#postpoint li span {
font-weight: 600;
font-size: 1.4rem;
padding-left: 3px;
padding-right: 3px;
letter-spacing: 0.02rem;
}
/* アイコンはFontawesome */
li.readAllTime:before {
content: "\f252";
}
li.textCount:before {
content: "\f891";
}
/* 文字数を取得する要素 */
p#countPost {
max-height: 400px;
overflow-y: scroll;
margin: 0;
border: solid 2px #ddd;
padding: 20px 25px;
background: #FFF;
border-radius: 0 0 3px 3px;
}
p.dummyTitle {
background: #dddddd;
text-align: center;
color: #313131;
margin: 0;
padding: 15px 0 12px;
font-size: 1.3rem;
font-weight: 500;
letter-spacing: 0.05rem;
position: relative;
border-radius: 3px 3px 0 0;
}
/* スクロールバー */
p#countPost::-webkit-scrollbar {
width: 12px;
}
p#countPost::-webkit-scrollbar-thumb {
background: #313131;
border-radius: 9999px;
}
サンプルで取得する文字数が1500文字程度と多めなので、スクロールバーを付けており、その辺りの記述が最後にあります。
さいごに
WordPressのテーマによっては、文字数をカウントして「読む時間」を出力してくれるのが多いですが、ない場合や静的なページなど、そんな場合にはこの記事を参考にしてみてください。