DecPK
DecPK

Reputation: 25408

How to create menu responsive on click or on hover depend on device?

I was creating a button with a and what I wanted is when I'm on a mobile device, I can click on the button and the menu appears. As we know, we can't hover on mobile devices But on a tab and higher devices, the menu should display on hover, not on click. codepen If I use onclick for mobile devices, then the menu stays on medium and above devices and If I remove onclick to work properly on medium and above devices then on mobile we can't click, as the only option left to open the menu is hover which we can't do in mobile devices. How to solve this problem. The only goal is to make a responsive design.

const btn = document.querySelector('.btn');
const list = document.querySelector('.list');

btn.addEventListener('click', () => {
  list.style.display = 'block';
})
.btn{
  margin: 0;
  display: block;
  width: 100%;
  padding: 1rem;
  background-color: teal;
  color: white;
  font-size: 2rem;
  border-radius: 8px;
}

.list{
  display: none;
}

.btn:hover + .list{
    display: block;
  }
}

@media (min-width: 768px) {
  .btn{
    width: 50%;
  }
}
<a class="btn"> Names </a>

<ul class="list">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
</ul>

Upvotes: 1

Views: 307

Answers (3)

Alex
Alex

Reputation: 1

You have to add 'touch' event, by this way it gonna work with touchscreens only

btn.addEventListener('touchstart', () => {
  list.style.display = 'block';
})

Upvotes: 0

matthieu_dwle
matthieu_dwle

Reputation: 33

Try this :

const btn = document.querySelector('.btn');
const list = document.querySelector('.list');
const header = document.querySelector('header')
let clicked = false

btn.addEventListener('click', () => {
    clicked = !clicked;
    list.classList.toggle('active');
})

btn.addEventListener('mouseover', () => {
    if (!clicked) {
        list.classList.add('active');
    }
})

btn.addEventListener('mouseout', () => {
    if (!clicked) {
        setTimeout(400);
        list.classList.remove('active');
    }
})

list.addEventListener('mouseover', () => {
    if (!clicked) {
        list.classList.add('active');
    }
})

list.addEventListener('mouseout', () => {
    if (!clicked) {
        list.classList.remove('active');
    }
})
.btn {
        margin: 0;
        display: block;
        width: 100%;
        padding: 1rem;
        background-color: teal;
        color: white;
        font-size: 2rem;
        border-radius: 8px;
    }

    .list {
        margin: 0;
        padding: 16px 0;
        padding-left: 40px;
        display: none;
    }

    .list.active {
        display: block;
    }

    @media (min-width: 768px) {
        .btn {
            width: 50%;
        }
    }
<header>
    <a class="btn">Names</a>

    <ul class="list">
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
    </ul>
</header>
<p> Some text to increase height of window and let you pass mouse out of the list: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

I replace the margin by padding to increase trigger zone of the list

margin: 0;
padding: 16px 0;
padding-left: 40px;

I add event for the list to avoid that it toggle active even if the mouse is over the list

list.addEventListener('mouseover', () => {
    if (!clicked) {
        list.classList.add('active');
    }
})

list.addEventListener('mouseout', () => {
    if (!clicked) {
        list.classList.remove('active');
    }
})

I add clicked var to keep list display: block if you click on the button. I add timeout to let time to transition between btn and list mouse over

Upvotes: 0

user884321
user884321

Reputation: 477

Here you go read about media queries in JavaScript and you can put a different onClick even based on the size of the window: https://www.w3schools.com/howto/howto_js_media_queries.asp

Upvotes: 1

Related Questions