teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

TreeWalkerでの例を追加。

2017/11/29 07:51

投稿

x_x
x_x

スコア13749

answer CHANGED
@@ -1,3 +1,53 @@
1
1
  この手のものをまともに処理しようとするとかなり複雑になるし、全角/半角は言うのは簡単ですが判別は大変です。
2
2
  そこで、幅を固定し、text-overflow: ellipsis を使うのはどうでしょうか?
3
- [https://developer.mozilla.org/ja/docs/Web/CSS/text-overflow](https://developer.mozilla.org/ja/docs/Web/CSS/text-overflow)
3
+ [https://developer.mozilla.org/ja/docs/Web/CSS/text-overflow](https://developer.mozilla.org/ja/docs/Web/CSS/text-overflow)
4
+
5
+ -- 追記。
6
+ ノード操作をした一例です。ちょっとうんざりしてくるのではないでしょうか?
7
+ ```JavaScript
8
+ function isHalf(code) {
9
+ return (code >= 0x0 && code < 0x81) || (code == 0xf8f0) || (code >= 0xff61 && code < 0xffa0) || (code >= 0xf8f1 && code < 0xf8f4);
10
+ }
11
+
12
+ function truncateTextNode(textNode) {
13
+ var text = textNode.nodeValue;
14
+ var newText = '';
15
+ for (var i = 0; i < text.length; i++) {
16
+ var c = text.charCodeAt(i);
17
+ var cost = isHalf(c) ? 0.5 : 1;
18
+ if (cost > remain) {
19
+ remain = -1;
20
+ textNode.nodeValue = newText;
21
+ return;
22
+ }
23
+
24
+ newText += text.charAt(i);
25
+ remain -= cost;
26
+ }
27
+
28
+ textNode.nodeValue = newText;
29
+ }
30
+
31
+ var remain = 50;
32
+ var root = document.querySelector('p.txt');
33
+ var tw = document.createTreeWalker(root);
34
+ var node;
35
+ while (node = tw.nextNode()) {
36
+ switch (node.nodeType) {
37
+ case document.ELEMENT_NODE:
38
+ if (remain < 0) {
39
+ node.setAttribute('data-remove', '1');
40
+ }
41
+
42
+ break;
43
+ case document.TEXT_NODE:
44
+ truncateTextNode(node);
45
+ break;
46
+ }
47
+ }
48
+
49
+ if (remain < 0) {
50
+ $(root.querySelectorAll('[data-remove]')).remove();
51
+ root.appendChild(document.createTextNode('…'));
52
+ }
53
+ ```