Skip to content

Commit 6aecf92

Browse files
committed
v1.0.5 release.
1 parent 2146c04 commit 6aecf92

3 files changed

Lines changed: 67 additions & 83 deletions

File tree

dist/hemenu.js

Lines changed: 64 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* heMenu v1.0.4
2+
* heMenu v1.0.5
33
* https://github.com/meceware/heMenu
44
*
55
* Made by Mehmet Celik (https://www.meceware.com/)
@@ -29,9 +29,9 @@
2929
// If the global wrapper (window) is undefined, do nothing
3030
if ('undefined' === typeof global.document) {
3131
return;
32-
} // Default options
33-
32+
}
3433

34+
// Default options
3535
const defaults = {
3636
menu: '.hemenu-menu',
3737
trigger: null,
@@ -40,7 +40,6 @@
4040
theme: 'light',
4141
position: 'left'
4242
};
43-
4443
const forEach = (array, callback, scope) => {
4544
for (let i = 0; i < array.length; i++) {
4645
callback.call(scope, array[i]); // passes back stuff we need
@@ -52,97 +51,92 @@
5251
if (element.matches(selector)) {
5352
return element;
5453
}
55-
5654
element = element.parentElement || element.parentNode;
5755
}
58-
5956
return null;
6057
};
61-
6258
class heMenu {
6359
constructor(wrapper, options = {}) {
6460
// const isIE11 = navigator.userAgent.indexOf( 'MSIE' ) > -1 || navigator.appVersion.indexOf( 'Trident/' ) > -1;
6561
const getElement = (el, parent = document) => {
6662
if (el) {
6763
return 'string' === typeof el ? parent.querySelector(el) : el;
6864
}
69-
7065
return null;
71-
}; // Extend options
72-
66+
};
7367

68+
// Extend options
7469
Object.keys(defaults).forEach(key => {
7570
if (!Object.prototype.hasOwnProperty.call(options, key)) {
7671
options[key] = defaults[key];
7772
}
78-
}); // Set options
79-
80-
this.options = options; // Get the container
73+
});
8174

82-
this.wrapper = getElement(wrapper); // Check if wrapper exists
75+
// Set options
76+
this.options = options;
77+
// Get the container
78+
this.wrapper = getElement(wrapper);
8379

80+
// Check if wrapper exists
8481
if (!this.wrapper) {
8582
return;
86-
} // Disable double initialization
87-
83+
}
8884

85+
// Disable double initialization
8986
if (this.wrapper.heMenu) {
9087
return;
91-
} // Set position
92-
88+
}
9389

90+
// Set position
9491
forEach(['hemenu', `hemenu-${this.options.position}`, `hemenu-theme-${this.options.theme}`], cls => {
9592
this.wrapper.classList.add(cls);
96-
}); // Get menu element
93+
});
9794

98-
this.menu = getElement(this.options.menu, this.wrapper); // Check if the menu exists
95+
// Get menu element
96+
this.menu = getElement(this.options.menu, this.wrapper);
9997

98+
// Check if the menu exists
10099
if (this.menu) {
101-
this.menu.classList.add('hemenu-navbar'); // Create title element and append it as the first child of the menu
100+
this.menu.classList.add('hemenu-navbar');
102101

102+
// Create title element and append it as the first child of the menu
103103
this.menuTitle = document.createElement('div');
104104
this.menuTitle.classList.add('hemenu-menu-title');
105-
this.menu.parentElement.insertBefore(this.menuTitle, this.menu); // Add menu title click event
105+
this.menu.parentElement.insertBefore(this.menuTitle, this.menu);
106106

107+
// Add menu title click event
107108
this.menuTitle.addEventListener('click', (event => {
108109
/** The opened ULs. */
109110
const panels = this.menu.querySelectorAll('.hemenu-menu-parent');
110111
/** The last opened UL. */
111-
112112
const panel = panels[panels.length - 1];
113-
114113
if (panel) {
115114
this.openPanel(panel);
116115
event.stopImmediatePropagation();
117116
return true;
118117
}
119-
120118
return false;
121-
}).bind(this)); // Open selected panel initially
119+
}).bind(this));
122120

121+
// Open selected panel initially
123122
const setSelectedList = (() => {
124123
/** All selected LIs. */
125124
const listitems = this.menu.querySelectorAll(`.${this.options.selected}`);
126125
/** The last selected LI. */
127-
128126
const listitem = listitems[listitems.length - 1];
129127
/** The opened UL. */
130-
131128
let panel = null;
132-
133129
if (listitem) {
134130
panel = closest(listitem, 'ul', this.menu);
135131
}
136-
137132
if (!panel) {
138133
panel = this.menu.querySelector('ul');
139134
}
140-
141135
this.openPanel(panel);
142136
}).bind(this);
137+
setSelectedList();
143138

144-
setSelectedList(); // Set li's with level
145-
139+
// Set li's with level
146140
forEach(this.menu.querySelectorAll('ul li'), el => {
147141
if (el.querySelector('ul')) {
148142
el.classList.add('hemenu-menu-level');
@@ -151,23 +145,20 @@
151145
this.menu.addEventListener('click', (event => {
152146
/** The clicked element */
153147
const target = event.target;
154-
155148
if (target.matches('a')) {
156149
return;
157150
}
158-
/** Parent listitem for the submenu. */
159151

160-
161-
let listitem; // Find the parent listitem.
162-
163-
if (closest(target, 'span', this.menu)) {
152+
/** Parent listitem for the submenu. */
153+
let listitem;
154+
// Find the parent listitem.
155+
if (closest(target, 'span, div.hemenu-span', this.menu)) {
164156
listitem = target.parentElement;
165157
} else if (closest(target, 'li', this.menu)) {
166158
listitem = target;
167159
} else {
168160
listitem = false;
169161
}
170-
171162
if (listitem) {
172163
forEach(listitem.children, panel => {
173164
if (panel.matches('ul')) {
@@ -177,110 +168,104 @@
177168
event.stopImmediatePropagation();
178169
}
179170
}).bind(this));
180-
} // Backdrop
181-
171+
}
182172

173+
// Backdrop
183174
const addBackdrop = (self = this) => {
184175
// Create the backdrop.
185176
const backdrop = document.createElement('div');
186-
backdrop.classList.add('hemenu-bg'); // Backdrop close event.
177+
backdrop.classList.add('hemenu-bg');
187178

179+
// Backdrop close event.
188180
const close = event => {
189181
self.close();
190182
event.preventDefault();
191183
event.stopImmediatePropagation();
192184
};
193-
194185
backdrop.addEventListener('touchstart', close.bind(self));
195186
backdrop.addEventListener('mousedown', close.bind(self));
196187
return backdrop;
197188
};
189+
this.wrapper.appendChild(addBackdrop());
198190

199-
this.wrapper.appendChild(addBackdrop()); // Add trigger event
200-
191+
// Add trigger event
201192
const triggerClick = event => {
202193
event.preventDefault();
203194
this.open();
204195
};
205-
206196
const trigger = getElement(this.options.trigger);
207-
208197
if (trigger) {
209198
trigger.addEventListener('click', triggerClick.bind(this));
210-
} // Store the instance in the container
211-
199+
}
212200

201+
// Store the instance in the container
213202
this.wrapper.heMenu = this;
214203
this.wrapper.setAttribute('data-hemenu-initialized', true);
215204
}
216-
217205
openPanel(panel) {
218206
//Title above the panel to open.
219-
let title = this.options.title; // Get panel title
207+
let title = this.options.title;
220208

209+
// Get panel title
221210
forEach(panel.parentElement.children, child => {
222-
if (child.matches('a, span')) {
211+
if (child.matches('a, span, div.hemenu-span')) {
223212
title = child.textContent;
224213
}
225-
}); // Set the title.
226-
227-
this.menuTitle.textContent = title; // Unset all panels from being opened and parent.
214+
});
215+
// Set the title.
216+
this.menuTitle.textContent = title;
228217

218+
// Unset all panels from being opened and parent.
229219
forEach(panel.querySelectorAll('.hemenu-menu-parent'), open => {
230220
open.classList.remove('hemenu-menu-parent');
231221
});
232222
forEach(panel.querySelectorAll('.hemenu-menu-open'), open => {
233223
open.classList.remove('hemenu-menu-open');
234-
}); // Set the current panel as being opened.
224+
});
235225

226+
// Set the current panel as being opened.
236227
panel.classList.remove('hemenu-menu-parent');
237-
panel.classList.add('hemenu-menu-open'); // Set all parent panels as being parent.
228+
panel.classList.add('hemenu-menu-open');
238229

230+
// Set all parent panels as being parent.
239231
let parent = panel;
240232
let depth = 0;
241-
242233
do {
243234
parent = closest(parent.parentElement, 'ul', this.menu);
244-
245235
if (parent) {
246236
parent.classList.add('hemenu-menu-open');
247237
parent.classList.add('hemenu-menu-parent');
248238
depth++;
249239
}
250240
} while (parent);
251-
252241
if (depth !== 0) {
253242
this.menuTitle.classList.add('hemenu-title-back');
254243
} else {
255244
this.menuTitle.classList.remove('hemenu-title-back');
256245
}
257246
}
258-
259247
open() {
260248
this.wrapper.classList.add('hemenu-open');
261249
document.body.classList.add('hemenu-opened');
262250
}
263-
264251
close() {
265252
this.wrapper.classList.remove('hemenu-open');
266253
document.body.classList.remove('hemenu-opened');
267-
} // Destroys and unloads the player
268-
254+
}
269255

256+
// Destroys and unloads the player
270257
destroy() {
271258
// We wrap this next part in try...catch in case the element is already gone for some reason
272259
try {
273260
if (!(this.wrapper.hasAttribute('data-hemenu-initialized') && this.wrapper.getAttribute('data-hemenu-initialized') === 'true' && this.wrapper.heMenu)) {
274261
return;
275262
}
276-
277263
document.body.classList.remove('hemenu-opened');
278264
forEach([`hemenu-${this.options.position}`, `hemenu-theme-${this.options.theme}`, 'hemenu-open'], cls => {
279265
this.wrapper.classList.remove(cls);
280266
});
281267
this.wrapper.querySelector('.hemenu-bg').remove();
282268
this.wrapper.querySelector('.hemenu-menu-title').remove();
283-
284269
if (this.menu) {
285270
this.menu.classList.remove('hemenu-navbar');
286271
this.menuTitle.remove();
@@ -293,25 +278,25 @@
293278
forEach(this.menu.querySelectorAll('.hemenu-menu-open'), el => {
294279
el.classList.remove('hemenu-menu-open');
295280
});
296-
} // TODO: remove click events
297-
281+
}
298282

299-
this.wrapper.removeAttribute('data-hemenu-initialized'); // Delete the instance
283+
// TODO: remove click events
300284

285+
this.wrapper.removeAttribute('data-hemenu-initialized');
286+
// Delete the instance
301287
delete this.menu.heMenu;
302-
} catch (e) {// Nothing to do when error is invoked
288+
} catch (e) {
289+
// Nothing to do when error is invoked
303290
}
304291
}
305-
306292
}
307-
308293
heMenu.destroy = () => {
309294
forEach(document.querySelectorAll('[data-hemenu-initialized]'), el => {
310295
el.heMenu.destroy();
311296
});
312-
}; // Provide method for scanning the DOM and initializing heMenu from attribute
313-
297+
};
314298

299+
// Provide method for scanning the DOM and initializing heMenu from attribute
315300
heMenu.scan = () => {
316301
// API method for scanning the DOM and initializing vide instances from data-vide attribute
317302
// Scan the DOM for elements that have data-hemenu attribute and initialize new heMenu instance based on that attribute
@@ -323,24 +308,23 @@
323308
// this element already has an instance
324309
return;
325310
}
326-
327311
try {
328312
new heMenu(el, JSON.parse(decodeURIComponent(el.getAttribute('data-hemenu'))));
329-
} catch (e) {// Nothin to do when an error is invoked
313+
} catch (e) {
314+
// Nothin to do when an error is invoked
330315
}
331316
});
332317
};
333-
334318
if (document.readyState !== 'loading') {
335319
scan();
336320
} else {
337321
document.addEventListener('DOMContentLoaded', scan);
338322
}
339323
};
340-
341324
heMenu.scan();
342-
window.heMenu = heMenu; // Return heMenu
325+
window.heMenu = heMenu;
343326

327+
// Return heMenu
344328
return heMenu;
345329
})('undefined' !== typeof window ? window : undefined, document);
346330

0 commit comments

Comments
 (0)