回答編集履歴
2
追記&訂正
test
CHANGED
@@ -190,4 +190,4 @@
|
|
190
190
|
|
191
191
|
・・・のあたりから来ているようですが、そこを改善して何とかするというのは JavaScript では無理っぽい気がします。
|
192
192
|
|
193
|
-
CSS の text-overflow:ellipsis と JavaScript を組み合わせて何とかなりそうな気がします。が、質問者さんのやりたいことが
|
193
|
+
CSS の text-overflow:ellipsis と JavaScript を組み合わせて何とかなりそうな気がします。が、質問者さんのやりたいことが下のコメント欄の説明を見ても分かりませんので、気がするだけですけど。
|
1
追記
test
CHANGED
@@ -52,3 +52,142 @@
|
|
52
52
|
テキストが領域をこえた場合に三点リーダー「…」を表示する text-overflow:ellipsis はもともと IE の独自拡張だそうですが、他のブラウザでも取り入れられているようで、以下のブラウザで同様な結果となります。
|
53
53
|
|
54
54
|
Edge 113.0.1774.35, Chrome 113.0.5672.64, Firefox 112.0.2, Opera 98.0.4759.15
|
55
|
+
|
56
|
+
---
|
57
|
+
|
58
|
+
**【追記」**
|
59
|
+
|
60
|
+
下のコメント欄の 2023/05/09 12:05 の私のコメントで「質問に書かれた JavaScript のコードではプロポーショナルフォントやサロゲートペアへの対応が考えられてないところに問題があるのではないですか? あとで、どういう問題がありそうか回答欄に追記しておきます」と書いた件です。
|
61
|
+
|
62
|
+
どのような問題がありそうかの具体例を書いておきます。以下のコードを見てください。body 要素の中にある br 要素の上の方を最初の回答に書いたように CSS の text-overflow:ellipsis を使って、br 要素の下の方を質問者さんが書いた JavaScript で処理してみます。
|
63
|
+
|
64
|
+
```html
|
65
|
+
<!DOCTYPE html>
|
66
|
+
|
67
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
68
|
+
<head runat="server">
|
69
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
70
|
+
<title></title>
|
71
|
+
<style type="text/css">
|
72
|
+
.style1
|
73
|
+
{
|
74
|
+
width: 80%;
|
75
|
+
overflow: hidden;
|
76
|
+
white-space: nowrap;
|
77
|
+
text-overflow: ellipsis;
|
78
|
+
}
|
79
|
+
|
80
|
+
.style2
|
81
|
+
{
|
82
|
+
width: 80%;
|
83
|
+
}
|
84
|
+
|
85
|
+
.sample1
|
86
|
+
{
|
87
|
+
width: 400px;
|
88
|
+
}
|
89
|
+
|
90
|
+
.sample2
|
91
|
+
{
|
92
|
+
width: 200px;
|
93
|
+
}
|
94
|
+
</style>
|
95
|
+
<script type="text/javascript">
|
96
|
+
function capacity(s) {
|
97
|
+
|
98
|
+
//算出されたCSSを取得
|
99
|
+
var style = window.getComputedStyle(s);
|
100
|
+
|
101
|
+
//フォントサイズとボックスの幅を数値で取得
|
102
|
+
var fontsize = parseInt(style.fontSize);
|
103
|
+
var width = parseInt(style.width);
|
104
|
+
|
105
|
+
//ボックスに収納できる文字数
|
106
|
+
var mojisuu = Math.floor(width / fontsize);
|
107
|
+
|
108
|
+
return mojisuu;
|
109
|
+
};
|
110
|
+
|
111
|
+
function textcount(n) {
|
112
|
+
var nagasa = 0;
|
113
|
+
for (i = 0; i < n.length; i++) {
|
114
|
+
if (n[i].match(/[ -~]/)) {
|
115
|
+
|
116
|
+
nagasa += 0.5;
|
117
|
+
}
|
118
|
+
|
119
|
+
else {
|
120
|
+
|
121
|
+
nagasa += 1;
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
return nagasa;
|
126
|
+
};
|
127
|
+
|
128
|
+
window.addEventListener("DOMContentLoaded", () => {
|
129
|
+
var sampleall = document.querySelectorAll(".style1");
|
130
|
+
sampleall.forEach(function (value) {
|
131
|
+
var count = (textcount(value.innerText));
|
132
|
+
var cap = capacity(value);
|
133
|
+
console.log(`count: ${count}, capacity: ${cap}`);
|
134
|
+
});
|
135
|
+
|
136
|
+
var sampleall2 = document.querySelectorAll(".style2");
|
137
|
+
sampleall2.forEach(function (value) {
|
138
|
+
var count = (textcount(value.innerText));
|
139
|
+
|
140
|
+
if (count > capacity(value)) {
|
141
|
+
|
142
|
+
//はみ出してる文字数+4文字をテキストの後ろから削除
|
143
|
+
value.innerHTML = value.innerHTML.slice(0, capacity(value) - count - 4);
|
144
|
+
|
145
|
+
//「…」と連結し、元のテキストを置き換える
|
146
|
+
value.innerHTML = value.innerHTML + "…";
|
147
|
+
}
|
148
|
+
});
|
149
|
+
});
|
150
|
+
</script>
|
151
|
+
</head>
|
152
|
+
<body>
|
153
|
+
<div class="sample1">
|
154
|
+
<div class="style1">エスケープされた < > & などの文字の扱いはどうなる?</div>
|
155
|
+
<div class="style1">Proportional Font WWWWWWWWWWW iiiiiiii のように文字幅が異なるフォント</div>
|
156
|
+
<div class="style1">サロゲートペア 𠀋 𡈽 𠮟 などはどのようになるか?</div>
|
157
|
+
<div class="style1">絵文字 🍎 🍏 👨🌾 などはどのようになるか?</div>
|
158
|
+
</div>
|
159
|
+
|
160
|
+
<br />
|
161
|
+
|
162
|
+
<div class="sample1">
|
163
|
+
<div class="style2">エスケープされた < > & などの文字の扱いはどうなる?</div>
|
164
|
+
<div class="style2">Proportional Font WWWWWWWWWWW iiiiiiii のように文字幅が異なるフォント</div>
|
165
|
+
<div class="style2">サロゲートペア 𠀋 𡈽 𠮟 などはどのようになるか?</div>
|
166
|
+
<div class="style2">絵文字 🍎 🍏 👨🌾 などはどのようになるか?</div>
|
167
|
+
|
168
|
+
</div>
|
169
|
+
</body>
|
170
|
+
</html>
|
171
|
+
```
|
172
|
+
|
173
|
+
結果は以下のようになります。上が CSS の text-overflow:ellipsis での処理、下が質問者さんが書いた JavaScript での処理です。ブラウザは Chrome 113.0.5672.93、フォントは 16px Meiryo です。
|
174
|
+
|
175
|
+

|
176
|
+
|
177
|
+
> 該当テキストでは現状絵文字と記号は使ってない
|
178
|
+
|
179
|
+
・・・とのことですので絵文字の結果は関係ない、```< > &``` などの文字は length では 1 文字としてカウントされるので問題ないと思いますが、プロポーショナルフォントやサロゲートペアはどうでしょう?
|
180
|
+
|
181
|
+
問題は質問のコードの、
|
182
|
+
|
183
|
+
> //ボックスに収納できる文字数
|
184
|
+
> var mojisuu = Math.floor(width/fontsize);
|
185
|
+
|
186
|
+
> /*対象のテキスト(.sample)が全角1文字、半角0.5文字で合計何文字になるか計算する関数*/
|
187
|
+
> function textcount(n) {
|
188
|
+
> ...
|
189
|
+
> for (i = 0; i < n.length; i++) {
|
190
|
+
|
191
|
+
・・・のあたりから来ているようですが、そこを改善して何とかするというのは JavaScript では無理っぽい気がします。
|
192
|
+
|
193
|
+
CSS の text-overflow:ellipsis と JavaScript を組み合わせて何とかなりそうな気がします。が、質問者さんのやりたいことが上のコメントを見ても分かりませんので、気がするだけですけど。
|