绑定'touchstart'和'click'时防止鬼点击

时间:2013-11-26 18:33:40

标签: jquery mobile

我正在开发一款应用,在我的桌面和手机上进行测试。我正在尝试修复移动设备上的这些慢速按钮,并了解touchstart和click之间的区别。

所以我用jquery绑定我的按钮来同时执行touchstart和click:

$('.button').on('touchstart click', function(){
});

现在该应用在手机上的表现稍好一些。但是,它正在执行触摸点击,然后定期点击,即可能双击,或者当下一张幻灯片进入时,它会点击那里的某些内容。在我的情况下,表单正在出现,并且选中了单击按钮所在的空间中显示的输入字段。鬼点击。

如何告诉我的功能,如果有触摸,请忽略点击?

或者更好的是,有没有办法告诉jquery只是承认所有“点击”是否接触?

我会删除'click'绑定,但是我无法在桌面环境中完全测试。

9 个答案:

答案 0 :(得分:23)

如果您想针对不同的事件类型执行特定操作,请使用e.type

$('.button').on('touchstart click', function(e) {    
    e.preventDefault(); //prevent default behavior
    if(e.type == "touchstart") {
        // Handle touchstart event.
    } else if(e.type == "click") {
        // Handle click event.
    }
});

答案 1 :(得分:12)

Touchstart应该在点击之前发生,所以如果事件是touchstart类型,我会删除点击处理程序。这似乎很适合我的目的:

$('.do-popdown').on('click touchstart', handlePopdown);
function handlePopdown(e){
    if(e.type == 'touchstart') {
        $('.do-popdown').off('click', handlePopdown).click(function(e){
            // do nothing
            e.stopPropagation();
            e.preventDefault();
            return false;
        });
    }
    // do my handling...
    // and nothing else:
    e.stopPropagation();
    e.preventDefault();
    return false;
}

e.stopPropagation(); e.preventDefault(); return false;可能过度,但我会在各种不同的元素上使用它(<a><div><span><button>,&amp; c。)这符合我的惯常需求。

编辑:更通用(更好?)方法是创建类似于熟悉的.click()事件活页夹的内容:

jQuery.fn.extend({
    clickOrTouch: function(handler) {
        return this.each(function() {
            var event = ('ontouchstart' in document) ? 'touchstart' : 'click';
            $(this).on(event, handler);
        });
    }
});

这样,只有适当的事件附加到所选元素。

我认为更“正确”的名称是.touchstartOrClick(),但由于它或多或少是.click()的替代品,我决定以click开头。

这可以像.click()一样使用。例如,将button放在div内并运行:

$('button').clickOrTouch(doSomething);
$('div').clickOrTouch(doSomething);
function doSomething(e) {
    $('body').append(this.tagName + ' ' + e.type + '<br>');
    e.stopPropagation();
}

这将显示“DIV click”或“BUTTON touchstart”,具体取决于它是如何触发的。如果在链接上使用此功能,请在处理程序中添加e.preventDefault()

答案 2 :(得分:3)

@Krishna的这段代码对我不起作用:

$('.button').on('touchstart click', function(e) {    
    e.stopPropagation(); //stops propagation
    if(e.type == "touchstart") {
        // Handle touchstart event.
    } else if(e.type == "click") {
        // Handle click event.
    }
});

但是这个应该可行,正如@Slashback最初建议的那样。

$('.button').on('touchstart click', function(e) {    
    e.preventDefault();

    if(e.type == "touchstart") {
        // Handle touchstart event.
    } else if(e.type == "click") {
        // Handle click event.
    }
});

.preventDefault()单独为我工作而不是.stopPropagation()。我也不必做过度杀伤。

答案 3 :(得分:1)

我正在使用PhoneGap。这可能有用:

function longTapEvent(id, longTapFun) {
    $(id).click(function() {
        longTapFun();
        return;
    })

    $(id).unbind("touchstart");
    $(id).bind("touchstart", function() {
        //do sth...
    });
    $(id).unbind("touchend");
    $(id).bind("touchend", function() {
        //do sth...
    });
}

答案 4 :(得分:0)

使用data-tap-disabled =&#34; true&#34; on element解决了我的问题。

http://ionicframework.com/docs/api/page/tap/

答案 5 :(得分:0)

如果之前的火灾不是点击(即触摸或其他东西),你可以检测到点击并转义函数的当前触发 - 在vanilla js中:

buttonx.addEventListener('touchend',clicktap);
buttonx.addEventListener('click',clicktap);

function clicktap(e) {
var c = e.type.includes("click"); // or "mouse" if using "mousedown"
if (c && (this.wastouched)) return this.wastouched = 0;
this.wastouched = !c;

// ..run things..

}

答案 6 :(得分:0)

这是我自己酿制的解决方案,请批评一下!谢谢!

基本上,如果您单击价格按钮,则该商品会立即添加到购物车中。

如果您点击/触摸按钮,它将显示价格。 第二次点击/触摸将其添加到购物车。

在此处查看实际操作:https://www.indospace.io/studio-city/urban-treez

    var price_button = $(evt.target).closest('.price-button')
    if(price_button.length) {
        price_button.on('mouseleave', function() {
            $(this).removeAttr('data-touched')
        })
        if(evt.type == 'touchstart') {
            jQuery.touch_start = true
            if(!price_button.attr('data-touched')) {
                price_button.attr('data-touched', 1)
                return
            }
            price_button.attr('data-touched', 2)
        }
        if(evt.type == 'click') {
            if(price_button.attr('data-touched'))
                return
        }
        bag.add(price_button)
        return true
    }

答案 7 :(得分:0)

如果目的是区分用户拖动和点击,使用 touchmove 而不是 touchstart 的 vanilla JS 对我有用:

 document.querySelector("#mydiv").addEventListener("click", function(e){
    console.log("click");
 });
 let count = 0;
 document.querySelector("#mydiv").addEventListener("touchmove", function(e){
    e.preventDefault();

    // if need to detect once
    //count++;
    //if(count == 3){
    //  console.log("dragged!");  // dragHandler(), and reset count later
    //}

    console.log("touchmove");
 });

更多信息:https://developer.mozilla.org/en-US/docs/Web/API/Touch_events/Supporting_both_TouchEvent_and_MouseEvent

答案 8 :(得分:-1)

我在我的项目中使用以下内容:

$('.button').on('touchstart', function() {

   var thisButton = $(this); 
   if(!thisButton.hasClass('disabled')) {
     thisButton.addClass('disabled'); //add class disabled to prevent double execution

     ............rest of code

     window.setTimeout(function () {
        thisButton.removeClass('disabled'); //remove class disalbed after 300ms
     }, 300);

});

我希望这会对某人有所帮助。