gpt4 book ai didi

javascript - 多个同时发生的事件javascript

转载 作者:行者123 更新时间:2023-11-30 15:04:57 24 4
gpt4 key购买 nike

这可能是个愚蠢的问题。我知道我有点绿。我的任务是修改这个旧系统的导航。有两个导航栏。第二个只有搜索按钮。我被要求删除第二个导航栏,并将其替换为显示搜索功能的下拉菜单。由于该系统的年龄,我可以更改的内容受到限制。我能写的JS没有任何限制。他们在 Adob​​e ColdFusion 系统上运行 jQuery 1.11.1(两个月前他们从 1.3.2 升级)

首先:当目标被点击时,mouseenter和click事件都会触发。 mouseenter 首先触发。这会导致敏锐的观众在桌面上看到一个问题,但在移动设备上,这会产生一个可怕的可用性问题。 A:根据我的理解,鼠标事件不会发生在移动设备上,而是为我做的。 B:由于 mouseenter 事件先运行,所以它在处理 click 事件之前激活了 closeDropDown 函数。随着 closeDropDown 的运行,它的 .on('click', f(...eventstuff...)) 听到旨在触发 openDropDown 函数的打开点击,因此下拉不会打开。

这里是函数。 console.log 用于检查什么时候运行。

function openDropDown(){
$('div.dropdown').parent().on('click.open mouseenter', function(event){

$subject = $(this).find('.dropdown-menu')
// console.log(event.type, $subject, "first o");

if(!$subject.is(":visible")){
// console.log($subject, 'second o');

$subject.show()
}else {
if(event.type == 'click'){
// console.log('third o');

$subject.toggle()
}
}

closeDropDown($subject)
// console.log('open complete');
})
}


function closeDropDown($x){
// console.log('first c');

$(document).on("click.close",function(e){
// console.log("second c", e.type, "this type");

if(!$(e.target).closest(".dropdown-menu").parent().length){
// console.log("third c");

if($x.is(":visible")){
// console.log('forth c');
$x.hide()
}
}

$(document).off("click.close")
// console.log('complete close');
})
}

openDropDown()
onSearchClick()

我已经阅读了一些希望得到帮助的帖子(例如 thisthat

总而言之,我知道我需要压缩我的代码。我了解解决此问题的几种方法(添加 if(... are we on a mobile device...) 或一些计数器/检查以防止 closeDropDown 在下拉菜单关闭时运行)

我真的很想了解事件监听器的基础知识以及为什么一个监听器先于其他监听器运行。

虽然关于如何解决这个问题的建议很好,但我希望了解我做错事的基本原理。任何基本指标都非常有帮助。

注意:我刚刚读到这个:.is(':visible') not working .我将在没有 .is('visible') 的情况下重写代码。

其他可能有帮助的事情:当我的所有 console.log(s) 都处于事件状态时,这是 Chrome Dev Tools 控制台。首先,在页面加载后单击.... enter image description here下拉菜单打开并快速关闭。

第二次点击.... enter image description here

谢谢!感谢您的帮助!

最佳答案

这是一个相当宽泛的问题。我会尽量简洁。我不认为 ColdFusion 应该被标记在这里,因为它似乎只与 HTML/CSS/JS 有关。

配置事件

首先,我想谈谈您配置脚本的方式。您可能会从查看事件处理中受益 examples from jquery .

大多数人都会创建如下事件。它只是说在单击任何具有“alerter”ID 的文档元素时,运行警报功能。

// Method 1
$(document).on(click, "#alerter", function(event){
alert("Hi!");
});

// Method 2 
$(document).on("click", "#alerter", ClickAlerter);

function ClickAlerter(event) {
alert("Hi!");
}

这两种方法都是完全有效的。但是,我的意见是第二种方法更具可读性和可维护性。它将事件委托(delegate)与逻辑分开。

对于您的代码,我强烈建议删除事件分配和逻辑的混合。 (它至少移除了一层嵌套)。

顺便说一下,您的事件监听器似乎配置不正确。参见 the correct syntax以及这个来自 jQuery 的示例。

$( "#dataTable tbody" ).on( "click", "tr", function() {
console.log( $( this ).text() );
});

关于多个事件

如果您在一个对象上有多个事件监听器,那么它们将按照它们注册的顺序被触发。 This SO question已经涵盖了这一点并提供了一个例子。

但是,这并不意味着在鼠标输入之前会发生点击。因为您的鼠标必须真正进入元素才能单击它,所以 mouseenter 的事件将首先被触发。换句话说,在考虑事件顺序时,您至少有 2 个因素在起作用。

  1. 浏览器触发事件​​的顺序
  2. 他们注册的顺序

因此,实际上并没有所谓的“同时”事件。当浏览器想要触发事件时,事件就会被触发,它们将遍历事件并按照您指定的顺序触发匹配项。

您始终可以选择 preventDefaultstopPropagation如果您想更改默认事件行为,请对这些类型的事件进行处理。这将停止浏览器的默认操作,并分别阻止事件冒泡到父元素。

关于移动鼠标事件

鼠标事件绝对会发生在移动设备上,假设它们不会发生是不安全的。 This article深入介绍了触发事件的范围。引用:

"[Y]ou have to be careful when designing more advanced touch interactions: when the user uses a mouse it will respond via a click event, but when the user touches the screen both touch and click events will occur. For a single click the order of events is:

touchstart
touchmove
touchend
mouseover
mousemove
mousedown
mouseup
click

我认为您会从阅读那篇文章中获益。它涵盖了有关移动和非移动环境中事件的常见问题和概念。同样,关于您的情况的相关声明:

Interestingly enough, though, the CSS :hover pseudoclass CAN be triggered by touch interfaces in some cases - tapping an element makes it :active while the finger is down, and it also acquires the :hover state. (With Internet Explorer, the :hover is only in effect while the user’s finger is down - other browsers keep the :hover in effect until the next tap or mouse move.)

一个例子

我接受了所有这些概念和made an example on jsFiddle向您展示其中一些实际情况。基本上,我通过监听 touchstart 事件并在这种情况下以不同方式处理 click 来检测用户是否正在使用触摸屏。因为我没有你的 HTML,所以我不得不制作一个原始界面。这些是指令:

  1. 我们需要确定用户是否有触摸屏
  2. 当用户将鼠标悬停到按钮上时,菜单应该出现
  3. 在移动设备上,当用户点击按钮时,菜单应该出现
  4. 我们需要在用户点击按钮外部时关闭菜单
  5. 离开按钮应关闭菜单(移动或其他方式)

正如您将看到的,我在一个地方创建了所有事件:

$(document).on("mouseover", "#open", $app.mouseOver);
$(document).on("mouseout", "#open", $app.mouseOut);
$(document).on("click", "#open", $app.click);
$(document).on("touchstart", $app.handleTouch);
$(document).on("touchstart", "#open", $app.click);

我还创建了一个对象来包装所有逻辑,$app,这为我们提供了更大的灵 active 和可读性。这是它的一个片段:

var $app = $app || {}; 
$app = {

hasTouchScreen: false,

handleTouch:function(e){
// fires on the touchstart event
$app.hasTouchScreen = true;
$("#hasTouchScreen").html("true");
$(document).off("touchstart", $app.handleTouch);
},

click: function(e) {
// fires when a click event occurrs on the button
if ($app.hasTouchScreen) {
e.stopPropagation();
e.preventDefault();
return;
}

// since we don't have a touchscreen, close on click.
$app.toggleMenu(true);
},

touch: function(e) {
// fires when a touchstart event occurs on the button
if ($("#menu").hasClass("showing")) {
$app.toggleMenu(true);
} else {
$app.toggleMenu();
}
}

};

关于javascript - 多个同时发生的事件javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45928973/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com