JQuery .on("点击")触发"鼠标悬停"在触摸设备上

时间:2016-05-24 03:08:46

标签: javascript jquery touch mouseevent touch-event

在触摸设备上使用JQuery的$.on("click", function(){});时,我遇到了不受欢迎的行为。这是我的代码:

代码:

$(".team").on("mouseover", teamMouseOver);
$(".team").on("mouseout", teamMouseOut);
$(".team").on("click", teamThumbClicked);

function teamMouseOver(event){
    console.log(event.type);
}

function teamMouseOut(event){
    // Do something
}

function teamThumbClicked(event){
    console.log("Clicked!");
}

问题:

使用上面的代码,点击触摸设备上的.team元素会同时触发两个侦听器,为我提供以下控制台日志:

mouseover
Clicked!

问题 为什么触摸设备会触发mouseover?这不是我对没有鼠标的设备所期望的行为。这是一个错误吗?我应该使用什么事件" mouseover"只有在它进入的实际鼠标指针时才会被触发?

我的JQuery版本是2.2.4。

3 个答案:

答案 0 :(得分:0)

我刚遇到同样的问题,这就是我为解决问题所做的工作。

$('#myEl').on('click', myElClickEvent);

$('#myEl').on('mouseenter', myElMouseEnterEvent);

function myElClickEvent (event) {
   $(this).addClass('Clicked');
}

function myElMouseEnterEvent() {
    // Turn off events
    $('#myEl').off();

    // After 100 milliseconds cut on events, notice click event won't trigger
    setTimeout(function() {
       // .off() is used to prevent from adding multiple click events if the user hovers multiple elements too quickly.
       $('#myEl').off().on('click', myElClickEvent);             
       $('#myEl').off().on('mouseenter', myElMouseEnterEvent);
    }, 100);


   // Do some mouseenter stuff, whatever the reqs. are.
}

这就是我所做的,它在我的用例中运行良好。希望这可以帮助将来的某个人。我们的想法是关闭鼠标输入事件中的单击事件,然后在100毫秒后重新打开鼠标单击事件。这样可以防止两个事件在触​​摸时触发。

答案 1 :(得分:0)

我遇到了同样的问题,也觉得不能将两个事件分开有点烦人。我解决这个问题的方法是添加 touchend 事件并让它首先标记它是一个触摸设备。由于其余事件将随之发生,我可以忽略它们或对它们执行其他操作,如果由非触摸设备触发,它们仍将运行。

var touchEndDetected = false;
var mouseOverDetected = false;

$('#myEl').on('click mouseover touchend', function (e) {
    console.log('Event type: ' + e.type);

    if(mouseOverDetected) {
        console.log('Mouseover event has already run this before');
        touchEndDetected = false;
        mouseOverDetected = false;
        return;
    }

    if(touchEndDetected) {
        touchEndDetected = false;
        mouseOverDetected = true;
        console.log('Touchend event has already run this before');
        return;
    }

    if(e.type === 'touchend') {
        touchEndDetected = true;
        mouseOverDetected = false;
    }

    console.log('This code will only run once when touch');
}

答案 2 :(得分:0)

在原始触摸事件上调用 .preventDefault()

API 链接实际上提供了答案。 https://developer.mozilla.org/en-US/docs/Web/API/Touch_events/Supporting_both_TouchEvent_and_MouseEvent#event_firing

在您的情况下,您使用的是 jQuery 的 .on() 函数,您可以向该函数发送多个事件(以空格分隔),因此您可以将 touchstart ontouchstart 添加到该字符串并只需在处理程序函数中立即调用 preventDeault() 即可。

$(".team").on("click touchstart", teamThumbClicked);

// and later...

function teamThumbClicked(event){
    event.preventDefault(); // prevent further mouse events from being dispatched
    console.log("Clicked!");
}