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');
}
});