Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jquery 如何绑定&x27;touchstart';和';单击';事件,但两者都不响应?_Jquery_Click_Touchstart - Fatal编程技术网

Jquery 如何绑定&x27;touchstart';和';单击';事件,但两者都不响应?

Jquery 如何绑定&x27;touchstart';和';单击';事件,但两者都不响应?,jquery,click,touchstart,Jquery,Click,Touchstart,我在一个移动网站上工作,该网站必须在各种设备上工作。现在让我头疼的是黑莓手机 我们需要同时支持键盘点击和触摸事件 理想情况下,我只会使用: $thing.click(function(){...}) 但我们遇到的问题是,从触摸到触发点击,这些黑莓设备中的一些设备都有一个非常恼人的延迟 补救办法是改用touchstart: $thing.bind('touchstart', function(event){...}) 但是如何绑定这两个事件,但只触发一个?我仍然需要键盘设备的点击事件,但当然,

我在一个移动网站上工作,该网站必须在各种设备上工作。现在让我头疼的是黑莓手机

我们需要同时支持键盘点击和触摸事件

理想情况下,我只会使用:

$thing.click(function(){...})
但我们遇到的问题是,从触摸到触发点击,这些黑莓设备中的一些设备都有一个非常恼人的延迟

补救办法是改用touchstart:

$thing.bind('touchstart', function(event){...})
但是如何绑定这两个事件,但只触发一个?我仍然需要键盘设备的点击事件,但当然,如果我使用触摸设备,我不希望点击事件触发

还有一个额外的问题:是否有其他方法可以做到这一点,并额外适应甚至没有touchstart事件的浏览器?在研究这一点时,黑莓OS5似乎不支持touchstart,因此该浏览器也需要依赖点击事件

增编:

也许更全面的问题是:

使用jQuery,是否可以/建议使用相同的绑定处理触摸交互和鼠标交互

理想情况下,答案是肯定的。如果没有,我有一些选择:

1) 我们使用WURFL获取设备信息,以便创建我们自己的设备矩阵。根据设备的不同,我们将使用touchstart或单击

2) 通过JS在浏览器中检测触摸支持(我需要做更多的研究,但这似乎是可行的)


然而,这仍然存在一个问题:支持这两种功能的设备如何。我们支持的一些手机(即诺基亚和黑莓)既有触摸屏又有键盘。因此,这让我又回到了最初的问题……有没有一种方法可以同时考虑这两个问题呢?

更新:查看jQuery项目,它允许您绑定到“指针”事件,而不是在鼠标和触摸之间进行选择


绑定到两者,但设置一个标志,使函数仅每100ms左右触发一次

var flag = false;
$thing.bind('touchstart click', function(){
  if (!flag) {
    flag = true;
    setTimeout(function(){ flag = false; }, 100);
    // do something
  }

  return false
});

通常,您不希望将默认触摸和非触摸(单击)api混合使用。一旦进入触摸世界,只处理触摸相关功能就更容易了。下面是一些伪代码,可以实现您想要的功能

如果您在touchmove事件中连接并跟踪位置,您可以在doTouchLogic功能中添加更多项目以检测手势等

var touchStartTime;
var touchStartLocation;
var touchEndTime;
var touchEndLocation;

$thing.bind('touchstart'), function() {
     var d = new Date();
     touchStartTime = d.getTime();
     touchStartLocation = mouse.location(x,y);
});

$thing.bind('touchend'), function() {
     var d = new Date();
     touchEndTime= d.getTime();
     touchEndLocation= mouse.location(x,y);
     doTouchLogic();
});

function doTouchLogic() {
     var distance = touchEndLocation - touchStartLocation;
     var duration = touchEndTime - touchStartTime;

     if (duration <= 100ms && distance <= 10px) {
          // Person tapped their finger (do click/tap stuff here)
     }
     if (duration > 100ms && distance <= 10px) {
          // Person pressed their finger (not a quick tap)
     }
     if (duration <= 100ms && distance > 10px) {
          // Person flicked their finger
     }
     if (duration > 100ms && distance > 10px) {
          // Person dragged their finger
     }
}
var开始时间;
var定位;
var-touchEndTime;
var-touchEndLocation;
$thing.bind('touchstart'),function(){
var d=新日期();
touchStartTime=d.getTime();
touchStartLocation=鼠标位置(x,y);
});
$thing.bind('touchend'),function(){
var d=新日期();
touchEndTime=d.getTime();
touchEndLocation=鼠标位置(x,y);
doTouchLogic();
});
函数doTouchLogic(){
var距离=touchEndLocation-touchStartLocation;
var持续时间=touchEndTime-touchStartTime;
如果(持续时间10px){
//那个人拖着手指
}
}

您可以尝试以下方法:

var clickEventType=((document.ontouchstart!==null)?'click':'touchstart');
$("#mylink").bind(clickEventType, myClickHandler);
var clickEvent = (('ontouchstart' in document.documentElement)?'touchstart':'click');
$("#mylink").on(clickEvent, myClickHandler);

我还在开发一款Android/iPad网络应用程序,似乎只要使用“touchmove”就足以“移动组件”(不需要touchstart)。 通过禁用touchstart,您可以使用。单击();来自jQuery。它实际上在工作,因为它没有被touchstart过载

$.fn.extend({ _on: (function(){ return $.fn.on; })() });
$.fn.extend({
    on: (function(){
        var isTouchSupported = 'ontouchstart' in window || window.DocumentTouch && document instanceof DocumentTouch;
        return function( types, selector, data, fn, one ) {
            if (typeof types == 'string' && isTouchSupported && !(types.match(/touch/gi))) types = types.replace(/click/gi, 'touchstart');
            return this._on( types, selector, data, fn);
        };
    }()),
});
最后,您可以使用binb.live(“touchstart”,函数(e){e.stopPropagation();});要要求touchstart事件停止传播,请单击客厅()以触发


它对我起了作用。

我通过以下方式成功了

简单的豌豆

$(this).on('touchstart click', function(e){
  e.preventDefault();
  //do your stuff here
});

另一个实现是为了更好地维护。但是,此技术也将执行event.stopPropagation()。在单击100毫秒的任何其他元素上都不会捕捉到该单击

var clickObject = {
    flag: false,
    isAlreadyClicked: function () {
        var wasClicked = clickObject.flag;
        clickObject.flag = true;
        setTimeout(function () { clickObject.flag = false; }, 100);
        return wasClicked;
    }
};

$("#myButton").bind("click touchstart", function (event) {
   if (!clickObject.isAlreadyClicked()) {
      ...
   }
}
这是我“创建”的修复,它去掉了GhostClick并实现了FastClick。你自己试试,让我们知道它是否对你有用

$(document).on('touchstart click', '.myBtn', function(event){
        if(event.handled === false) return
        event.stopPropagation();
        event.preventDefault();
        event.handled = true;

        // Do your magic here

});

当试图解决这个问题时,有很多事情要考虑。大多数解决方案要么中断滚动,要么不能正确处理重影单击事件

有关完整解决方案,请参阅


注意:不能基于每个元素处理重影单击事件。屏幕位置会触发延迟单击,因此如果您的触摸事件以某种方式修改页面,则单击事件将发送到页面的新版本。

检查快速按钮和从谷歌选择的单击通常也可以:

$('#buttonId').on('touchstart click', function(e){
    e.stopPropagation(); e.preventDefault();
    //your code here

});

为事件指定“touchstart mousedown”或“touchend mouseup”可能是有效的,以避免使用
点击

产生不希望的副作用,利用点击总是会跟随触摸事件的事实,以下是我为消除“幻影点击”所做的无需使用超时或全局标志

$('#buttonId').on('touchstart click', function(event){
    if ($(this).data("already")) {
        $(this).data("already", false);
        return false;
    } else if (event.type == "touchstart") {
        $(this).data("already", true);
    }
    //your code here
});

基本上,每当元素上触发一个
ontouchstart
事件时,一个标记就会被设置,然后在单击到来时被删除(并被忽略)。

为什么不使用jQuery事件API

我成功地利用了这个简单的事件。它干净、可命名,并且足够灵活,可以对其进行改进

var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
var eventType = isMobile ? "touchstart" : "click";

jQuery.event.special.touchclick = {
  bindType: eventType,
  delegateType: eventType
};

仅出于文档目的,以下是我为最快/响应最快的桌面点击/移动点击解决方案所做的工作:

我将jQuery的
on
功能替换为一个经过修改的功能,每当浏览器支持触摸事件时,它都会将我的所有点击事件替换为touchstart

$.fn.extend({ _on: (function(){ return $.fn.on; })() });
$.fn.extend({
    on: (function(){
        var isTouchSupported = 'ontouchstart' in window || window.DocumentTouch && document instanceof DocumentTouch;
        return function( types, selector, data, fn, one ) {
            if (typeof types == 'string' && isTouchSupported && !(types.match(/touch/gi))) types = types.replace(/click/gi, 'touchstart');
            return this._on( types, selector, data, fn);
        };
    }()),
});
用法与以前完全相同,如:

$('#my-button').on('click', function(){ /* ... */ });

但它会在可用时使用touchstart,在不可用时单击。不需要任何形式的延迟:我不得不做类似的事情。这是一个对我有用的简化版本。如果检测到触摸事件,请删除单击绑定

$thing.on('touchstart click', function(event){
  if (event.type == "touchstart")
    $(this).off('click');

  //your code here
});
在我的例子中,click事件绑定到一个
元素,因此我必须删除click绑定并
  function filterEvent( ob, ev ) {
      if (ev.type == "touchstart") {
          ob.off('click').on('click', function(e){ e.preventDefault(); });
      }
  }
  $('#keypad').on('touchstart click', '.number, .dot', function(event) {
      filterEvent( $('#keypad'), event );
      console.log( event.type );  // debugging only
           ... finish handling touch events...
  }
ev = Modernizr.touch ? 'touchstart' : 'click';

$('#menu').on(ev, '[href="#open-menu"]', function(){
  //winning
});
bindBtn ("#loginbutton",loginAction);

function bindBtn(element,action){

var flag = false;
$(element).bind('touchstart click', function(e) {
    e.preventDefault();
    if (!flag) {
        flag = true;
        setTimeout(function() {
            flag = false;
        }, 100);
        // do something
        action();
    }
    return false;
});
$(document.body).touchOrMouse('init');
$('.link').click(function(e) {
  var touchOrMouse = $(document.body).touchOrMouse('get', e);

  if (touchOrMouse === 'touch') {
    // Handle touch click.
  }
  else if (touchOrMouse === 'mouse') {
    // Handle mouse click.
  }
}
$thing.on('vclick', function(event){ ... });
var clickEvent = (('ontouchstart' in document.documentElement)?'touchstart':'click');
$("#mylink").on(clickEvent, myClickHandler);
 $btnUp.bind('touchstart mousedown',function(e){
     e.preventDefault();

     if (e.type === 'touchstart') {
         return;
     }

     var val = _step( _options.arrowStep );
               _evt('Button', [val, true]);
  });
// A very simple fast click implementation
$thing.on('click touchstart', function(e) {
  if (!$(document).data('trigger')) $(document).data('trigger', e.type);
  if (e.type===$(document).data('trigger')) {
    // Do your stuff here
  }
});
// A very simple fast click plugin
// Syntax: .fastClick([selector,] handler)
$.fn.fastClick = function(arg1, arg2) {
  var selector, handler;
  switch (typeof arg1) {
    case 'function':
      selector = null;
      handler = arg1;
      break;
    case 'string':
      selector = arg1;
      if (typeof arg2==='function') handler = arg2;
      else return;
      break;
    default:
      return;
  }
  this.on('click touchstart', selector, function(e) {
    if (!$(document).data('trigger')) $(document).data('trigger', e.type);
    if (e.type===$(document).data('trigger')) handler.apply(this, arguments);
  });
};
$(this).on("click touchstart", function() {
  // Do things
  return false;
});
$("body").on("touchstart", ".touchable", function() { //make touchable  items fire like a click event
var d1 = new Date();
var n1 = d1.getTime();
setTimeout(function() {
    $(".touchable").on("touchend", function(event) {
        var d2 = new Date();
        var n2 = d2.getTime();
        if (n2 - n1 <= 300) {
            $(event.target).trigger("click"); //dont do the action here just call real click handler
        }
    });
}, 50)}).on("click", "#myelement", function() {
//all the behavior i originally wanted
});
$('#object').on('touchend mouseup', function () { });
jQuery(document).on('mouseup keydown touchend', function (event) {
var eventType = event.type;
if (eventType == 'touchend') {
    jQuery(this).off('mouseup');
}
});