我正在使用简单纯净的CSS下拉菜单上的网站工作。该网站应该在桌面和iPad上使用。我的下拉菜单使用:hover
伪级,并在触摸屏上出现问题:菜单扩展良好,但永远不会崩溃。关闭它的唯一方法是从同一下拉菜单中打开另一个子菜单。我的目标是当我在DOM
中的任何地方触摸菜单时(当然在菜单中除外)。经过许多研究,似乎我们无法使用CSS来做到这一点,JS是必须的。我是一个初学者,我在JS方面没有技能,是否只能使用几种香草JS系列进行操作?我不想使用jQuery。这是我的代码:
/* ========================================================================= */
/* Global styles */
/* ========================================================================= */
html {
box-sizing: border-box;
font-size: 62.5%;
}
*, *:before, *:after {
margin: 0;
padding: 0;
box-sizing: inherit;
}
body, input {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
img {
border: none;
}
/* ========================================================================= */
/* Layout styles */
/* ========================================================================= */
body > header, body > main {
margin: auto;
}
body > header {
padding-top : 20px;
width: 768px;
}
body > header > img {
width: 150px;
margin-left: 10px;
}
/* ========================================================================= */
/* Nav styles */
/* ========================================================================= */
body > header > nav {
min-width: 768px;
margin: 0 auto;
padding-top: 20px;
font-size: 1.5em;
text-align: center;
}
nav > ul ul {
position: absolute;
display: none;
text-align: left;
}
nav li {
width: 150px;
}
nav > ul > li {
display: inline-block;
}
nav a {
display: block;
text-decoration: none;
}
nav > ul > li > a {
padding: 10px 0;
color: #44546A;
}
nav > ul ul li {
background-color: #333F50;
list-style-type: none;
}
nav > ul ul li a {
padding: 10px 0 10px 30px;
color: #FAFAFA;
font-size: 0.9em;
}
nav > ul li:hover ul {
display: block;
}
nav > ul ul li:hover {
background-color: #51647f;
}
<!DOCTYPE html>
<html>
<head>
<base href="/"/>
<meta charset="UTF-8"/>
<title>Test Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" type="text/css" href="css/normalize.css"/>
<link rel="stylesheet" type="text/css" href="css/styles.css"/>
</head>
<body>
<header>
<img src="img/test.svg" alt="test"/>
<nav>
<ul>
<li>
<a href="#">Menu 1</a>
<ul class="subMenu">
<li>
<a href="#">SubMenu 1.1</a>
</li>
</ul>
</li>
<li>
<a href="#">Menu 2</a>
<ul>
<li>
<a href="#">SubMenu 2.1</a>
</li>
<li>
<a href="#">SubMenu 2.2</a>
</li>
<li>
<a href="#">SubMenu 2.3</a>
</li>
</ul>
</li>
<li>
<a href="#">Menu 3</a>
<ul>
<li>
<a href="#">SubMenu 3.1</a>
</li>
</ul>
</li>
<li>
<a href="#">Menu 4</a>
<ul class="subMenu">
<li>
<a href="#">SubMenu 4.1</a>
</li>
</ul>
</li>
</ul>
</nav>
</header>
</body>
</html>
编辑:该代码在平板电脑上运行良好,但在iPads上不能
:hover
伪类在触摸屏设备上的行为不同。当用户触摸元素时,浏览器会触发并保留状态:hover
,直到触发另一个伪级为止。因此,当用户触摸页面上的另一个元素时,浏览器会触发不同的伪级,并且下拉菜单被隐藏。在大多数情况下,触发的是:active
伪级。
但是,正如Safari开发人员库上所述,Mobile Safari不会触发:active
伪级,除非将触摸事件附加到元素上:
在iOS上,鼠标事件发送得如此之快,以至于 从未收到下降或活跃状态。因此,
时:active
伪状态只有在设置触摸事件设置时才触发 HTML元素 - 例如,当OnTouchStart设置在元素上...
要解决此问题,您可以将touchstart
侦听器添加到您的文档中,以触发:active
伪级:
document.addEventListener('touchstart', function() {});
在此解决方案,询问您是否要说明。
<nav id='nav'>
...
<script>
function hideDropDownMenu(e) {
var element = e.target;
var parent = element.parentNode;
var mustHide = false;
while (parent != null && !mustHide) {
mustHide = element.id === 'nav';
element = element.parentNode;
}
var subMenus = document.getElementsByClassName('subMenu');
var i = 0;
for (i = 0; i < subMenus.length; i++) {
var subMenu = subMenus[i];
subMenu.style = mustHide ? 'none !important' : 'block'; // not sure if the !import is optionnal
}
}
document.body.addEventListener('click', hideDropDownMenu);
</script>
正如我在另一个问题中发布的那样:
我通过在<body>
标签中添加tabindex
来解决此问题,例如:
<body tabindex="0">
这个小技巧允许iPad Safari在攻击时专注于身体,然后从下拉菜单中删除焦点。
无需JavaScript。😊