如何根据设备创建响应式点击或悬停菜单?

时间:2021-01-22 09:03:48

标签: javascript html css

我正在创建一个带有 a 的按钮,我想要的是当我在移动设备上时,我可以单击该按钮并显示菜单。正如我们所知,我们不能在移动设备上悬停但是在选项卡和更高的设备上,菜单应该在悬停时显示,而不是在点击时显示。 codepen 如果我将 onclick 用于移动设备,则菜单会保留在中型及以上设备上,如果我删除 onclick 以在中型及以上设备上正常工作,那么在移动设备上我们将无法点击,这是唯一可以打开的选项菜单是悬停,这是我们在移动设备中无法做到的。如何解决这个问题呢。 唯一的目标是做出响应式设计。

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>

3 个答案:

答案 0 :(得分:1)

在这里,您可以阅读 JavaScript 中的媒体查询,您甚至可以根据窗口的大小设置不同的 onClick:https://www.w3schools.com/howto/howto_js_media_queries.asp

答案 1 :(得分:0)

试试这个:

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>

我通过填充替换边距以增加列表的触发区域

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

我为列表添加事件以避免即使鼠标在列表上也切换活动

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

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

如果您点击按钮,我会添加 clicked var 以保留列表 display: block。 我添加超时让时间在 btnlist 鼠标悬停

之间转换

答案 2 :(得分:0)

你必须添加'touch'事件,这样它只能在触摸屏上工作

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