Как работать с многоуровневыми меню на устройствах с сенсорным экраном, которые используют: hover и: focus для интерактивных ссылок верхнего уровня? - PullRequest
0 голосов
/ 09 октября 2018

Взгляните на следующее меню:

.clearfix::after {
    content: "";
    clear: both;
    display: table;
}

#my-menu-inner > ul {
  margin:10px;
  width:100%;
  background-color:yellow;
  list-style-type:none;
  position:relative;
}

#my-menu-inner > ul > li {
  float:left;
  margin:20px;
}

#my-menu-inner > ul > li > a {
  padding:20px;
  border:1px solid black;
  display:block;
}

#my-menu-inner > ul > li > div.sub {
   position:absolute;
   top:calc(100%  - 20px);
   background-color:red;
   padding:40px;
   display:none;
   left:0;
   width:100vw;
}

#my-menu-inner > ul > li a:hover + div.sub, #my-menu-inner > ul > li a:focus + div.sub,
#my-menu-inner > ul > li > div.sub:hover, #my-menu-inner > ul > li > div.sub:focus {
    display:block;
}
<div id="whatever">Just something before ...</div>
<div id="my-menu">
  <div id="my-menu-inner">
    <ul class="clearfix">
      <li>
        <a href="http://www.example.com/foo/">foo</a>
        <div class="sub">
          <ul>
            <li><a href="http://www.example.com/mobile/">mobile</a></li>
            <li><a href="http://www.example.com/users/">users</a></li>
          </ul>
        </div>
      </li>
      <li>
        <a href="http://www.example.com/bar/">bar</a>
        <div class="sub">
          <ul>
            <li><a href="http://www.example.com/never/">never</a></li>
            <li><a href="http://www.example.com/see-me/">see me</a></li>
          </ul>
        </div>
      </li>
    </ul>
  </div>
</div>

Это хорошо работающее меню для всех, у кого есть мышь или тачпад.Тем не менее: пользователи мобильных устройств никогда не увидят подменю, поскольку они мгновенно переходят в местоположение href, как только они нажимают одну из ссылок.И у них нет состояний наведения, ofc.

О чем я думал:

Идея 1 : есть отдельное мобильное меню для сенсорных устройств.Это замечательно, потому что большинство проектов в любом случае имеют отдельные мобильные меню.

Проблема: @media screen (max-width: 1000px) не будет достаточным методом, чтобы определить, может ли пользователь зависать / фокусироваться, как, например, все с большим сенсорным экраном.исключено.

Идея 2: preventDefault() при нажатии на ссылки.Проверьте, было ли ранее обнаружено движение мыши, и если да, перейдите по ссылке.Если не требуется повторного щелчка.

Проблема: Требование двух кликов, вероятно, не удобно для пользователя (многие не признают, что ссылка кликабельна).

Что хорошои рекомендуемый способ справиться с этой ситуацией?

1 Ответ

0 голосов
/ 09 октября 2018

Я думаю, что хорошей практикой является создание видимого кликабельного элемента.Вы должны думать не только о реализации, но и о том, как пользователь будет взаимодействовать.Пользователь должен знать, что есть подменю, и для этого вы можете добавить маленький значок, который может появляться везде, даже если мы можем :hover.

. Вот упрощенный пример, где по умолчанию работает hover.Если мы не можем парить, мы можем щелкнуть значок, чтобы отобразить меню.Просто используйте значок, который делает щелчок интуитивно понятным для пользователей.

$('li span').click(function() {
    $(this).next('.sub').toggleClass('show');
    $(this).toggleClass('open');
})
.clearfix::after {
    content: "";
    clear: both;
    display: table;
}

#my-menu-inner > ul {
  margin:10px;
  width:100%;
  background-color:yellow;
  list-style-type:none;
  position:relative;
}

#my-menu-inner > ul > li {
  float:left;
  margin:20px;
}

#my-menu-inner > ul > li > a {
  padding:20px;
  border:1px solid black;
  display:inline-block;
}
#my-menu-inner > ul > li > span {
  text-decoration:none;
  display:inline-block;
  padding:20px 5px;
  border:1px solid black;
  margin-right:-10px;
  cursor:pointer;
}
#my-menu-inner > ul > li > span:before {
  content:"▼"
}
#my-menu-inner > ul > li > span.open:before {
  content:"▲"
}

#my-menu-inner > ul > li > div.sub {
   position:absolute;
   top:calc(100%  - 20px);
   background-color:red;
   padding:40px;
   display:none;
   left:0;
   width:100vw;
}

#my-menu-inner > ul > li a:hover ~ div.sub,
#my-menu-inner > ul > li span:hover ~ div.sub,
#my-menu-inner > ul > li a:focus ~ div.sub,
#my-menu-inner > ul > li span:focus ~ div.sub,
#my-menu-inner > ul > li > div.sub:hover, 
#my-menu-inner > ul > li > div.sub:focus,
#my-menu-inner > ul > li > div.sub:hover, 
#my-menu-inner > ul > li > div.sub.show{
    display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="whatever">Just something before ...</div>
<div id="my-menu">
  <div id="my-menu-inner">
    <ul class="clearfix">
      <li>
        <a href="http://www.example.com/foo/">foo</a><span></span>
        <div class="sub">
          <ul>
            <li><a href="http://www.example.com/mobile/">mobile</a></li>
            <li><a href="http://www.example.com/users/">users</a></li>
          </ul>
        </div>
      </li>
      <li>
        <a href="http://www.example.com/bar/">bar</a><span></span>
        <div class="sub">
          <ul>
            <li><a href="http://www.example.com/never/">never</a></li>
            <li><a href="http://www.example.com/see-me/">see me</a></li>
          </ul>
        </div>
      </li>
       <li>
        <a href="http://www.example.com/bar/">I don't have submenu</a>
        
      </li>
    </ul>
  </div>
</div>
...