UNPKG

6.12 kBJavaScriptView Raw
1
2export const TabSectionConfig = {
3
4 tagName: 'tabsection',
5 tagNameList: 'tablist',
6 tagNameTab: 'tab',
7 tagNamePanel: 'tabpanel',
8
9 animate: true,
10 animationDelay: 0.15,
11 classFade: 'fade',
12 classFadeIn: 'active'
13
14};
15
16export const TabSectionUI = {
17
18 Config: TabSectionConfig,
19
20 getAllTabSections(node = document) {
21 return node.getElementsByTagName(this.Config.tagName);
22 },
23
24 getTabList(tabsection) {
25 return tabsection.getElementsByTagName(this.Config.tagNameList)[0] || false;
26 },
27
28 getTabs(tablist) {
29 return tablist.getElementsByTagName(this.Config.tagNameTab);
30 },
31
32 getTabPanels(tabsection) {
33 return tabsection.getElementsByTagName(this.Config.tagNamePanel);
34 },
35
36 getActiveTab(tabsection) {
37 const tabList = this.getTabList(tabsection);
38 const tabs = this.getTabs(tabList);
39 for (let k = 0; k < tabs.length; k++) {
40 if (tabs[k].hasAttribute('selected')) {
41 return tabs[k];
42 }
43 }
44 return false;
45 },
46
47 getActiveTabPanel(tabsection) {
48 const tabpanels = this.getTabPanels(tabsection);
49 for (let k = 0; k < tabpanels.length; k++) {
50 if (!tabpanels[k].hasAttribute('hidden')) {
51 return tabpanels[k];
52 }
53 }
54 return false;
55 },
56
57 getTabSectionByTab(tab) {
58 return tab.parentNode.parentNode;
59 },
60
61 getTabSectionByTabPanel(tabpanel) {
62 return tabpanel.parentNode;
63 },
64
65 getTabIndex(tab) {
66 return [].indexOf.call(tab.parentNode.children, tab);
67 },
68
69 getTabPanelIndex(tabpanel) {
70 const tabsection = this.getTabSectionByTabPanel(tabpanel);
71 const tabpanels = this.getTabPanels(tabsection);
72 let tabPanelIndex = 0;
73 [].forEach.call(tabpanels, tp => {
74 if (tp === tabpanel) {
75 return tabPanelIndex;
76 }
77 tabPanelIndex++;
78 });
79 return false;
80 },
81
82 getTabPanelByTab(tab) {
83 const tabIndex = this.getTabIndex(tab);
84 const tabsection = this.getTabSectionByTab(tab);
85 const tabpanels = this.getTabPanels(tabsection);
86 return tabpanels[tabIndex];
87 },
88
89 getTabByTabPanel(tabpanel) {
90 const tabPanelIndex = this.getTabPanelIndex(tabpanel);
91 const tabsection = this.getTabSectionByTabPanel(tabpanel);
92 const tablist = this.getTabList(tabsection);
93 const tabs = this.getTabs(tablist);
94 return tabs[tabPanelIndex];
95 },
96
97 setTabActive(tab) {
98 tab.setAttribute('selected', '');
99 },
100
101 setTabInactive(tab) {
102 tab.removeAttribute('selected');
103 },
104
105 setTabPanelVisible(tabpanel) {
106 return new Promise(resolve => {
107 if (this.Config.animate) {
108 tabpanel.removeAttribute('hidden');
109 tabpanel.classList.add(this.Config.classFadeIn);
110 setTimeout(() => {
111 resolve();
112 }, this.Config.animationDelay * 1000);
113 } else {
114 tabpanel.removeAttribute('hidden');
115 resolve();
116 }
117 });
118 },
119
120 setTabPanelHidden(tabpanel) {
121 return new Promise(resolve => {
122 if (this.Config.animate) {
123 tabpanel.classList.remove(this.Config.classFadeIn);
124 setTimeout(() => {
125 tabpanel.setAttribute('hidden', '');
126 resolve();
127 }, this.Config.animationDelay * 1000);
128 } else {
129 tabpanel.setAttribute('hidden', '');
130 resolve();
131 }
132 });
133 },
134
135 switchTab(tab) {
136 const tabsection = this.getTabSectionByTab(tab);
137 const tabpanel = this.getTabPanelByTab(tab);
138 const activeTab = this.getActiveTab(tabsection);
139 const activeTabPanel = this.getActiveTabPanel(tabsection);
140
141 if (tab !== activeTab) {
142 this.setTabInactive(activeTab);
143 this.setTabPanelHidden(activeTabPanel).then(() => {
144 this.setTabActive(tab);
145 this.setTabPanelVisible(tabpanel);
146 });
147 }
148 },
149
150 switchTabPanel(tabpanel) {
151 const tab = this.getTabByTabPanel(tabpanel);
152 const tabsection = this.getTabSectionByTabPanel(tabpanel);
153 const activeTab = this.getActiveTab(tabsection);
154 const activeTabPanel = this.getActiveTabPanel(tabsection);
155
156 if (tabpanel !== activeTabPanel) {
157 this.setTabInactive(activeTab);
158 this.setTabPanelHidden(activeTabPanel).then(() => {
159 this.setTabActive(tab);
160 this.setTabPanelVisible(tabpanel);
161 });
162 }
163 },
164
165};
166
167export const TabSection = {
168
169 Config: TabSectionConfig,
170 UI: TabSectionUI,
171
172 init(tabsection) {
173 this.addEvents(tabsection);
174 if (this.Config.animate) {
175 this.initAnimationClass(tabsection);
176 }
177 },
178
179 initAll() {
180 const tabsections = this.UI.getAllTabSections();
181 [].forEach.call(tabsections, tabsection => {
182 this.init(tabsection);
183 })
184 },
185
186 addEvents(tabsection) {
187 const tablist = this.UI.getTabList(tabsection);
188 const tabs = this.UI.getTabs(tablist);
189 [].forEach.call(tabs, tab => {
190 tab.addEventListener('click', () => {
191 this.UI.switchTab(tab);
192 });
193 })
194 },
195
196 initAnimationClass(tabsection) {
197 const tabpanels = this.UI.getTabPanels(tabsection);
198 [].forEach.call(tabpanels, tabpanel => {
199 tabpanel.classList.add(this.Config.classFade);
200 });
201 const actibeTabPanel = this.UI.getActiveTabPanel(tabsection);
202 actibeTabPanel.classList.add(this.Config.classFadeIn);
203 }
204
205};
206
207document.addEventListener('DOMContentLoaded', () => {
208 TabSection.initAll();
209});