-
Notifications
You must be signed in to change notification settings - Fork 5
/
siderMenu.js
153 lines (148 loc) · 5.2 KB
/
siderMenu.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
class SiderContent extends HTMLDivElement {
static new(ele, minWidth) {
Object.setPrototypeOf(ele, SiderContent.prototype);
SiderContent.prototype.init.call(ele, minWidth);
return ele;
}
init(minWidth) {
this.resize = this._resize.bind(this);
this.mouseup = this._mouseup.bind(this);
this.mousedown = this._mousedown.bind(this);
this.classList.add('siderContent');
this.minWidth = minWidth;
this.judge = (minWidth >> 1) + this.getBoundingClientRect().left;
this.style.width = minWidth + 'px';
const bar = document.createElement('div');
bar.className = 'siderBar';
this.insertAdjacentElement('afterend', bar);
bar.addEventListener('mousedown', this.mousedown);
this.bar = bar;
}
_mousedown(e) {
if (e.button) return;
document.addEventListener('mousemove', this.resize);
document.addEventListener('mouseup', this.mouseup);
}
_resize(e) {
if (e.clientX < this.judge) this.display = 'none';
else {
let rect = this.getBoundingClientRect();
let w = e.clientX - rect.left;
if (w < this.minWidth) return;
// 触发刷新
this.width = w + 'px';
this.display = 'block';
}
}
_mouseup() {
document.removeEventListener('mousemove', this.resize);
document.removeEventListener('mouseup', this.mouseup);
this.bar.blur();
window.dispatchEvent(new Event("resize")); // 触发app.resize
}
get display() {
return this.style.display;
}
// 设置display可以触发刷新 因为app.resize绑定在window.onresize上
set display(state) {
if (this.style.display != state) {
this.style.display = state;
window.dispatchEvent(new Event("resize"));
}
}
get width() {
return this.style.width;
}
set width(w) {
if (this.style.width != w) {
this.style.width = w;
window.dispatchEvent(new Event("resize"));
}
}
}
class SiderMenu extends HTMLDivElement {
/**
* 构造tabMenu和container
* @param {HTMLDivElement} menu 存放tab的 样式: .siderTabs 每一个tab: .siderTab
* @param {HTMLDivElement} container 展示具体内容的 样式: .siderContent 拖动条: .siderBar 每一个子内容都会加上siderItem类
* @param {Number} minWidth 展示具体内容的最小宽度
* @returns
*/
static new(menu, container, minWidth) {
Object.setPrototypeOf(menu, SiderMenu.prototype);
SiderMenu.prototype.init.call(menu, container, minWidth);
return menu;
}
init(box, minWidth) {
this.classList.add('siderTabs');
this.container = SiderContent.new(box, minWidth);
box.display = 'none';
this.tabClick = this._tabClick.bind(this);
this.tabs = [];
}
/**
* 添加一个菜单项及其内容
* @param {String} name tab的名字
* @param {String} tabClass tab的类名 用空格分隔
* @param {HTMLElement} dom tab对应的内容
* @param {Boolean} selected 是否默认选中
* @returns {HTMLDivElement} 添加的tab
*/
add(name, tabClass, dom, selected = false) {
const tab = document.createElement('div');
tab.className = 'siderTab';
tab.classList.add(...tabClass.split(' '));
tab.dataset.name = name;
this.container.appendChild(dom);
dom.classList.add('siderItem');
dom.style.display = 'none';
tab.item = dom;
tab.addEventListener('click', this.tabClick);
this.appendChild(tab);
if (this.tabs.push(tab) == 1) {
tab.classList.add('selected');
dom.style.display = 'block';
} else if (selected) this.select(tab);
return tab;
}
/**
* 选中一个标签
* @param {HTMLDivElement || Number} tab
* @returns {HTMLDivElement} 选择的标签
*/
select(tab) {
if (typeof tab == 'number') tab = this.tabs[tab];
if (!tab) return;
for (const t of this.tabs) {
t.classList.remove('selected');
t.item.style.display = 'none';
}
tab.classList.add('selected');
tab.item.style.display = 'block';
return tab;
}
/**
* 控制面板的显示
* @param {Boolean} ifshow 是否显示面板
*/
show(ifshow = true) {
this.container.display = ifshow ? 'block' : 'none';
}
// 绑定给tab用,不应该用户被调用
_tabClick(e) {
const tab = e.target;
if (tab.classList.contains('selected')) { // 如果显示的就是tab的,则隐藏
// 用style.dispaly是读取,用.display = 是为了刷新
this.container.display = this.container.style.display == 'none' ? 'block' : 'none';
} else { // 否则只显示tab的
for (const t of this.tabs) {
t.classList.remove('selected');
t.item.style.display = 'none';
}
tab.classList.add('selected');
this.container.display = 'block';
}
tab.item.style.display = 'block';
tab.blur();
}
}