I have next example of implementing dropdowns.
let isTouchScreen = {
Android: function () {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function () {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function () {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function () {
return navigator.userAgent.match(/Opera Mini/i);
},
Windows: function () {
return navigator.userAgent.match(/IEMobile/i);
},
any: function () {
return isTouchScreen.Android() || isTouchScreen.BlackBerry() || isTouchScreen.iOS() || isTouchScreen.Opera() || isTouchScreen.Windows();
},
};
let body = document.querySelector('body');
if(isTouchScreen.any()) {
body.classList.add('touch');
link = document.querySelectorAll('nav a');
link.forEach(function(index) {
index.addEventListener('click', function() {
let arrow = index.nextElementSibling;
let menu = arrow.nextElementSibling;
arrow.classList.toggle('active');
menu.classList.toggle('open');
});
});
} else {
body.classList.add('mouse');
}
*,
*:before,
*:after
{
box-sizing: border-box;
margin: 0;
padding: 0;
border: 0;
}
body
{
font-family: Arial, sans-serif;
font-size: 1em;
min-height: 100vh;
line-height: 1;
color: #fff;
}
.menu {
background: #181818;
}
.menu a {
display: block;
text-decoration: none;
white-space: nowrap;
min-width: 150px;
background: #181818;
padding: 10px 20px;
color: #a4a6a7;
}
.menu a:hover {
background: #cd412b;
color: #fff;
}
.menu li
{
position: relative;
list-style: none;
}
.menu__list
{
display: flex;
}
.sub-menu__list
{
position: absolute;
top: auto;
left: 0;
display: none;
}
.sub-sub-menu__list
{
position: absolute;
top: 0;
left: 100%;
display: none;
}
.arrow
{
position: absolute;
top: 12px;
right: 20px;
display: none;
background: url('../images/select.svg');
height: 8px;
width: 12px;
cursor: pointer;
}
.arrow.active
{
transform: rotate(-180deg);
}
body.mouse .menu__list > li:hover .sub-menu__list
{
display: block;
}
body.mouse .sub-menu__list > li:hover .sub-sub-menu__list
{
display: block;
}
body.touch .sub-menu__list.open
{
display: block;
}
body.touch .sub-sub-menu__list.open
{
display: block;
}
body.touch .arrow
{
display: block;
}
@media (max-width: 768px)
{
.arrow {
display: block;
}
.menu__list
{
display: block;
}
.sub-menu__list
{
position: relative;
top: 0;
left: 0;
}
.sub-sub-menu__list
{
position: relative;
top: 0;
left: 0;
}
}
<nav >
<ul >
<li>
<a href="#" >First level</a>
<span ></span>
<ul >
<li><a href="#" >Second level</a></li>
<li><a href="#" >Second level</a>
<span ></span>
<ul >
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
</ul>
</li>
<li><a href="#" >Second level</a></li>
<li><a href="#" >Second level</a></li>
</ul>
</li>
<li><a href="#" >First level</a></li>
<li>
<a href="#" >First level</a>
<span ></span>
<ul >
<li><a href="#" >Second level</a></li>
<li><a href="#" >Second level</a>
<span ></span>
<ul >
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
</ul>
</li>
<li><a href="#" >Second level</a></li>
<li><a href="#" >Second level</a></li>
</ul>
</li>
</ul>
</nav>
The next following problems related to screens which with is less than 767px.
In browser when i hover on the links by mouse i can't actually to get to some of them (check snippet on screens less than 767px). And next problem when on the mobile mode i am clicking on the links which have dropdowns it is ok. But those who does not have a menu, when you click on them it gives an error in the console.
CodePudding user response:
You need to check whether the nextElementSibling
exists before trying to toggle its class.
link.forEach(function(index) {
index.addEventListener('click', function() {
let arrow = index.nextElementSibling;
if (arrow) {
arrow.classList.toggle('active');
let menu = arrow.nextElementSibling;
menu.classList.toggle('open');
}
});
});
CodePudding user response:
link = document.querySelectorAll('.link');
link.forEach(function(index) {
index.addEventListener('click', function() {
let arrow = index.nextElementSibling;
if (arrow) {
arrow.classList.toggle('active');
let menu = arrow.nextElementSibling;
menu.classList.toggle('open');
}
});
});
*,
*:before,
*:after
{
box-sizing: border-box;
margin: 0;
padding: 0;
border: 0;
}
body
{
font-family: Arial, sans-serif;
font-size: 1em;
min-height: 100vh;
line-height: 1;
color: #fff;
}
.menu {
background: #181818;
}
.link {
display: block;
text-decoration: none;
white-space: nowrap;
min-width: 150px;
background: #181818;
padding: 10px 20px;
color: #a4a6a7;
}
.link:hover {
background: #cd412b;
color: #fff;
}
.menu li
{
position: relative;
list-style: none;
}
.menu__list
{
display: flex;
}
.sub-menu__list
{
position: absolute;
top: auto;
left: 0;
display: none;
}
.sub-sub-menu__list
{
position: absolute;
top: 0;
left: 100%;
display: none;
}
.arrow
{
position: absolute;
top: 12px;
right: 20px;
pointer-events: none;
display: none;
background: url('../images/select.svg');
height: 8px;
width: 12px;
cursor: pointer;
}
.arrow.active
{
transform: rotate(-180deg);
}
@media (min-width: 767px) {
.menu__list > li:hover .sub-menu__list
{
display: block;
}
.sub-menu__list > li:hover .sub-sub-menu__list
{
display: block;
}
}
@media (max-width: 767px) {
.arrow {
display: block;
}
.menu__list {
display: block;
}
.menu__list,
.sub-menu__list,
.sub-sub-menu__list {
position: relative;
top: 0;
left: 0;
}
.menu__list.open,
.sub-menu__list.open,
.sub-sub-menu__list.open {
display: block;
}
}
<nav >
<ul >
<li>
<a href="#" >First level</a>
<span ></span>
<ul >
<li><a href="#" >Second level</a></li>
<li><a href="#" >Second level</a>
<span ></span>
<ul >
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
</ul>
</li>
<li><a href="#" >Second level</a></li>
<li><a href="#" >Second level</a></li>
</ul>
</li>
<li><a href="#" >First level</a></li>
<li>
<a href="#" >First level</a>
<span ></span>
<ul >
<li><a href="#" >Second level</a></li>
<li><a href="#" >Second level</a>
<span ></span>
<ul >
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
<li><a href="#" >Third level</a></li>
</ul>
</li>
<li><a href="#" >Second level</a></li>
<li><a href="#" >Second level</a></li>
</ul>
</li>
</ul>
</nav>
Okay i made it nice, if somebody needs - you are welcome.