'Dropdown menu issue on touchstart and on hover
I am trying to make a dropdown menu appear only when hovering above it on laptop screen and only on click when on mobile. The problem is that it also appears when it is clicked on on laptop size screen with a messed up margin as well. The other problem is that when I'm on mobile I have to keep pressing the screen in order for it to be shown. Below is the link of the webpage as well as the Javascript code and HTML that I wrote.
https://dreamy-brigadeiros-09ff46.netlify.app/
Javascript
const dropdown = document.querySelector('.dropdown');
const dropdownToggle = document.querySelector('.dropdown .dropdown-toggle');
const dropdownMenu = document.querySelector('.dropdown .dropdown-menu');
var mq = window.matchMedia('(max-width: 900px)');
var flagSm = false;
if (mq.matches) {
if (!flagSm) {
dropdown.addEventListener('touchstart', function () {
dropdownToggle.classList.add("show");
dropdownMenu.classList.add("show");
});
flagSm = true;
} else {
dropdown.addEventListener('touchcancel', function () {
dropdownToggle.classList.remove("show");
dropdownMenu.classList.remove("show");
});
flagSm = false;
}
} else {
dropdown.addEventListener('mouseover', function () {
dropdownToggle.classList.add("show");
dropdownMenu.classList.add("show");
});
dropdown.addEventListener('mouseout', function () {
dropdownToggle.classList.remove("show");
dropdownMenu.classList.remove("show");
});
}
HTML
<div class="container-fluid top-menu">
<nav class="navbar navbar-expand-lg navbar-dark topnav">
<a class="navbar-brand topnav-logo" href=""><img class="topnav-logo-img" src="./images/shop/pyrosvesi.png"></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarToggler"
aria-controls="navbarToggler" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarToggler">
<ul class="navbar-nav ms-auto menu-items">
<li class="nav-item"><a class="nav-link" href="">Αρχική</a></li>
<li class="nav-item"><a class="nav-link" href="">Το Κατάστημα</a></li>
<li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="" id="navbarDropdown"
role="button" data-bs-toggle="dropdown" aria-expanded="false">Προϊόντα</a>
<ul id="navbarDropdownContent" class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#">Πυροσβεστικός εξοπλισμός</a></li>
<li><a class="dropdown-item" href="#">Συστήματα πυρανίχνευσης-πυρόσβεσης</a></li>
</ul>
</li>
<li class="nav-item"><a class="nav-link" href="">Υπηρεσίες</a></li>
<li class="nav-item"><a class="nav-link" href="">Επικοινωνία</a></li>
</ul>
</div>
</nav>
</div>
</section>
Solution 1:[1]
Try something like this:
if (isTouchDevice()) {
if (!flagSm) {
dropdown.addEventListener('touchstart', function () {
dropdownToggle.classList.add("show");
dropdownMenu.classList.add("show");
});
flagSm = true;
} else {
dropdown.addEventListener('touchcancel', function () {
dropdownToggle.classList.remove("show");
dropdownMenu.classList.remove("show");
});
flagSm = false;
}
} else {
dropdown.addEventListener('mouseover', function () {
dropdownToggle.classList.add("show");
dropdownMenu.classList.add("show");
});
dropdown.addEventListener('mouseout', function () {
dropdownToggle.classList.remove("show");
dropdownMenu.classList.remove("show");
});
}
/**SET THIS FUNCTION SOMEWHERE OUT OF SCOPE**/
function isTouchDevice(){
try{
const device = document.createEvent('TouchEvent');
return true;
}catch(e){
return false;
}
}
It wouldn't be a good idea to use the size of the device to determine if it is a mobile device or not so I'd advise receiving a promise from the device determining if it allows touch events.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Trayvon Como |
