[英]How can I detect when a user touches something other than a menu or it's children?
I'm trying to write some JavaScript to handle touch interactions on a drop down menu. 我正在尝试编写一些JavaScript来处理下拉菜单中的触摸交互。 This is working well, except that I can't figure out how to hide the menu when a user taps away from it.
这很好用,除了当用户点击它时我无法弄清楚如何隐藏菜单。
My script is as follows: 我的脚本如下:
// mark all menu items as inative
function mark_all_inactive(elem) {
elem.find(".is-active").removeClass("is-active");
elem.find("[aria-hidden=false]").attr("aria-hidden", "true");
}
// mark element as active
function mark_active(elem) {
elem.closest(".menu-list_item").addClass("is-active");
elem.siblings("[aria-hidden]").attr("aria-hidden", "false");
}
// open on touchstart
jQuery(".menu-list_item").not(".menu-list_item.-mega .menu-list_item.-parent").on("touchstart", function(e) {
if (!jQuery(this).hasClass("is-active") && jQuery(this).children("[aria-hidden]").length) {
e.preventDefault();
mark_all_inactive(jQuery(this).closest(".menu-list"));
mark_active(jQuery(this).children(".menu-list_link"));
}
});
// hide on focusout
jQuery(".menu-list").on("focusout", ".menu-list_link", function() {
var parent_item = jQuery(this).closest(".menu-list_item.-parent.is-active");
if (parent_item.length) {
// timeout required for the next element to get focus
setTimeout(function() {
if (!parent_item.find(":focus").length) {
parent_item.removeClass("is-active");
parent_item.children("[aria-hidden]").attr("aria-hidden", "true");
parent_item.closest(".menu-list_item.-parent.is-active").find(".menu-list_link").first().trigger("focusout");
}
}, 10);
}
});
As you can see, I'm using touchstart
to add some classes, which works perfectly. 正如您所看到的,我正在使用
touchstart
添加一些类,它们完美无缺。 The issue arises when trying to remove those classes. 尝试删除这些类时会出现问题。
The focusout
bit of code is primarily used for keyboard navigation, but I'd like to adapt it to also trigger when you tap away from the menu. 代码的
focusout
位主要用于键盘导航,但我想调整它以便在您点击菜单时触发。
From what I understand, mobile browsers typically don't fire focusout
when tapping away from something. 根据我的理解,移动浏览器通常不会在远离某些东西时触发
focusout
。 That seems odd to me, as you'd think tapping away from something would surly fire a focusout
regardless of input type, but that's beside the point. 这对我来说似乎很奇怪,因为你认为无论输入类型如何,从某些东西中
focusout
都会引起focusout
,但这不是重点。
I have looked in to touchend
, but that appears to fire immediately after lifting your finger, which isn't what I want. 我已经看了一下
touchend
,但是在抬起你的手指之后,它似乎立即开火,这不是我想要的。 The goal is to tap once to add the classes, then be able to lift your finger to select a child link (which can also contain flyout menus, thus re-using the same touchstart
script). 目标是点击一次添加类,然后能够抬起手指选择子链接(也可以包含弹出菜单,从而重新使用相同的
touchstart
脚本)。 Then, when you tap anywhere that's not the active menu, remove the classes. 然后,当您点击不是活动菜单的任何地方时,请删除这些类。
So, on to the question: Can the focusout
bit of script be modified to accommodate tapping away from a menu or it's children? 所以,关于这样一个问题:是否可以修改脚本的
focusout
位置,以适应从菜单或它的孩子focusout
? If not, how would I go about writing a second bit of script to accomplish that task? 如果没有,我将如何编写第二个脚本来完成该任务?
You can view a live demo at the follow URL: 您可以在以下网址查看实时演示:
https://framework.ghostlyco.de/ https://framework.ghostlyco.de/
I figured this out, but I don't know that it's the best way. 我想出来了,但我不知道这是最好的方式。 It seems kind of dumb to attach an event to the entire document, but this works:
将事件附加到整个文档似乎有点愚蠢,但这有效:
// hide on touch away
jQuery(document).on("touchstart", function(e) {
if (!jQuery(e.target).closest(".menu-list_item.-parent.is-active").length) {
jQuery(".menu-list_item.-parent.is-active").children("[aria-hidden]").attr("aria-hidden", "true");
jQuery(".menu-list_item.-parent.is-active").removeClass("is-active");
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.