简体   繁体   English

Ipad上的下拉菜单CSS / JS

[英]Dropdown menu css / js on Ipad

I'm working on a website with a simple and pure css dropdown menu. 我正在使用一个简单且纯净的CSS下拉菜单的网站。 That website is supposed to be used on desktop and on Ipads. 该网站应该在台式机和Ipad上使用。 My dropdown menu uses :hover pseudo-class and issue appears on the touch screen: the menu expands well but it never collapse. 我的下拉菜单使用:hover伪类,并且问题出现在触摸屏上:菜单可以很好地展开,但永远不会折叠。 The only way to close it is to open another submenu from the same dropdown menu. 关闭它的唯一方法是从同一下拉菜单中打开另一个子菜单。 My goal is that my menu collapse when I touch anywhere in the DOM (except in the menu of course). 我的目标是,当我触摸DOM任何位置时(当然,菜单中的菜单除外),菜单就会折叠。 After many researches, it appears that we can not do this with , is obligatory. 经过大量研究,似乎我们无法使用做到这一点, 是必须的。 I am a beginner and I have no skill in JS, is it possible to do it with only few vanilla lines ? 我是一个初学者,我没有JS技能,是否可以仅使用几条普通行? I don't want to use . 我不想使用 Here is my code: 这是我的代码:

 /* ========================================================================= */ /* 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> 

Edit : That code works well on tablets but not on Ipads 编辑:该代码在平板电脑上效果很好,但不适用于Ipad

Here a solution, ask if you want explanation. 这是一个解决方案,询问您是否要解释。

<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>

The :hover pseudo-class behaves differently on touch screen devices. :hover伪类在触摸屏设备上的行为有所不同。 When the user touches an element, the browser triggers and keeps the state :hover until another pseudo-class is triggered. 当用户触摸元素时,浏览器将触发并保持:hover状态,直到触发另一个伪类。 Thus, when the user touches another element on the page, a different pseudo-class is triggered by the browser and the drop-down menu becomes hidden. 因此,当用户触摸页面上的另一个元素时,浏览器将触发另一个伪类,并且下拉菜单将隐藏。 Most of the time, it is the :active pseudo-class that is triggered. 大多数时候,它是:active伪类触发的。

However, as explained on the Safari Developer Library , Mobile Safari doesn't trigger the :active pseudo-class unless a touch event is attached to the element: 但是,如Safari开发人员库中所述 ,除非将touch事件附加到元素,否则Mobile Safari不会触发:active伪类:

On iOS, mouse events are sent so quickly that the down or active state is never received. 在iOS上,鼠标事件发送得如此之快,以至于永远不会收到按下或活动状态。 Therefore, the :active pseudo state is triggered only when there is a touch event set on the HTML element—for example, when ontouchstart is set on the element... 因此,仅在HTML元素上设置了触摸事件时,例如,当在元素上设置ontouchstart时,才触发:active伪状态。

To fix this, you can add a touchstart listener to your document in order to trigger the :active pseudo-class: 要解决此问题,您可以在文档中添加一个touchstart侦听器,以触发:active伪类:

document.addEventListener('touchstart', function() {});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM