smart-text-ellipsis 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +15 -0
- package/dist/simple-text-ellipsis.cjs.js +116 -0
- package/dist/simple-text-ellipsis.cjs.js.map +68 -0
- package/dist/simple-text-ellipsis.css +63 -0
- package/dist/simple-text-ellipsis.esm.js +116 -0
- package/dist/simple-text-ellipsis.esm.js.map +69 -0
- package/dist/simple-text-ellipsis.umd.js +128 -0
- package/dist/simple-text-ellipsis.umd.js.map +68 -0
- package/package.json +46 -0
- package/src/common.js +11 -0
- package/src/index.js +138 -0
- package/src/index.scss +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 wurencaideli
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* smart-text-ellipsis v0.0.2
|
|
3
|
+
* Copyright 2025 wuzhanggui https://github.com/wurencaideli
|
|
4
|
+
* Licensed under MIT
|
|
5
|
+
*/
|
|
6
|
+
'use strict';
|
|
7
|
+
function e(e) {
|
|
8
|
+
e && e.parentNode && e.parentNode.removeChild(e);
|
|
9
|
+
}
|
|
10
|
+
function t(e, t) {
|
|
11
|
+
e.classList.add(t);
|
|
12
|
+
}
|
|
13
|
+
function s(e, t) {
|
|
14
|
+
e.classList.remove(t);
|
|
15
|
+
}
|
|
16
|
+
exports.SmartTextEllipsis = class {
|
|
17
|
+
isDestroyed = !1;
|
|
18
|
+
maxLines = 0;
|
|
19
|
+
targetEl = void 0;
|
|
20
|
+
expandEl = void 0;
|
|
21
|
+
collapseEl = void 0;
|
|
22
|
+
placeholderEl = void 0;
|
|
23
|
+
isOpen = !1;
|
|
24
|
+
#e = 0;
|
|
25
|
+
constructor(e = {}) {
|
|
26
|
+
const s = e.targetEl,
|
|
27
|
+
i = e.isOpen,
|
|
28
|
+
l = e.maxLines,
|
|
29
|
+
n = document.createElement('span'),
|
|
30
|
+
p = document.createElement('div'),
|
|
31
|
+
h = document.createElement('div');
|
|
32
|
+
(n.innerText = e.expandElText || 'Expand'),
|
|
33
|
+
(p.innerText = e.collapseElText || 'Collapse'),
|
|
34
|
+
(n.onclick = () => {
|
|
35
|
+
this.#t();
|
|
36
|
+
}),
|
|
37
|
+
(p.onclick = () => {
|
|
38
|
+
this.#s();
|
|
39
|
+
}),
|
|
40
|
+
t(p, 'smart-text-ellipsis-collapse'),
|
|
41
|
+
t(n, 'smart-text-ellipsis-expand'),
|
|
42
|
+
t(h, 'smart-text-ellipsis-placeholder'),
|
|
43
|
+
s.prepend(n),
|
|
44
|
+
s.prepend(h),
|
|
45
|
+
s.appendChild(p),
|
|
46
|
+
(this.targetEl = s),
|
|
47
|
+
(this.isOpen = i),
|
|
48
|
+
(this.maxLines = l),
|
|
49
|
+
(this.expandEl = n),
|
|
50
|
+
(this.collapseEl = p),
|
|
51
|
+
(this.placeholderEl = h),
|
|
52
|
+
this.update();
|
|
53
|
+
}
|
|
54
|
+
destroy() {
|
|
55
|
+
(this.isOpen = !0),
|
|
56
|
+
e(this.expandEl),
|
|
57
|
+
e(this.collapseEl),
|
|
58
|
+
this.#i(),
|
|
59
|
+
(this.targetEl = void 0),
|
|
60
|
+
(this.expandEl = void 0),
|
|
61
|
+
(this.collapseEl = void 0),
|
|
62
|
+
(this.isDestroyed = !0);
|
|
63
|
+
}
|
|
64
|
+
update() {
|
|
65
|
+
this.isDestroyed || ((this.#e = this.#l()), this.#i(), this.#n(), this.#p());
|
|
66
|
+
}
|
|
67
|
+
#t() {
|
|
68
|
+
this.isDestroyed || ((this.isOpen = !0), this.update());
|
|
69
|
+
}
|
|
70
|
+
#s() {
|
|
71
|
+
this.isDestroyed || ((this.isOpen = !1), this.update());
|
|
72
|
+
}
|
|
73
|
+
#i() {
|
|
74
|
+
const e = this.targetEl;
|
|
75
|
+
e &&
|
|
76
|
+
(this.isDestroyed
|
|
77
|
+
? e.style.setProperty('--max-lines', void 0)
|
|
78
|
+
: e.style.setProperty('--max-lines', `${this.maxLines}`),
|
|
79
|
+
1 == this.maxLines
|
|
80
|
+
? (t(e, 'smart-text-ellipsis-one'), s(e, 'smart-text-ellipsis-more'))
|
|
81
|
+
: (t(e, 'smart-text-ellipsis-more'), s(e, 'smart-text-ellipsis-one')),
|
|
82
|
+
this.isOpen && (s(e, 'smart-text-ellipsis-more'), s(e, 'smart-text-ellipsis-one')),
|
|
83
|
+
s(e, 'is-ellipsis'),
|
|
84
|
+
s(e, 'is-exceeded-max-line'));
|
|
85
|
+
}
|
|
86
|
+
#p() {
|
|
87
|
+
if (this.isDestroyed) return;
|
|
88
|
+
const e = this.targetEl;
|
|
89
|
+
e &&
|
|
90
|
+
(this.isOpen
|
|
91
|
+
? this.#h() > this.maxLines && t(e, 'is-exceeded-max-line')
|
|
92
|
+
: this.#a() && t(e, 'is-ellipsis'));
|
|
93
|
+
}
|
|
94
|
+
#n() {
|
|
95
|
+
const e = this.#e,
|
|
96
|
+
t = this.placeholderEl,
|
|
97
|
+
s = this.targetEl;
|
|
98
|
+
t.style.height = s.clientHeight - e + 'px';
|
|
99
|
+
}
|
|
100
|
+
#l() {
|
|
101
|
+
const e = this.targetEl;
|
|
102
|
+
if (e) return parseFloat(getComputedStyle(e).lineHeight) || 24;
|
|
103
|
+
}
|
|
104
|
+
#a() {
|
|
105
|
+
const e = this.maxLines,
|
|
106
|
+
t = this.targetEl;
|
|
107
|
+
return 1 === e ? t.scrollWidth > t.clientWidth : t.scrollHeight > t.clientHeight;
|
|
108
|
+
}
|
|
109
|
+
#h() {
|
|
110
|
+
const e = this.targetEl,
|
|
111
|
+
t = this.collapseEl,
|
|
112
|
+
s = this.#e;
|
|
113
|
+
return Math.floor((e.clientHeight - t.clientHeight) / s);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=smart-text-ellipsis.cjs.js.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"file": "smart-text-ellipsis.cjs.js",
|
|
4
|
+
"sources": [
|
|
5
|
+
"../src/common.js",
|
|
6
|
+
"../src/index.js"
|
|
7
|
+
],
|
|
8
|
+
"sourcesContent": [
|
|
9
|
+
"export function removeElement(element) {\n if (element && element.parentNode) {\n element.parentNode.removeChild(element);\n }\n}\nexport function addElementClass(el, className) {\n el.classList.add(className);\n}\nexport function removeElementClass(el, className) {\n el.classList.remove(className);\n}\n",
|
|
10
|
+
"import { addElementClass, removeElement, removeElementClass } from './common';\nexport class SmartTextEllipsis {\n isDestroyed = false;\n maxLines = 0;\n targetEl = undefined;\n expandEl = undefined;\n collapseEl = undefined;\n placeholderEl = undefined;\n isOpen = false;\n #lineHeight = 0;\n constructor(options = {}) {\n const targetEl = options.targetEl;\n const isOpen = options.isOpen;\n const maxLines = options.maxLines;\n const expandEl = document.createElement('span');\n const collapseEl = document.createElement('div');\n const placeholderEl = document.createElement('div');\n expandEl.innerText = options.expandElText || 'Expand';\n collapseEl.innerText = options.collapseElText || 'Collapse';\n expandEl.onclick = () => {\n this.#handleExpand();\n };\n collapseEl.onclick = () => {\n this.#handleCollapse();\n };\n addElementClass(collapseEl, 'smart-text-ellipsis-collapse');\n addElementClass(expandEl, 'smart-text-ellipsis-expand');\n addElementClass(placeholderEl, 'smart-text-ellipsis-placeholder');\n targetEl.prepend(expandEl);\n targetEl.prepend(placeholderEl);\n targetEl.appendChild(collapseEl);\n this.targetEl = targetEl;\n this.isOpen = isOpen;\n this.maxLines = maxLines;\n this.expandEl = expandEl;\n this.collapseEl = collapseEl;\n this.placeholderEl = placeholderEl;\n this.update();\n }\n /** 销毁实例 */\n destroy() {\n this.isOpen = true;\n removeElement(this.expandEl);\n removeElement(this.collapseEl);\n this.#setupClass();\n this.targetEl = undefined;\n this.expandEl = undefined;\n this.collapseEl = undefined;\n this.isDestroyed = true;\n }\n /** 更新样式 */\n update() {\n if (this.isDestroyed) return;\n this.#lineHeight = this.#getLineHeight();\n this.#setupClass();\n this.#setupPlaceholderStyle();\n this.#setupBtClass();\n }\n #handleExpand() {\n if (this.isDestroyed) return;\n this.isOpen = true;\n this.update();\n }\n #handleCollapse() {\n if (this.isDestroyed) return;\n this.isOpen = false;\n this.update();\n }\n /** 设置容器的类名 */\n #setupClass() {\n const targetEl = this.targetEl;\n if (!targetEl) return;\n if (!this.isDestroyed) {\n targetEl.style.setProperty('--max-lines', `${this.maxLines}`);\n } else {\n targetEl.style.setProperty('--max-lines', undefined);\n }\n if (this.maxLines == 1) {\n addElementClass(targetEl, 'smart-text-ellipsis-one');\n removeElementClass(targetEl, 'smart-text-ellipsis-more');\n } else {\n addElementClass(targetEl, 'smart-text-ellipsis-more');\n removeElementClass(targetEl, 'smart-text-ellipsis-one');\n }\n if (this.isOpen) {\n removeElementClass(targetEl, 'smart-text-ellipsis-more');\n removeElementClass(targetEl, 'smart-text-ellipsis-one');\n }\n removeElementClass(targetEl, 'is-ellipsis');\n removeElementClass(targetEl, 'is-exceeded-max-line');\n }\n /** 设置按钮的类名 */\n #setupBtClass() {\n if (this.isDestroyed) return;\n const targetEl = this.targetEl;\n if (!targetEl) return;\n if (this.isOpen) {\n // 如果行数超过了,显示收缩按钮\n if (this.#getActualLines() > this.maxLines) {\n addElementClass(targetEl, 'is-exceeded-max-line');\n }\n } else {\n // 如果字体省略了,显示展开按钮\n if (this.#isEllipsisActive()) {\n addElementClass(targetEl, 'is-ellipsis');\n }\n }\n }\n /** 设置占位元素的样式 */\n #setupPlaceholderStyle() {\n const lineHeight = this.#lineHeight;\n const placeholderEl = this.placeholderEl;\n const targetEl = this.targetEl;\n placeholderEl.style.height = `${targetEl.clientHeight - lineHeight}px`;\n }\n /** 获取一行文本的高度 */\n #getLineHeight() {\n const targetEl = this.targetEl;\n if (!targetEl) return;\n return parseFloat(getComputedStyle(targetEl).lineHeight) || 24;\n }\n /** 判断是否省略了 */\n #isEllipsisActive() {\n const maxLines = this.maxLines;\n const el = this.targetEl;\n if (maxLines === 1) {\n return el.scrollWidth > el.clientWidth;\n }\n return el.scrollHeight > el.clientHeight;\n }\n /** 获取文本视觉上的行数 */\n #getActualLines() {\n const targetEl = this.targetEl;\n const collapseEl = this.collapseEl;\n const lh = this.#lineHeight;\n return Math.floor((targetEl.clientHeight - collapseEl.clientHeight) / lh);\n }\n}\n"
|
|
11
|
+
],
|
|
12
|
+
"names": [
|
|
13
|
+
"removeElement",
|
|
14
|
+
"element",
|
|
15
|
+
"parentNode",
|
|
16
|
+
"removeChild",
|
|
17
|
+
"addElementClass",
|
|
18
|
+
"el",
|
|
19
|
+
"className",
|
|
20
|
+
"classList",
|
|
21
|
+
"add",
|
|
22
|
+
"removeElementClass",
|
|
23
|
+
"remove",
|
|
24
|
+
"isDestroyed",
|
|
25
|
+
"maxLines",
|
|
26
|
+
"targetEl",
|
|
27
|
+
"undefined",
|
|
28
|
+
"expandEl",
|
|
29
|
+
"collapseEl",
|
|
30
|
+
"placeholderEl",
|
|
31
|
+
"isOpen",
|
|
32
|
+
"lineHeight",
|
|
33
|
+
"constructor",
|
|
34
|
+
"options",
|
|
35
|
+
"document",
|
|
36
|
+
"createElement",
|
|
37
|
+
"innerText",
|
|
38
|
+
"expandElText",
|
|
39
|
+
"collapseElText",
|
|
40
|
+
"onclick",
|
|
41
|
+
"this",
|
|
42
|
+
"handleExpand",
|
|
43
|
+
"handleCollapse",
|
|
44
|
+
"prepend",
|
|
45
|
+
"appendChild",
|
|
46
|
+
"update",
|
|
47
|
+
"destroy",
|
|
48
|
+
"setupClass",
|
|
49
|
+
"getLineHeight",
|
|
50
|
+
"setupPlaceholderStyle",
|
|
51
|
+
"setupBtClass",
|
|
52
|
+
"style",
|
|
53
|
+
"setProperty",
|
|
54
|
+
"getActualLines",
|
|
55
|
+
"isEllipsisActive",
|
|
56
|
+
"height",
|
|
57
|
+
"clientHeight",
|
|
58
|
+
"parseFloat",
|
|
59
|
+
"getComputedStyle",
|
|
60
|
+
"scrollWidth",
|
|
61
|
+
"clientWidth",
|
|
62
|
+
"scrollHeight",
|
|
63
|
+
"lh",
|
|
64
|
+
"Math",
|
|
65
|
+
"floor"
|
|
66
|
+
],
|
|
67
|
+
"mappings": "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"
|
|
68
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
.smart-text-ellipsis-more {
|
|
2
|
+
display: -webkit-box;
|
|
3
|
+
-webkit-line-clamp: var(--max-lines);
|
|
4
|
+
-webkit-box-orient: vertical;
|
|
5
|
+
display: -moz-box;
|
|
6
|
+
line-clamp: var(--max-lines);
|
|
7
|
+
box-orient: vertical;
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
}
|
|
10
|
+
.smart-text-ellipsis-one {
|
|
11
|
+
white-space: nowrap;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
text-overflow: ellipsis;
|
|
14
|
+
}
|
|
15
|
+
.is-ellipsis > .smart-text-ellipsis-expand {
|
|
16
|
+
display: inline;
|
|
17
|
+
display: initial;
|
|
18
|
+
}
|
|
19
|
+
.is-ellipsis > .smart-text-ellipsis-placeholder {
|
|
20
|
+
display: inline;
|
|
21
|
+
display: initial;
|
|
22
|
+
}
|
|
23
|
+
.is-exceeded-max-line > .smart-text-ellipsis-collapse {
|
|
24
|
+
display: -webkit-box;
|
|
25
|
+
display: -webkit-flex;
|
|
26
|
+
display: -moz-box;
|
|
27
|
+
display: -ms-flexbox;
|
|
28
|
+
display: flex;
|
|
29
|
+
}
|
|
30
|
+
.smart-text-ellipsis-expand {
|
|
31
|
+
display: none;
|
|
32
|
+
float: right;
|
|
33
|
+
clear: both;
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
color: #1178d9;
|
|
36
|
+
position: relative;
|
|
37
|
+
z-index: 2;
|
|
38
|
+
}
|
|
39
|
+
.smart-text-ellipsis-collapse {
|
|
40
|
+
display: none;
|
|
41
|
+
-webkit-box-orient: horizontal;
|
|
42
|
+
-webkit-box-direction: normal;
|
|
43
|
+
-webkit-flex-direction: row;
|
|
44
|
+
-moz-box-orient: horizontal;
|
|
45
|
+
-moz-box-direction: normal;
|
|
46
|
+
-ms-flex-direction: row;
|
|
47
|
+
flex-direction: row;
|
|
48
|
+
-webkit-box-pack: end;
|
|
49
|
+
-webkit-justify-content: flex-end;
|
|
50
|
+
-moz-box-pack: end;
|
|
51
|
+
-ms-flex-pack: end;
|
|
52
|
+
justify-content: flex-end;
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
color: #1178d9;
|
|
55
|
+
position: relative;
|
|
56
|
+
z-index: 2;
|
|
57
|
+
}
|
|
58
|
+
.smart-text-ellipsis-placeholder {
|
|
59
|
+
display: none;
|
|
60
|
+
float: right;
|
|
61
|
+
width: 0;
|
|
62
|
+
pointer-events: none;
|
|
63
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* smart-text-ellipsis v0.0.2
|
|
3
|
+
* Copyright 2025 wuzhanggui https://github.com/wurencaideli
|
|
4
|
+
* Licensed under MIT
|
|
5
|
+
*/
|
|
6
|
+
function e(e) {
|
|
7
|
+
e && e.parentNode && e.parentNode.removeChild(e);
|
|
8
|
+
}
|
|
9
|
+
function t(e, t) {
|
|
10
|
+
e.classList.add(t);
|
|
11
|
+
}
|
|
12
|
+
function s(e, t) {
|
|
13
|
+
e.classList.remove(t);
|
|
14
|
+
}
|
|
15
|
+
class i {
|
|
16
|
+
isDestroyed = !1;
|
|
17
|
+
maxLines = 0;
|
|
18
|
+
targetEl = void 0;
|
|
19
|
+
expandEl = void 0;
|
|
20
|
+
collapseEl = void 0;
|
|
21
|
+
placeholderEl = void 0;
|
|
22
|
+
isOpen = !1;
|
|
23
|
+
#e = 0;
|
|
24
|
+
constructor(e = {}) {
|
|
25
|
+
const s = e.targetEl,
|
|
26
|
+
i = e.isOpen,
|
|
27
|
+
l = e.maxLines,
|
|
28
|
+
n = document.createElement('span'),
|
|
29
|
+
p = document.createElement('div'),
|
|
30
|
+
h = document.createElement('div');
|
|
31
|
+
(n.innerText = e.expandElText || 'Expand'),
|
|
32
|
+
(p.innerText = e.collapseElText || 'Collapse'),
|
|
33
|
+
(n.onclick = () => {
|
|
34
|
+
this.#t();
|
|
35
|
+
}),
|
|
36
|
+
(p.onclick = () => {
|
|
37
|
+
this.#s();
|
|
38
|
+
}),
|
|
39
|
+
t(p, 'smart-text-ellipsis-collapse'),
|
|
40
|
+
t(n, 'smart-text-ellipsis-expand'),
|
|
41
|
+
t(h, 'smart-text-ellipsis-placeholder'),
|
|
42
|
+
s.prepend(n),
|
|
43
|
+
s.prepend(h),
|
|
44
|
+
s.appendChild(p),
|
|
45
|
+
(this.targetEl = s),
|
|
46
|
+
(this.isOpen = i),
|
|
47
|
+
(this.maxLines = l),
|
|
48
|
+
(this.expandEl = n),
|
|
49
|
+
(this.collapseEl = p),
|
|
50
|
+
(this.placeholderEl = h),
|
|
51
|
+
this.update();
|
|
52
|
+
}
|
|
53
|
+
destroy() {
|
|
54
|
+
(this.isOpen = !0),
|
|
55
|
+
e(this.expandEl),
|
|
56
|
+
e(this.collapseEl),
|
|
57
|
+
this.#i(),
|
|
58
|
+
(this.targetEl = void 0),
|
|
59
|
+
(this.expandEl = void 0),
|
|
60
|
+
(this.collapseEl = void 0),
|
|
61
|
+
(this.isDestroyed = !0);
|
|
62
|
+
}
|
|
63
|
+
update() {
|
|
64
|
+
this.isDestroyed || ((this.#e = this.#l()), this.#i(), this.#n(), this.#p());
|
|
65
|
+
}
|
|
66
|
+
#t() {
|
|
67
|
+
this.isDestroyed || ((this.isOpen = !0), this.update());
|
|
68
|
+
}
|
|
69
|
+
#s() {
|
|
70
|
+
this.isDestroyed || ((this.isOpen = !1), this.update());
|
|
71
|
+
}
|
|
72
|
+
#i() {
|
|
73
|
+
const e = this.targetEl;
|
|
74
|
+
e &&
|
|
75
|
+
(this.isDestroyed
|
|
76
|
+
? e.style.setProperty('--max-lines', void 0)
|
|
77
|
+
: e.style.setProperty('--max-lines', `${this.maxLines}`),
|
|
78
|
+
1 == this.maxLines
|
|
79
|
+
? (t(e, 'smart-text-ellipsis-one'), s(e, 'smart-text-ellipsis-more'))
|
|
80
|
+
: (t(e, 'smart-text-ellipsis-more'), s(e, 'smart-text-ellipsis-one')),
|
|
81
|
+
this.isOpen && (s(e, 'smart-text-ellipsis-more'), s(e, 'smart-text-ellipsis-one')),
|
|
82
|
+
s(e, 'is-ellipsis'),
|
|
83
|
+
s(e, 'is-exceeded-max-line'));
|
|
84
|
+
}
|
|
85
|
+
#p() {
|
|
86
|
+
if (this.isDestroyed) return;
|
|
87
|
+
const e = this.targetEl;
|
|
88
|
+
e &&
|
|
89
|
+
(this.isOpen
|
|
90
|
+
? this.#h() > this.maxLines && t(e, 'is-exceeded-max-line')
|
|
91
|
+
: this.#a() && t(e, 'is-ellipsis'));
|
|
92
|
+
}
|
|
93
|
+
#n() {
|
|
94
|
+
const e = this.#e,
|
|
95
|
+
t = this.placeholderEl,
|
|
96
|
+
s = this.targetEl;
|
|
97
|
+
t.style.height = s.clientHeight - e + 'px';
|
|
98
|
+
}
|
|
99
|
+
#l() {
|
|
100
|
+
const e = this.targetEl;
|
|
101
|
+
if (e) return parseFloat(getComputedStyle(e).lineHeight) || 24;
|
|
102
|
+
}
|
|
103
|
+
#a() {
|
|
104
|
+
const e = this.maxLines,
|
|
105
|
+
t = this.targetEl;
|
|
106
|
+
return 1 === e ? t.scrollWidth > t.clientWidth : t.scrollHeight > t.clientHeight;
|
|
107
|
+
}
|
|
108
|
+
#h() {
|
|
109
|
+
const e = this.targetEl,
|
|
110
|
+
t = this.collapseEl,
|
|
111
|
+
s = this.#e;
|
|
112
|
+
return Math.floor((e.clientHeight - t.clientHeight) / s);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export { i as SmartTextEllipsis };
|
|
116
|
+
//# sourceMappingURL=smart-text-ellipsis.esm.js.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"file": "smart-text-ellipsis.esm.js",
|
|
4
|
+
"sources": [
|
|
5
|
+
"../src/common.js",
|
|
6
|
+
"../src/index.js"
|
|
7
|
+
],
|
|
8
|
+
"sourcesContent": [
|
|
9
|
+
"export function removeElement(element) {\n if (element && element.parentNode) {\n element.parentNode.removeChild(element);\n }\n}\nexport function addElementClass(el, className) {\n el.classList.add(className);\n}\nexport function removeElementClass(el, className) {\n el.classList.remove(className);\n}\n",
|
|
10
|
+
"import { addElementClass, removeElement, removeElementClass } from './common';\nexport class SmartTextEllipsis {\n isDestroyed = false;\n maxLines = 0;\n targetEl = undefined;\n expandEl = undefined;\n collapseEl = undefined;\n placeholderEl = undefined;\n isOpen = false;\n #lineHeight = 0;\n constructor(options = {}) {\n const targetEl = options.targetEl;\n const isOpen = options.isOpen;\n const maxLines = options.maxLines;\n const expandEl = document.createElement('span');\n const collapseEl = document.createElement('div');\n const placeholderEl = document.createElement('div');\n expandEl.innerText = options.expandElText || 'Expand';\n collapseEl.innerText = options.collapseElText || 'Collapse';\n expandEl.onclick = () => {\n this.#handleExpand();\n };\n collapseEl.onclick = () => {\n this.#handleCollapse();\n };\n addElementClass(collapseEl, 'smart-text-ellipsis-collapse');\n addElementClass(expandEl, 'smart-text-ellipsis-expand');\n addElementClass(placeholderEl, 'smart-text-ellipsis-placeholder');\n targetEl.prepend(expandEl);\n targetEl.prepend(placeholderEl);\n targetEl.appendChild(collapseEl);\n this.targetEl = targetEl;\n this.isOpen = isOpen;\n this.maxLines = maxLines;\n this.expandEl = expandEl;\n this.collapseEl = collapseEl;\n this.placeholderEl = placeholderEl;\n this.update();\n }\n /** 销毁实例 */\n destroy() {\n this.isOpen = true;\n removeElement(this.expandEl);\n removeElement(this.collapseEl);\n this.#setupClass();\n this.targetEl = undefined;\n this.expandEl = undefined;\n this.collapseEl = undefined;\n this.isDestroyed = true;\n }\n /** 更新样式 */\n update() {\n if (this.isDestroyed) return;\n this.#lineHeight = this.#getLineHeight();\n this.#setupClass();\n this.#setupPlaceholderStyle();\n this.#setupBtClass();\n }\n #handleExpand() {\n if (this.isDestroyed) return;\n this.isOpen = true;\n this.update();\n }\n #handleCollapse() {\n if (this.isDestroyed) return;\n this.isOpen = false;\n this.update();\n }\n /** 设置容器的类名 */\n #setupClass() {\n const targetEl = this.targetEl;\n if (!targetEl) return;\n if (!this.isDestroyed) {\n targetEl.style.setProperty('--max-lines', `${this.maxLines}`);\n } else {\n targetEl.style.setProperty('--max-lines', undefined);\n }\n if (this.maxLines == 1) {\n addElementClass(targetEl, 'smart-text-ellipsis-one');\n removeElementClass(targetEl, 'smart-text-ellipsis-more');\n } else {\n addElementClass(targetEl, 'smart-text-ellipsis-more');\n removeElementClass(targetEl, 'smart-text-ellipsis-one');\n }\n if (this.isOpen) {\n removeElementClass(targetEl, 'smart-text-ellipsis-more');\n removeElementClass(targetEl, 'smart-text-ellipsis-one');\n }\n removeElementClass(targetEl, 'is-ellipsis');\n removeElementClass(targetEl, 'is-exceeded-max-line');\n }\n /** 设置按钮的类名 */\n #setupBtClass() {\n if (this.isDestroyed) return;\n const targetEl = this.targetEl;\n if (!targetEl) return;\n if (this.isOpen) {\n // 如果行数超过了,显示收缩按钮\n if (this.#getActualLines() > this.maxLines) {\n addElementClass(targetEl, 'is-exceeded-max-line');\n }\n } else {\n // 如果字体省略了,显示展开按钮\n if (this.#isEllipsisActive()) {\n addElementClass(targetEl, 'is-ellipsis');\n }\n }\n }\n /** 设置占位元素的样式 */\n #setupPlaceholderStyle() {\n const lineHeight = this.#lineHeight;\n const placeholderEl = this.placeholderEl;\n const targetEl = this.targetEl;\n placeholderEl.style.height = `${targetEl.clientHeight - lineHeight}px`;\n }\n /** 获取一行文本的高度 */\n #getLineHeight() {\n const targetEl = this.targetEl;\n if (!targetEl) return;\n return parseFloat(getComputedStyle(targetEl).lineHeight) || 24;\n }\n /** 判断是否省略了 */\n #isEllipsisActive() {\n const maxLines = this.maxLines;\n const el = this.targetEl;\n if (maxLines === 1) {\n return el.scrollWidth > el.clientWidth;\n }\n return el.scrollHeight > el.clientHeight;\n }\n /** 获取文本视觉上的行数 */\n #getActualLines() {\n const targetEl = this.targetEl;\n const collapseEl = this.collapseEl;\n const lh = this.#lineHeight;\n return Math.floor((targetEl.clientHeight - collapseEl.clientHeight) / lh);\n }\n}\n"
|
|
11
|
+
],
|
|
12
|
+
"names": [
|
|
13
|
+
"removeElement",
|
|
14
|
+
"element",
|
|
15
|
+
"parentNode",
|
|
16
|
+
"removeChild",
|
|
17
|
+
"addElementClass",
|
|
18
|
+
"el",
|
|
19
|
+
"className",
|
|
20
|
+
"classList",
|
|
21
|
+
"add",
|
|
22
|
+
"removeElementClass",
|
|
23
|
+
"remove",
|
|
24
|
+
"SmartTextEllipsis",
|
|
25
|
+
"isDestroyed",
|
|
26
|
+
"maxLines",
|
|
27
|
+
"targetEl",
|
|
28
|
+
"undefined",
|
|
29
|
+
"expandEl",
|
|
30
|
+
"collapseEl",
|
|
31
|
+
"placeholderEl",
|
|
32
|
+
"isOpen",
|
|
33
|
+
"lineHeight",
|
|
34
|
+
"constructor",
|
|
35
|
+
"options",
|
|
36
|
+
"document",
|
|
37
|
+
"createElement",
|
|
38
|
+
"innerText",
|
|
39
|
+
"expandElText",
|
|
40
|
+
"collapseElText",
|
|
41
|
+
"onclick",
|
|
42
|
+
"this",
|
|
43
|
+
"handleExpand",
|
|
44
|
+
"handleCollapse",
|
|
45
|
+
"prepend",
|
|
46
|
+
"appendChild",
|
|
47
|
+
"update",
|
|
48
|
+
"destroy",
|
|
49
|
+
"setupClass",
|
|
50
|
+
"getLineHeight",
|
|
51
|
+
"setupPlaceholderStyle",
|
|
52
|
+
"setupBtClass",
|
|
53
|
+
"style",
|
|
54
|
+
"setProperty",
|
|
55
|
+
"getActualLines",
|
|
56
|
+
"isEllipsisActive",
|
|
57
|
+
"height",
|
|
58
|
+
"clientHeight",
|
|
59
|
+
"parseFloat",
|
|
60
|
+
"getComputedStyle",
|
|
61
|
+
"scrollWidth",
|
|
62
|
+
"clientWidth",
|
|
63
|
+
"scrollHeight",
|
|
64
|
+
"lh",
|
|
65
|
+
"Math",
|
|
66
|
+
"floor"
|
|
67
|
+
],
|
|
68
|
+
"mappings": "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"
|
|
69
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* smart-text-ellipsis v0.0.2
|
|
3
|
+
* Copyright 2025 wuzhanggui https://github.com/wurencaideli
|
|
4
|
+
* Licensed under MIT
|
|
5
|
+
*/
|
|
6
|
+
!(function (e, t) {
|
|
7
|
+
'object' == typeof exports && 'undefined' != typeof module
|
|
8
|
+
? t(exports)
|
|
9
|
+
: 'function' == typeof define && define.amd
|
|
10
|
+
? define(['exports'], t)
|
|
11
|
+
: t(
|
|
12
|
+
((e = 'undefined' != typeof globalThis ? globalThis : e || self)[
|
|
13
|
+
'smart-text-ellipsis'
|
|
14
|
+
] = {}),
|
|
15
|
+
);
|
|
16
|
+
})(this, function (e) {
|
|
17
|
+
'use strict';
|
|
18
|
+
function t(e) {
|
|
19
|
+
e && e.parentNode && e.parentNode.removeChild(e);
|
|
20
|
+
}
|
|
21
|
+
function s(e, t) {
|
|
22
|
+
e.classList.add(t);
|
|
23
|
+
}
|
|
24
|
+
function i(e, t) {
|
|
25
|
+
e.classList.remove(t);
|
|
26
|
+
}
|
|
27
|
+
e.SmartTextEllipsis = class {
|
|
28
|
+
isDestroyed = !1;
|
|
29
|
+
maxLines = 0;
|
|
30
|
+
targetEl = void 0;
|
|
31
|
+
expandEl = void 0;
|
|
32
|
+
collapseEl = void 0;
|
|
33
|
+
placeholderEl = void 0;
|
|
34
|
+
isOpen = !1;
|
|
35
|
+
#e = 0;
|
|
36
|
+
constructor(e = {}) {
|
|
37
|
+
const t = e.targetEl,
|
|
38
|
+
i = e.isOpen,
|
|
39
|
+
l = e.maxLines,
|
|
40
|
+
n = document.createElement('span'),
|
|
41
|
+
p = document.createElement('div'),
|
|
42
|
+
h = document.createElement('div');
|
|
43
|
+
(n.innerText = e.expandElText || 'Expand'),
|
|
44
|
+
(p.innerText = e.collapseElText || 'Collapse'),
|
|
45
|
+
(n.onclick = () => {
|
|
46
|
+
this.#t();
|
|
47
|
+
}),
|
|
48
|
+
(p.onclick = () => {
|
|
49
|
+
this.#s();
|
|
50
|
+
}),
|
|
51
|
+
s(p, 'smart-text-ellipsis-collapse'),
|
|
52
|
+
s(n, 'smart-text-ellipsis-expand'),
|
|
53
|
+
s(h, 'smart-text-ellipsis-placeholder'),
|
|
54
|
+
t.prepend(n),
|
|
55
|
+
t.prepend(h),
|
|
56
|
+
t.appendChild(p),
|
|
57
|
+
(this.targetEl = t),
|
|
58
|
+
(this.isOpen = i),
|
|
59
|
+
(this.maxLines = l),
|
|
60
|
+
(this.expandEl = n),
|
|
61
|
+
(this.collapseEl = p),
|
|
62
|
+
(this.placeholderEl = h),
|
|
63
|
+
this.update();
|
|
64
|
+
}
|
|
65
|
+
destroy() {
|
|
66
|
+
(this.isOpen = !0),
|
|
67
|
+
t(this.expandEl),
|
|
68
|
+
t(this.collapseEl),
|
|
69
|
+
this.#i(),
|
|
70
|
+
(this.targetEl = void 0),
|
|
71
|
+
(this.expandEl = void 0),
|
|
72
|
+
(this.collapseEl = void 0),
|
|
73
|
+
(this.isDestroyed = !0);
|
|
74
|
+
}
|
|
75
|
+
update() {
|
|
76
|
+
this.isDestroyed || ((this.#e = this.#l()), this.#i(), this.#n(), this.#p());
|
|
77
|
+
}
|
|
78
|
+
#t() {
|
|
79
|
+
this.isDestroyed || ((this.isOpen = !0), this.update());
|
|
80
|
+
}
|
|
81
|
+
#s() {
|
|
82
|
+
this.isDestroyed || ((this.isOpen = !1), this.update());
|
|
83
|
+
}
|
|
84
|
+
#i() {
|
|
85
|
+
const e = this.targetEl;
|
|
86
|
+
e &&
|
|
87
|
+
(this.isDestroyed
|
|
88
|
+
? e.style.setProperty('--max-lines', void 0)
|
|
89
|
+
: e.style.setProperty('--max-lines', `${this.maxLines}`),
|
|
90
|
+
1 == this.maxLines
|
|
91
|
+
? (s(e, 'smart-text-ellipsis-one'), i(e, 'smart-text-ellipsis-more'))
|
|
92
|
+
: (s(e, 'smart-text-ellipsis-more'), i(e, 'smart-text-ellipsis-one')),
|
|
93
|
+
this.isOpen && (i(e, 'smart-text-ellipsis-more'), i(e, 'smart-text-ellipsis-one')),
|
|
94
|
+
i(e, 'is-ellipsis'),
|
|
95
|
+
i(e, 'is-exceeded-max-line'));
|
|
96
|
+
}
|
|
97
|
+
#p() {
|
|
98
|
+
if (this.isDestroyed) return;
|
|
99
|
+
const e = this.targetEl;
|
|
100
|
+
e &&
|
|
101
|
+
(this.isOpen
|
|
102
|
+
? this.#h() > this.maxLines && s(e, 'is-exceeded-max-line')
|
|
103
|
+
: this.#o() && s(e, 'is-ellipsis'));
|
|
104
|
+
}
|
|
105
|
+
#n() {
|
|
106
|
+
const e = this.#e,
|
|
107
|
+
t = this.placeholderEl,
|
|
108
|
+
s = this.targetEl;
|
|
109
|
+
t.style.height = s.clientHeight - e + 'px';
|
|
110
|
+
}
|
|
111
|
+
#l() {
|
|
112
|
+
const e = this.targetEl;
|
|
113
|
+
if (e) return parseFloat(getComputedStyle(e).lineHeight) || 24;
|
|
114
|
+
}
|
|
115
|
+
#o() {
|
|
116
|
+
const e = this.maxLines,
|
|
117
|
+
t = this.targetEl;
|
|
118
|
+
return 1 === e ? t.scrollWidth > t.clientWidth : t.scrollHeight > t.clientHeight;
|
|
119
|
+
}
|
|
120
|
+
#h() {
|
|
121
|
+
const e = this.targetEl,
|
|
122
|
+
t = this.collapseEl,
|
|
123
|
+
s = this.#e;
|
|
124
|
+
return Math.floor((e.clientHeight - t.clientHeight) / s);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
});
|
|
128
|
+
//# sourceMappingURL=smart-text-ellipsis.umd.js.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"file": "smart-text-ellipsis.umd.js",
|
|
4
|
+
"sources": [
|
|
5
|
+
"../src/common.js",
|
|
6
|
+
"../src/index.js"
|
|
7
|
+
],
|
|
8
|
+
"sourcesContent": [
|
|
9
|
+
"export function removeElement(element) {\n if (element && element.parentNode) {\n element.parentNode.removeChild(element);\n }\n}\nexport function addElementClass(el, className) {\n el.classList.add(className);\n}\nexport function removeElementClass(el, className) {\n el.classList.remove(className);\n}\n",
|
|
10
|
+
"import { addElementClass, removeElement, removeElementClass } from './common';\nexport class SmartTextEllipsis {\n isDestroyed = false;\n maxLines = 0;\n targetEl = undefined;\n expandEl = undefined;\n collapseEl = undefined;\n placeholderEl = undefined;\n isOpen = false;\n #lineHeight = 0;\n constructor(options = {}) {\n const targetEl = options.targetEl;\n const isOpen = options.isOpen;\n const maxLines = options.maxLines;\n const expandEl = document.createElement('span');\n const collapseEl = document.createElement('div');\n const placeholderEl = document.createElement('div');\n expandEl.innerText = options.expandElText || 'Expand';\n collapseEl.innerText = options.collapseElText || 'Collapse';\n expandEl.onclick = () => {\n this.#handleExpand();\n };\n collapseEl.onclick = () => {\n this.#handleCollapse();\n };\n addElementClass(collapseEl, 'smart-text-ellipsis-collapse');\n addElementClass(expandEl, 'smart-text-ellipsis-expand');\n addElementClass(placeholderEl, 'smart-text-ellipsis-placeholder');\n targetEl.prepend(expandEl);\n targetEl.prepend(placeholderEl);\n targetEl.appendChild(collapseEl);\n this.targetEl = targetEl;\n this.isOpen = isOpen;\n this.maxLines = maxLines;\n this.expandEl = expandEl;\n this.collapseEl = collapseEl;\n this.placeholderEl = placeholderEl;\n this.update();\n }\n /** 销毁实例 */\n destroy() {\n this.isOpen = true;\n removeElement(this.expandEl);\n removeElement(this.collapseEl);\n this.#setupClass();\n this.targetEl = undefined;\n this.expandEl = undefined;\n this.collapseEl = undefined;\n this.isDestroyed = true;\n }\n /** 更新样式 */\n update() {\n if (this.isDestroyed) return;\n this.#lineHeight = this.#getLineHeight();\n this.#setupClass();\n this.#setupPlaceholderStyle();\n this.#setupBtClass();\n }\n #handleExpand() {\n if (this.isDestroyed) return;\n this.isOpen = true;\n this.update();\n }\n #handleCollapse() {\n if (this.isDestroyed) return;\n this.isOpen = false;\n this.update();\n }\n /** 设置容器的类名 */\n #setupClass() {\n const targetEl = this.targetEl;\n if (!targetEl) return;\n if (!this.isDestroyed) {\n targetEl.style.setProperty('--max-lines', `${this.maxLines}`);\n } else {\n targetEl.style.setProperty('--max-lines', undefined);\n }\n if (this.maxLines == 1) {\n addElementClass(targetEl, 'smart-text-ellipsis-one');\n removeElementClass(targetEl, 'smart-text-ellipsis-more');\n } else {\n addElementClass(targetEl, 'smart-text-ellipsis-more');\n removeElementClass(targetEl, 'smart-text-ellipsis-one');\n }\n if (this.isOpen) {\n removeElementClass(targetEl, 'smart-text-ellipsis-more');\n removeElementClass(targetEl, 'smart-text-ellipsis-one');\n }\n removeElementClass(targetEl, 'is-ellipsis');\n removeElementClass(targetEl, 'is-exceeded-max-line');\n }\n /** 设置按钮的类名 */\n #setupBtClass() {\n if (this.isDestroyed) return;\n const targetEl = this.targetEl;\n if (!targetEl) return;\n if (this.isOpen) {\n // 如果行数超过了,显示收缩按钮\n if (this.#getActualLines() > this.maxLines) {\n addElementClass(targetEl, 'is-exceeded-max-line');\n }\n } else {\n // 如果字体省略了,显示展开按钮\n if (this.#isEllipsisActive()) {\n addElementClass(targetEl, 'is-ellipsis');\n }\n }\n }\n /** 设置占位元素的样式 */\n #setupPlaceholderStyle() {\n const lineHeight = this.#lineHeight;\n const placeholderEl = this.placeholderEl;\n const targetEl = this.targetEl;\n placeholderEl.style.height = `${targetEl.clientHeight - lineHeight}px`;\n }\n /** 获取一行文本的高度 */\n #getLineHeight() {\n const targetEl = this.targetEl;\n if (!targetEl) return;\n return parseFloat(getComputedStyle(targetEl).lineHeight) || 24;\n }\n /** 判断是否省略了 */\n #isEllipsisActive() {\n const maxLines = this.maxLines;\n const el = this.targetEl;\n if (maxLines === 1) {\n return el.scrollWidth > el.clientWidth;\n }\n return el.scrollHeight > el.clientHeight;\n }\n /** 获取文本视觉上的行数 */\n #getActualLines() {\n const targetEl = this.targetEl;\n const collapseEl = this.collapseEl;\n const lh = this.#lineHeight;\n return Math.floor((targetEl.clientHeight - collapseEl.clientHeight) / lh);\n }\n}\n"
|
|
11
|
+
],
|
|
12
|
+
"names": [
|
|
13
|
+
"removeElement",
|
|
14
|
+
"element",
|
|
15
|
+
"parentNode",
|
|
16
|
+
"removeChild",
|
|
17
|
+
"addElementClass",
|
|
18
|
+
"el",
|
|
19
|
+
"className",
|
|
20
|
+
"classList",
|
|
21
|
+
"add",
|
|
22
|
+
"removeElementClass",
|
|
23
|
+
"remove",
|
|
24
|
+
"isDestroyed",
|
|
25
|
+
"maxLines",
|
|
26
|
+
"targetEl",
|
|
27
|
+
"undefined",
|
|
28
|
+
"expandEl",
|
|
29
|
+
"collapseEl",
|
|
30
|
+
"placeholderEl",
|
|
31
|
+
"isOpen",
|
|
32
|
+
"lineHeight",
|
|
33
|
+
"constructor",
|
|
34
|
+
"options",
|
|
35
|
+
"document",
|
|
36
|
+
"createElement",
|
|
37
|
+
"innerText",
|
|
38
|
+
"expandElText",
|
|
39
|
+
"collapseElText",
|
|
40
|
+
"onclick",
|
|
41
|
+
"this",
|
|
42
|
+
"handleExpand",
|
|
43
|
+
"handleCollapse",
|
|
44
|
+
"prepend",
|
|
45
|
+
"appendChild",
|
|
46
|
+
"update",
|
|
47
|
+
"destroy",
|
|
48
|
+
"setupClass",
|
|
49
|
+
"getLineHeight",
|
|
50
|
+
"setupPlaceholderStyle",
|
|
51
|
+
"setupBtClass",
|
|
52
|
+
"style",
|
|
53
|
+
"setProperty",
|
|
54
|
+
"getActualLines",
|
|
55
|
+
"isEllipsisActive",
|
|
56
|
+
"height",
|
|
57
|
+
"clientHeight",
|
|
58
|
+
"parseFloat",
|
|
59
|
+
"getComputedStyle",
|
|
60
|
+
"scrollWidth",
|
|
61
|
+
"clientWidth",
|
|
62
|
+
"scrollHeight",
|
|
63
|
+
"lh",
|
|
64
|
+
"Math",
|
|
65
|
+
"floor"
|
|
66
|
+
],
|
|
67
|
+
"mappings": "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"
|
|
68
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "smart-text-ellipsis",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "A simple custom scrollbar plugin",
|
|
5
|
+
"author": "wuzhanggui",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"ellipsis"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://wurencaideli.github.io/smart-text-ellipsis/demo.html",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/wurencaideli/smart-text-ellipsis"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/wurencaideli/smart-text-ellipsis/issues"
|
|
18
|
+
},
|
|
19
|
+
"jspm": {
|
|
20
|
+
"main": "dist/smart-text-ellipsis.cjs.js",
|
|
21
|
+
"registry": "jspm"
|
|
22
|
+
},
|
|
23
|
+
"main": "dist/smart-text-ellipsis.cjs.js",
|
|
24
|
+
"module": "dist/smart-text-ellipsis.esm.js",
|
|
25
|
+
"style": "dist/smart-text-ellipsis.css",
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"src"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"dev": "rollup -c -w",
|
|
32
|
+
"build": "rollup -c",
|
|
33
|
+
"build-sass": "node ./build-sass.js"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@rollup/plugin-commonjs": "^28.0.6",
|
|
37
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
38
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
39
|
+
"autoprefixer": "^10.4.21",
|
|
40
|
+
"clean-css": "^5.3.3",
|
|
41
|
+
"postcss": "^8.5.6",
|
|
42
|
+
"postcss-preset-env": "^10.2.3",
|
|
43
|
+
"rollup": "^3.29.5",
|
|
44
|
+
"sass": "^1.89.2"
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/common.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function removeElement(element) {
|
|
2
|
+
if (element && element.parentNode) {
|
|
3
|
+
element.parentNode.removeChild(element);
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
export function addElementClass(el, className) {
|
|
7
|
+
el.classList.add(className);
|
|
8
|
+
}
|
|
9
|
+
export function removeElementClass(el, className) {
|
|
10
|
+
el.classList.remove(className);
|
|
11
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { addElementClass, removeElement, removeElementClass } from './common';
|
|
2
|
+
export class SmartTextEllipsis {
|
|
3
|
+
isDestroyed = false;
|
|
4
|
+
maxLines = 0;
|
|
5
|
+
targetEl = undefined;
|
|
6
|
+
expandEl = undefined;
|
|
7
|
+
collapseEl = undefined;
|
|
8
|
+
placeholderEl = undefined;
|
|
9
|
+
isOpen = false;
|
|
10
|
+
#lineHeight = 0;
|
|
11
|
+
constructor(options = {}) {
|
|
12
|
+
const targetEl = options.targetEl;
|
|
13
|
+
const isOpen = options.isOpen;
|
|
14
|
+
const maxLines = options.maxLines;
|
|
15
|
+
const expandEl = document.createElement('span');
|
|
16
|
+
const collapseEl = document.createElement('div');
|
|
17
|
+
const placeholderEl = document.createElement('div');
|
|
18
|
+
expandEl.innerText = options.expandElText || 'Expand';
|
|
19
|
+
collapseEl.innerText = options.collapseElText || 'Collapse';
|
|
20
|
+
expandEl.onclick = () => {
|
|
21
|
+
this.#handleExpand();
|
|
22
|
+
};
|
|
23
|
+
collapseEl.onclick = () => {
|
|
24
|
+
this.#handleCollapse();
|
|
25
|
+
};
|
|
26
|
+
addElementClass(collapseEl, 'smart-text-ellipsis-collapse');
|
|
27
|
+
addElementClass(expandEl, 'smart-text-ellipsis-expand');
|
|
28
|
+
addElementClass(placeholderEl, 'smart-text-ellipsis-placeholder');
|
|
29
|
+
targetEl.prepend(expandEl);
|
|
30
|
+
targetEl.prepend(placeholderEl);
|
|
31
|
+
targetEl.appendChild(collapseEl);
|
|
32
|
+
this.targetEl = targetEl;
|
|
33
|
+
this.isOpen = isOpen;
|
|
34
|
+
this.maxLines = maxLines;
|
|
35
|
+
this.expandEl = expandEl;
|
|
36
|
+
this.collapseEl = collapseEl;
|
|
37
|
+
this.placeholderEl = placeholderEl;
|
|
38
|
+
this.update();
|
|
39
|
+
}
|
|
40
|
+
/** 销毁实例 */
|
|
41
|
+
destroy() {
|
|
42
|
+
this.isOpen = true;
|
|
43
|
+
removeElement(this.expandEl);
|
|
44
|
+
removeElement(this.collapseEl);
|
|
45
|
+
this.#setupClass();
|
|
46
|
+
this.targetEl = undefined;
|
|
47
|
+
this.expandEl = undefined;
|
|
48
|
+
this.collapseEl = undefined;
|
|
49
|
+
this.isDestroyed = true;
|
|
50
|
+
}
|
|
51
|
+
/** 更新样式 */
|
|
52
|
+
update() {
|
|
53
|
+
if (this.isDestroyed) return;
|
|
54
|
+
this.#lineHeight = this.#getLineHeight();
|
|
55
|
+
this.#setupClass();
|
|
56
|
+
this.#setupPlaceholderStyle();
|
|
57
|
+
this.#setupBtClass();
|
|
58
|
+
}
|
|
59
|
+
#handleExpand() {
|
|
60
|
+
if (this.isDestroyed) return;
|
|
61
|
+
this.isOpen = true;
|
|
62
|
+
this.update();
|
|
63
|
+
}
|
|
64
|
+
#handleCollapse() {
|
|
65
|
+
if (this.isDestroyed) return;
|
|
66
|
+
this.isOpen = false;
|
|
67
|
+
this.update();
|
|
68
|
+
}
|
|
69
|
+
/** 设置容器的类名 */
|
|
70
|
+
#setupClass() {
|
|
71
|
+
const targetEl = this.targetEl;
|
|
72
|
+
if (!targetEl) return;
|
|
73
|
+
if (!this.isDestroyed) {
|
|
74
|
+
targetEl.style.setProperty('--max-lines', `${this.maxLines}`);
|
|
75
|
+
} else {
|
|
76
|
+
targetEl.style.setProperty('--max-lines', undefined);
|
|
77
|
+
}
|
|
78
|
+
if (this.maxLines == 1) {
|
|
79
|
+
addElementClass(targetEl, 'smart-text-ellipsis-one');
|
|
80
|
+
removeElementClass(targetEl, 'smart-text-ellipsis-more');
|
|
81
|
+
} else {
|
|
82
|
+
addElementClass(targetEl, 'smart-text-ellipsis-more');
|
|
83
|
+
removeElementClass(targetEl, 'smart-text-ellipsis-one');
|
|
84
|
+
}
|
|
85
|
+
if (this.isOpen) {
|
|
86
|
+
removeElementClass(targetEl, 'smart-text-ellipsis-more');
|
|
87
|
+
removeElementClass(targetEl, 'smart-text-ellipsis-one');
|
|
88
|
+
}
|
|
89
|
+
removeElementClass(targetEl, 'is-ellipsis');
|
|
90
|
+
removeElementClass(targetEl, 'is-exceeded-max-line');
|
|
91
|
+
}
|
|
92
|
+
/** 设置按钮的类名 */
|
|
93
|
+
#setupBtClass() {
|
|
94
|
+
if (this.isDestroyed) return;
|
|
95
|
+
const targetEl = this.targetEl;
|
|
96
|
+
if (!targetEl) return;
|
|
97
|
+
if (this.isOpen) {
|
|
98
|
+
// 如果行数超过了,显示收缩按钮
|
|
99
|
+
if (this.#getActualLines() > this.maxLines) {
|
|
100
|
+
addElementClass(targetEl, 'is-exceeded-max-line');
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
// 如果字体省略了,显示展开按钮
|
|
104
|
+
if (this.#isEllipsisActive()) {
|
|
105
|
+
addElementClass(targetEl, 'is-ellipsis');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** 设置占位元素的样式 */
|
|
110
|
+
#setupPlaceholderStyle() {
|
|
111
|
+
const lineHeight = this.#lineHeight;
|
|
112
|
+
const placeholderEl = this.placeholderEl;
|
|
113
|
+
const targetEl = this.targetEl;
|
|
114
|
+
placeholderEl.style.height = `${targetEl.clientHeight - lineHeight}px`;
|
|
115
|
+
}
|
|
116
|
+
/** 获取一行文本的高度 */
|
|
117
|
+
#getLineHeight() {
|
|
118
|
+
const targetEl = this.targetEl;
|
|
119
|
+
if (!targetEl) return;
|
|
120
|
+
return parseFloat(getComputedStyle(targetEl).lineHeight) || 24;
|
|
121
|
+
}
|
|
122
|
+
/** 判断是否省略了 */
|
|
123
|
+
#isEllipsisActive() {
|
|
124
|
+
const maxLines = this.maxLines;
|
|
125
|
+
const el = this.targetEl;
|
|
126
|
+
if (maxLines === 1) {
|
|
127
|
+
return el.scrollWidth > el.clientWidth;
|
|
128
|
+
}
|
|
129
|
+
return el.scrollHeight > el.clientHeight;
|
|
130
|
+
}
|
|
131
|
+
/** 获取文本视觉上的行数 */
|
|
132
|
+
#getActualLines() {
|
|
133
|
+
const targetEl = this.targetEl;
|
|
134
|
+
const collapseEl = this.collapseEl;
|
|
135
|
+
const lh = this.#lineHeight;
|
|
136
|
+
return Math.floor((targetEl.clientHeight - collapseEl.clientHeight) / lh);
|
|
137
|
+
}
|
|
138
|
+
}
|
package/src/index.scss
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
.smart-text-ellipsis-more {
|
|
2
|
+
display: -webkit-box;
|
|
3
|
+
-webkit-line-clamp: var(--max-lines);
|
|
4
|
+
-webkit-box-orient: vertical;
|
|
5
|
+
display: -moz-box; /* 旧 Firefox 私有(已废弃)可省略 */
|
|
6
|
+
line-clamp: var(--max-lines); /* 标准属性 */
|
|
7
|
+
box-orient: vertical;
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
}
|
|
10
|
+
.smart-text-ellipsis-one {
|
|
11
|
+
white-space: nowrap;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
text-overflow: ellipsis;
|
|
14
|
+
}
|
|
15
|
+
.is-ellipsis {
|
|
16
|
+
> .smart-text-ellipsis-expand {
|
|
17
|
+
display: initial;
|
|
18
|
+
}
|
|
19
|
+
> .smart-text-ellipsis-placeholder {
|
|
20
|
+
display: initial;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
.is-exceeded-max-line {
|
|
24
|
+
> .smart-text-ellipsis-collapse {
|
|
25
|
+
display: flex;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
.smart-text-ellipsis-expand {
|
|
29
|
+
display: none;
|
|
30
|
+
float: right;
|
|
31
|
+
clear: both;
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
color: #1178d9;
|
|
34
|
+
position: relative;
|
|
35
|
+
z-index: 2;
|
|
36
|
+
}
|
|
37
|
+
.smart-text-ellipsis-collapse {
|
|
38
|
+
display: none;
|
|
39
|
+
flex-direction: row;
|
|
40
|
+
justify-content: flex-end;
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
color: #1178d9;
|
|
43
|
+
position: relative;
|
|
44
|
+
z-index: 2;
|
|
45
|
+
}
|
|
46
|
+
.smart-text-ellipsis-placeholder {
|
|
47
|
+
display: none;
|
|
48
|
+
float: right;
|
|
49
|
+
width: 0;
|
|
50
|
+
pointer-events: none;
|
|
51
|
+
}
|