回答編集履歴

2

追記&訂正

2023/05/09 03:51

投稿

退会済みユーザー
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

追記

2023/05/09 03:48

投稿

退会済みユーザー
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">エスケープされた &lt; &gt; &amp; などの文字の扱いはどうなる?</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">エスケープされた &lt; &gt; &amp; などの文字の扱いはどうなる?</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
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2023-05-09/dcb0ea8a-9ab7-448d-812b-0b3d92eb7405.jpeg)
176
+
177
+ > 該当テキストでは現状絵文字と記号は使ってない
178
+
179
+ ・・・とのことですので絵文字の結果は関係ない、```&lt; &gt; &amp;``` などの文字は 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 を組み合わせて何とかなりそうな気がします。が、質問者さんのやりたいことが上のコメントを見ても分かりませんので、気がするだけですけど。