-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdropdown.js
More file actions
110 lines (89 loc) · 3.97 KB
/
dropdown.js
File metadata and controls
110 lines (89 loc) · 3.97 KB
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
//SETTINGS
// dropdown.target = The class name you will apply to the dropdown objects
// dropdown.trigger = The class name you will apply to the item to click on, or the "Trigger" item.
// dropdown.unopened = On your trigger, you should have an indication whether the dropdown is open or not. This is it when it is closed
// dropdown.opened = This is the indication for when the dropdown is open.
// dropdown.hoverable = whether or not one can simply hover to trigger the expansion of the dropdown.
//Note: Each trigger item is associated with the following dropdown item. You need to have the same amount of Triggers and DropDowns.
let dropdown = {
target: 'dropdown',
trigger: 'droptrigger',
opened: '\u25BE',
unopened: '\u25B8',
hoverable: true,
};
window.addEventListener("load", event =>
{
let drops = []; //list of all dropdowns with trigger, state, and target
for (let i = 0; i < document.querySelectorAll(`.${dropdown.target}`).length; i++)
{
if (!document.querySelectorAll(`.${dropdown.trigger}`)[i])
{
throw new Error(`Missing trigger for a dropdown.`);
}
drops.push({ trigger: document.querySelectorAll(`.${dropdown.trigger}`)[i], target: document.querySelectorAll(`.${dropdown.target}`)[i], open: false, hover: false });
}
for (let ddp of drops)
{
//this line adds the indicators. Modify if you want it in a different format.
ddp.trigger.innerHTML = `${ddp.trigger.innerHTML} ${dropdown.unopened}`;
ddp.trigger.style.cursor = "pointer";
ddp.target.style.zIndex = "3";
ddp.target.style.transformOrigin = "50% 0%";
dropdown.open = dd =>
{
dd.target.style.display = "block";
setTimeout(dd=>{
dd.target.style.transform = 'scaleY(1)';
dd.target.style.height = 'auto';
}, 1, dd);
dd.trigger.innerHTML = dd.trigger.innerHTML.replace(dropdown.unopened, dropdown.opened);
dd.open = true;
}
dropdown.close = dd =>
{
dd.target.style.transform = 'scaleY(0)';
setTimeout(dd=>{
if(!dd.hover)
{
dd.target.style.height = '0';
dd.target.style.display = "none";
}
}, 200, dd);
dd.trigger.innerHTML = dd.trigger.innerHTML.replace(dropdown.opened, dropdown.unopened);
dd.open = false;
}
dropdown.delayedClose = dd =>
{
setTimeout(() =>
{
if (!dd.hover) dropdown.close(dd);
else dropdown.delayedClose(dd);
}, 500);
}
dropdown.toggle = dd =>
{
if (dd.open) dropdown.close(dd); else dropdown.open(dd);
}
//this line hides them and makes them 0 height by default
dropdown.close(ddp);
ddp.target.style.position = "absolute";
//set left and top to the dd.trigger's left and right
if(!ddp.target.classList.contains("theme")) {
ddp.target.style.left = `${ddp.trigger.getBoundingClientRect().left}px`;
ddp.target.style.top = `${ddp.trigger.getBoundingClientRect().bottom}px`;
}
//prevents it from flashing when loading screen
setTimeout(ddp => {
ddp.target.style.transition = "transform 0.2s";
}, 200, ddp);
if (dropdown.hoverable)
{
ddp.target.addEventListener("mouseleave", () => { ddp.hover = false; dropdown.delayedClose(ddp); });
ddp.trigger.addEventListener("mouseleave", () => { ddp.hover = false; dropdown.delayedClose(ddp); });
ddp.target.addEventListener("mouseenter", () => { ddp.hover = true; dropdown.open(ddp); });
ddp.trigger.addEventListener("mouseenter", () => { ddp.hover = true; dropdown.open(ddp); });
}
else ddp.trigger.addEventListener("click", dropdown.toggle);
}
});