如何在移动设备上手动触发 mouseleave 事件

Posted

技术标签:

【中文标题】如何在移动设备上手动触发 mouseleave 事件【英文标题】:How to manually trigger the mouseleave event on a mobile device 【发布时间】:2021-11-20 22:49:42 【问题描述】:

我想将hover 上的链接颜色更改为橙​​色。

在移动设备上,当用户触摸该链接时,它会变成橙色,并且会一直保持橙色,直到用户点击离开。所以我想手动触发mouseout事件,让链接在1秒后失去悬停效果。

这是我尝试过的,但链接在 1 秒后仍为橙色:

$(window).on('load', function() 
  $('a').on('click', function() 
    
    // on a mobile device, I want the hover effect to end after 1 seconds
    window.setTimeout(function() 
      $('a').trigger('mouseout');
    , 1000);
  
  );
);
a 
  font-size: 2rem;


a:hover 
  color: orange;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <a href='#'>Test</a>
</div>

注意:这是一个简化的示例,在我的代码中,我没有使用计时器,而是想在 ajaxcomplete 上触发 mouseout 事件

$(document).on('ajaxComplete', function () 
    $('a').trigger('mouseout');
);

【问题讨论】:

如果只是在点击时添加一个类,然后在触发 ajaxComplete 后删除该类,不是更简单吗? 就其价值而言,似乎大多数解决方案都会涉及一些针对悬停状态的 hack-ish 变通办法,这在无光标环境的上下文中并没有多大意义。如果悬停视觉处理存在问题,是否只抑制小屏幕或触摸界面的悬停状态会更好? 【参考方案1】:

a 
  font-size: 2rem;


a:hover 
  color: myanimation 1s 1;
  -webkit-animation:myanimation 1s 1;


@keyframes myanimation

    0%      color:orange;
    100%    color:orange;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <a href='#'>Test</a>
</div>

这可以通过 CSS 动画解决,参见上面的 sn-p。

【讨论】:

谢谢,但这会破坏桌面功能,因为橙色会在一秒钟后消失……还有 1 秒钟用于演示我想在ajaxcomplete触发事件 @HoomanBahreini 您可以在移动时将名为mobile 的类添加到body,并将规则更改为.mobile a:hover @HoomanBahreini 您还可以应用媒体查询来区分悬停,将之前的悬停效果用于大屏幕,将建议的悬停效果用于小屏幕。 不幸的是,“移动测试”不起作用,因为小视口也可以在支持鼠标的设备上,而触摸设备可以很大。您需要检查用户是使用触摸还是鼠标 - 这并不可靠,他们可能同时使用两者。 @AHaworth 如果存在这种担忧,则可以从用户代理读取信息并使用该信息来确定它是否是触摸屏。在我们的示例中,该设备是问题中指定的移动设备,这就是我假设小屏幕的原因,因为很难想象有人在街上携带大电视屏幕并使用它。然而,如果我们将问题空间扩大到触摸屏,那么用户代理数据就会派上用场。【参考方案2】:

问题是试图强制 mouseout 事件在触摸设备上似乎不起作用。

在触摸设备上触发的一系列事件以 touchstart 事件开始 - 参见例如MDN

如果浏览器因为单个用户输入而同时触发触摸和鼠标事件,则浏览器必须在任何鼠标事件之前触发 touchstart。

这个 sn-p 记住用户已经启动了一个触摸事件,而不是对鼠标事件进行操作,它设置了一个更改文本颜色的类。鼠标事件也是如此,仅当用户似乎没有在此元素上使用触摸设备时才会执行鼠标事件。

虽然随后在元素上查找 touchend 事件似乎是合乎逻辑的,但似乎如果用户对它进行长时间触摸,假设它是一个锚元素,则在元素上不会触发 touchend 事件移除他们的手指/指点设备。但是它仍然在窗口上触发,因此我们捕获该事件并删除悬停类。

let usingTouch = false;
const a = document.querySelector('a');
a.addEventListener('touchstart', function() 
  usingTouch = true;
  a.classList.add('hover');
);
window.addEventListener('touchend', function() 
  usingTouch = true;
  setTimeout(function() 
    a.classList.remove('hover');
  , 1000);
);
a.addEventListener('mouseover', function() 
  if (!usingTouch) a.classList.add('hover');
);
a.addEventListener('mouseout', function() 
  if (!usingTouch) a.classList.remove('hover');
);
a 
  font-size: 2rem;


.hover 
  color: orange;
<div>
  <a href='#'>Test</a>
</div>

【讨论】:

以上是关于如何在移动设备上手动触发 mouseleave 事件的主要内容,如果未能解决你的问题,请参考以下文章

mouseover mouseleave

为啥mouseleave一直在触发?

JQuery事件与效果

mouse事件(mouseleave,mouseenter,mouseout,mouseover)

鼠标与滚轮事件

Jquery 判断是否 移动设备 浏览