Как обрабатывать события касания на устройствах, которые поддерживают события Touch и Pointer, с помощью меню с подпунктами, которые не являются дочерними элементами родительского меню - PullRequest
1 голос
/ 17 марта 2020

У меня проблема с mouseleave и hover на устройствах, которые поддерживают события Pointer и Touch. К таким устройствам относятся ноутбуки с мышью и сенсорным экраном.

Я просто хочу отключить мышиный отпуск и зависание, но проблема в том, что это устройство поддерживает оба, и я не могу найти статью, объясняющую это должным образом, и там Нет стандартов.

Я посмотрел следующие ссылки:

Отключить эффекты наведения на мобильных браузерах

Как удалить / игнорировать: hover css стиль на сенсорных устройствах

jquery предотвращение зависания при касании

jQuery отпуск мыши для сенсорного экрана / таблетки

Отключить эффекты наведения на мобильные браузеры

Мы используем DNN (DotNetNuke) в качестве системы управления контентом. Я знаю, что вы можете создавать собственные меню, используя токены и меню DDR, но это слишком сложно для того, чего я хочу достичь.

Мой простой подход заключался в создании подменю из данных, извлеченных из нашей базы данных ERP, и отображать его при наведении курсора на ссылку на страницу DNN, которая «отключена» с определенным именем, совпадающим с использованием jQuery.

Все отлично работает на настольном устройстве. Он также работает с устройством Touch & Pointer, используя Chrome.

У меня проблема с Edge на планшетном устройстве с событиями Touch и Pointer. Onmouseleave запускается, когда вы нажимаете «Категории», что приводит к закрытию подменю. Когда вы нажимаете на меню «Категории», оно вызывает событие при наведении.

Что делает его более трудным, так это то, что подменю не является прямым потомком родителя, поэтому его не всегда легко использовать. CSS селекторы. В настоящее время я размещаю модуль под меню так, чтобы он был, по крайней мере, очень близко, чтобы я мог использовать абсолютное и относительное позиционирование, чтобы подменю отображалось непосредственно под ссылками. Здесь вы заметите, что я добавил функцию тайм-аута для одного события mouseleave, чтобы позволить кому-либо перейти в подменю, когда его мышь покидает событие hover.

Вот скриншот меню. Он содержит подкатегории, которые могут отображаться, но я просто хочу, чтобы главное меню правильно отображалось на устройствах с поддержкой событий Touch и Point.

enter image description here

Пример кода JSFidle

JSFidle: https://jsfiddle.net/Tig7r/e6k9cfj1/13/

HTML

<nav class="NavMenu">
  <ul class="ul_menu">
  <li class='item'><a href="#"><span>Home</span></a></li>
  <li class='item'><a><span>Categories</span></a></li>
  </ul>
</nav>


<div class="subLevel MegaMenuDiv" id="MegaMenuDiv">
  <div class="custom_megamenu_wrapper">
   <ul class="main-category-list has-children"><li><a href="javascript:void(0)" class="Parent_Mega_Menu_Categories MegaMenuLinkMainWithChildren" style="">Accessories</a>
      <ul class="secondary-items">
      <li><a href="https://www.google.com" class="MegaMenu_Child_Link" style="">Accessory Holders</a></li>
      <li><a href="https://www.google.com" class="MegaMenu_Child_Link" style="">Whiteboard Starter Pack</a></li>
   </ul></li>
</ul>
 </div>
</div>

css

.NavMenu{
  width:100%;
  height:40px;
  background-color:red;
  color:white !important;
}

.NavMenu ul li{
  list-style:none;
  display:inline-block;
  padding:10px;
}

.ul_menu li a:link{
  color:white;
}

.ul_menu li a:hover{
  color:black;
}

#MegaMenuDiv{
  background:black;
  color:white;
  position:absolute;
  width:550px;
  display:none;
  min-height:300px;
}

.MegaMenuDiv a:link{
  color:white;
}

.displayHiddenMenu{
  display: block !important;
}

.main-category-list li{
  list-style:none;
}

.secondary-items{
  background: #31383e;
  position: absolute;
  top: 0;
  left: 150px;
  width: calc(80vw - 50%);
  height: auto;
  list-style: none;
  /* padding: 20px; */
  display: none;
  height: 92%;
  overflow-y: auto;
  padding-top: 0px;
  z-index: 1000;
  max-width: 840px;
  padding-top: 13px;
  line-height: 2;
}

.secondary-items a:link, .secondary-items a:visited{
  color:white !important;
}

JQUERY

$(document).ready(function () {

$(".item:contains(Categories)").hover(function () {
        if ($('.MegaMenuDiv').hasClass('displayHiddenMenu')) {          
        } else {
            console.log('No class, adding class');
            $('.MegaMenuDiv').addClass("displayHiddenMenu");
        }
    }); 

 /* Removes the submenu when the mouse moves away from categories */
 $('.item:contains(Categories)').on("mouseleave", function (event) {
       if ($('.MegaMenuDiv:hover').length > 0) {
       // do nothing
       } else {             
                $('.MegaMenuDiv').removeClass("displayHiddenMenu");
       }
});

$(".item:contains(Categories)").hover(function () {
    if ($('.MegaMenuDiv').hasClass('displayHiddenMenu')) {
      console.log('Item has class');
    } else {
      console.log('No class, adding class');
      $('.MegaMenuDiv').addClass("displayHiddenMenu");
    }
});

  $(".item:contains(Categories)").on("touchstart click", function () {
    if ($('.MegaMenuDiv').hasClass('displayHiddenMenu')) {
      $('.MegaMenuDiv').removeClass("displayHiddenMenu");
    } else {
      $('.MegaMenuDiv').removeClass("displayHiddenMenu");
      $('.MegaMenuDiv').addClass("displayHiddenMenu");
    }
  });

  $('.MegaMenuDiv').on("mouseleave", function () {
    console.log('Mouseleave remove class');
    $('.MegaMenuDiv').removeClass("displayHiddenMenu");
  });

//Code for child menu elements
  $('.MegaMenuLinkMainWithChildren').hover(function () {
        if ($(this).next().hasClass('displayHiddenMenu')) {
                //do nothing
        } else {
            $('.MegaMenuLinkMainWithChildren').next().removeClass('displayHiddenMenu');
            $(this).next().addClass('displayHiddenMenu');
        }
});

$('.MegaMenuLinkMainWithChildren').on('touchstart click', function () {
        var secondaryitems = $(this).next();        
        if ($(secondaryitems).hasClass('displayHiddenMenu')) {

        } else {
            $('.MegaMenuLinkMainWithChildren').next().not(secondaryitems).removeClass('displayHiddenMenu');
            $(secondaryitems).addClass("displayHiddenMenu");
        }
});

});

Ответы [ 2 ]

2 голосов
/ 22 марта 2020

Он лучше обходит проблему. Я слушаю clicks mouseevents и touchevents. Поэтому, надеюсь, должно работать на любом устройстве. Однако я не проверял это на Edge. Надеюсь, это поможет.

Вы также можете прослушать все элементы .NavMenu .item и скрыть .MegaMenuDiv, если это не элемент Категории, потому что кто-то может случайно навести элемент категории.

// main menu
$(".item:contains(Categories)").on('mouseenter touchstart click', function(e) {
	
	// toggle MegaMenuDiv on click
	e.type == 'click' ? $('.MegaMenuDiv').toggleClass("displayHiddenMenu") : $('.MegaMenuDiv').addClass("displayHiddenMenu");
});

$('#MegaMenuDiv').on('click', function(e){
	if(e.target == $('#MegaMenuDiv').get(0)){
  	$('.MegaMenuLinkMainWithChildren').next().removeClass('displayHiddenMenu');
  }
}).on('mouseleave', function(){
  $('#MegaMenuDiv .secondary-items').removeClass('displayHiddenMenu');
	$('#MegaMenuDiv').removeClass("displayHiddenMenu");
});

// MegaMenuLinkMainWithChildren
$(".MegaMenuLinkMainWithChildren").on('mouseenter touchstart click', function() {
	// toggle MegaMenuDiv
  $('.MegaMenuLinkMainWithChildren').next().removeClass('displayHiddenMenu');
  $(this).next().addClass('displayHiddenMenu');
});
.NavMenu{
  width:100%;
  height:40px;
  background-color:red;
  color:white !important;
}

.NavMenu ul li{
  list-style:none;
  display:inline-block;
  padding:10px;
}

.ul_menu li a:link{
  color:white;
}

.ul_menu li a:hover{
  color:black;
}

#MegaMenuDiv{
  background:black;
  color:white;
  position:absolute;
  width:550px;
  display:none;
  min-height:300px;
}

.MegaMenuDiv a:link{
  color:white;
}

.displayHiddenMenu{
  display: block !important;
}

.main-category-list li{
  list-style:none;
}

.secondary-items{
  background: #31383e;
  position: absolute;
  top: 0;
  left: 150px;
  width: calc(80vw - 50%);
  height: auto;
  list-style: none;
  /* padding: 20px; */
  display: none;
  height: 92%;
  overflow-y: auto;
  padding-top: 0px;
  z-index: 1000;
  max-width: 840px;
  padding-top: 13px;
  line-height: 2;
}

.secondary-items a:link, .secondary-items a:visited{
  color:white !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<nav class="NavMenu">
    <ul class="ul_menu">
        <li class="item">
            <a href="#">
                <span>
                    Home
                </span>
            </a>
        </li>
        <li class="item">
            <a>
                <span>
                    Categories
                </span>
            </a>
        </li>
    </ul>
</nav>
<div class="subLevel MegaMenuDiv" id="MegaMenuDiv">
    <div class="custom_megamenu_wrapper">
        <ul class="main-category-list has-children">
            <li>
                <a class="Parent_Mega_Menu_Categories MegaMenuLinkMainWithChildren" href="javascript:void(0)" style="">
                    Accessories
                </a>
                <ul class="secondary-items">
                    <li>
                        <a class="MegaMenu_Child_Link" href="https://www.google.com" style="">
                            Accessory Holders
                        </a>
                    </li>
                    <li>
                        <a class="MegaMenu_Child_Link" href="https://www.google.com" style="">
                            Whiteboard Starter Pack
                        </a>
                    </li>
                </ul>
            </li>
            <li>
                <a class="Parent_Mega_Menu_Categories MegaMenuLinkMainWithChildren" href="javascript:void(0)" style="">
                    Other
                </a>
                <ul class="secondary-items">
                    <li>
                        <a class="MegaMenu_Child_Link" href="https://www.google.com" style="">
                            Accessory
                        </a>
                    </li>
                    <li>
                        <a class="MegaMenu_Child_Link" href="https://www.google.com" style="">
                            Starter Pack
                        </a>
                    </li>
                </ul>
            </li>
        </ul>
    </div>
</div>
1 голос
/ 23 марта 2020

Я поиграл с некоторым кодом и смог заставить его работать. Событие mouseleave и hover не будет запускаться на сенсорных устройствах, что заставляет его работать.

$(document).ready(function () {

var touched = false;

    $(".item:contains(Categories)").on("mouseenter click", function (e) {
        if (!touched) {
            e.type == 'click' ? $('.MegaMenuDiv').toggleClass("displayHiddenMenu") : $('.MegaMenuDiv').addClass("displayHiddenMenu");
        }
    }).on('touchstart', function (e) {
        touched = true;
        setTimeout(function () {
            touched = false;
        }, 300);
        // do touchstart stuff (similar to click or not)
        // toggle MegaMenuDiv on click
        if ($('.MegaMenuDiv').hasClass('displayHiddenMenu')) {
            $('.MegaMenuDiv').removeClass("displayHiddenMenu");
        } else {
            $('.MegaMenuDiv').addClass("displayHiddenMenu");
        }
    });

    $('.MegaMenuDiv').on("mouseleave", function () {
        if (!touched) {
            $('.MegaMenuDiv').removeClass("displayHiddenMenu");
        }
    });

    // MegaMenuLinkMainWithChildren - Show children items
    $(".MegaMenuLinkMainWithChildren").on('mouseenter touchstart click', function () {
        // toggle MegaMenuDiv
        $('.MegaMenuLinkMainWithChildren').next().removeClass('displayHiddenMenu');
        $(this).next().addClass('displayHiddenMenu');
    });

    //Removes the sub-menu when hovering over other menu items
    $('.item').not(".item:contains(Categories)").hover(function () {
        console.log('Hovering over other items, remove class');
        if ($('.MegaMenuDiv').hasClass('displayHiddenMenu')) {
            $('.MegaMenuDiv').removeClass("displayHiddenMenu");
        }
    });

    //Add a cursor the the pointer
    $(".item:contains(Categories)").css("cursor", "pointer");

});

Вот последняя скрипка: https://jsfiddle.net/Tig7r/htLny8a7/1/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...