JSFiddle - React, Tailwind, and code Playground
by htsign
HTML
<div class="calc-length">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
<div class="calc-length">寿限無、寿限無
五劫の擦り切れ
海砂利水魚の
水行末 雲来末 風来末
食う寝る処に住む処
藪ら柑子の藪柑子
パイポパイポ パイポのシューリンガン
シューリンガンのグーリンダイ
グーリンダイのポンポコピーのポンポコナーの
長久命の長助
</div>
CSS
.calc-length {
margin: 0;
padding: 0;
outline: 1px solid blue;
float: left;
}
.show-more {
display: block;
}
JavaScript
// getElementsByClassName は比較的新しいメソッドであるためIE8以下では使えません。
// [] は配列のリテラルです。
// 配列が持つsliceメソッドを getElementsByClassName で得られる集合に適用します。
// call メソッドは説明すると長くなるので、ここでは呪文のようなものと思ってください。
var targets = [].slice.call(document.getElementsByClassName("calc-length"));
// forEach も比較的新しいメソッドです。これも配列が持つメソッドです。
// 古い環境に適用する場合には
// for (var i = 0, l = targets.length; i < l; i++) {
// target = targets[i];
// }
// などとします。
// 変数[e]に targets が持つ一つ一つの要素が順次入って、すべてに対して処理を行います。
// この場合は calc-lengthクラスを持つすべての要素です。
targets.forEach(function(e){
// textContent プロパティは内部のテキストを取得します。
// これも比較的新しいのでIE8以下で使えません。innerTextとは微妙に異なります。
var length = calcLength(e.textContent);
if (length >= 50) {
e.dataset.originaltext = e.textContent;
e.textContent = e.textContent.substr(0, 10) + "...";
// 「この要素の後ろに置く」というメソッドはないため、
// 「"この次の要素"の前に置く」という回りくどい処理になります。
var showMoreButton = new ShowMoreButton();
e.parentElement.insertBefore(showMoreButton, e.nextElementSibling);
}
});
// 半角を1文字、全角を2文字として文字数を計測します。
function calcLength(text) {
var length = 0;
for (var i = 0, l = text.length; i < l; i++) {
// ref: http://www.openspc2.org/reibun/javascript/string/026/
// 三項演算子というものを使っています。
// 構文は [条件文] ? [条件がtrueのとき] : [条件がfalseのとき] です。
// ここでは条件式の範囲が分かりやすいよう、見やすさのために無意味なカッコで括っています。
length += (escape(text[i]).length < 4) ? 1 : 2;
}
return length;
}
// 「もっと見る」ボタン
function ShowMoreButton() {
var button = document.createElement("button");
button.className = "show-more";
button.textContent = "もっと見る";
button.addEventListener("click", function(e){
// 「自分自身の前の要素」の data-originaltext をその要素のテキストに代入します。
var previousElement = button.previousElementSibling;
previousElement.textContent = previousElement.dataset.originaltext;
}, false);
return button;
}