DA.*_*DA. 40 javascript jquery scroll touch touch-event
我在移动设备上有一个可滚动的列表.他们希望人们能够通过滑动滚动列表,并通过点击选择一行.
抓住了两者.如果您实际滚动列表,我不希望选择一行.这是我发现的:
滚动时不触发:
滚动时是否触发:
简单的解决方案就是坚持点击事件.但我们发现,在某些黑莓设备上,touchstart之间存在非常明显的延迟,然后触发点击或鼠标.这种延迟足以使其在这些设备上无法使用.
所以这给我们留下了其他选择.但是,使用这些选项,您可以滚动列表而不触发您触摸的行以启动滚动.
解决此问题的最佳做法是什么?
Lev*_*ker 47
var touchmoved;
$('button').on('touchend', function(e){
if(touchmoved != true){
// button click action
}
}).on('touchmove', function(e){
touchmoved = true;
}).on('touchstart', function(){
touchmoved = false;
});
Run Code Online (Sandbox Code Playgroud)
Net*_*dia 23
你基本上想要做的是检测什么是滑动以及什么是点击.
我们可能会设置一些条件:
p1,然后将手指移动到指向p2同时仍然将手指放在屏幕上,然后松开.因此,如果您存储您所在位置的坐标touchStart,则可以测量其中的差异touchEnd.如果更改足够大,请将其视为滑动,否则,请将其视为单击.
此外,如果你想要做得非常整洁,你还可以在一个时间内用手指检测到你正在"悬停"的元素touchMove,如果你还没有在你开始点击的元素上,你可以运行一个clickCancel去除高光等的方法
// grab an element which you can click just as an example
var clickable = document.getElementById("clickableItem"),
// set up some variables that we need for later
currentElement,
clickedElement;
// set up touchStart event handler
var onTouchStart = function(e) {
// store which element we're currently clicking on
clickedElement = this;
// listen to when the user moves finger
this.addEventListener("touchMove" onTouchMove);
// add listener to when touch end occurs
this.addEventListener("touchEnd", onTouchEnd);
};
// when the user swipes, update element positions to swipe
var onTouchMove = function(e) {
// ... do your scrolling here
// store current element
currentElement = document.elementFromPoint(x, y);
// if the current element is no longer the same as we clicked from the beginning, remove highlight
if(clickedElement !== currentElement) {
removeHighlight(clickedElement);
}
};
// this is what is executed when the user stops the movement
var onTouchEnd = function(e) {
if(clickedElement === currentElement) {
removeHighlight(clickedElement);
// .... execute click action
}
// clean up event listeners
this.removeEventListener("touchMove" onTouchMove);
this.removeEventListener("touchEnd", onTouchEnd);
};
function addHighlight(element) {
element.className = "highlighted";
}
function removeHighlight(element) {
element.className = "";
}
clickable.addEventListener("touchStart", onTouchStart);
Run Code Online (Sandbox Code Playgroud)
然后,你将不得不侦听器添加到您滚动的元素还,但你不必担心,如果手指移动其间发生了什么touchStart和touchEnd.
var scrollable = document.getElementById("scrollableItem");
// set up touchStart event handler
var onTouchStartScrollable = function(e) {
// listen to when the user moves finger
this.addEventListener("touchMove" onTouchMoveScrollable);
// add listener to when touch end occurs
this.addEventListener("touchEnd", onTouchEndScrollable);
};
// when the user swipes, update element positions to swipe
var onTouchMoveScrollable = function(e) {
// ... do your scrolling here
};
// this is what is executed when the user stops the movement
var onTouchEndScrollable = function(e) {
// clean up event listeners
this.removeEventListener("touchMove" onTouchMoveScrollable);
this.removeEventListener("touchEnd", onTouchEndScrollable);
};
scrollable.addEventListener("touchStart", onTouchStartScrollable);
Run Code Online (Sandbox Code Playgroud)
// Simon A.
DA.*_*DA. 17
这是我最终提出的允许通过滑动滚动项目列表,但每个项目通过点击可以"触发".此外,您仍然可以使用键盘(使用onclick).
我认为这类似于Netlight_Digital_Media的回答.我需要多研究一下.
$(document)
// log the position of the touchstart interaction
.bind('touchstart', function(e){
touchStartPos = $(window).scrollTop();
})
// log the position of the touchend interaction
.bind('touchend', function(e){
// calculate how far the page has moved between
// touchstart and end.
var distance = touchStartPos - $(window).scrollTop();
var $clickableItem; // the item I want to be clickable if it's NOT a swipe
// adding this class for devices that
// will trigger a click event after
// the touchend event finishes. This
// tells the click event that we've
// already done things so don't repeat
$clickableItem.addClass("touched");
if (distance > 20 || distance < -20){
// the distance was more than 20px
// so we're assuming they intended
// to swipe to scroll the list and
// not selecting a row.
} else {
// we'll assume it was a tap
whateverFunctionYouWantToTriggerOnTapOrClick()
}
});
$($clickableItem).live('click',function(e){
// for any non-touch device, we need
// to still apply a click event
// but we'll first check to see
// if there was a previous touch
// event by checking for the class
// that was left by the touch event.
if ($(this).hasClass("touched")){
// this item's event was already triggered via touch
// so we won't call the function and reset this for
// the next touch by removing the class
$(this).removeClass("touched");
} else {
// there wasn't a touch event. We're
// instead using a mouse or keyboard
whateverFunctionYouWantToTriggerOnTapOrClick()
}
});
Run Code Online (Sandbox Code Playgroud)
引自DA:
这是一个有效的例子:
var touch_pos;
$(document).on('touchstart', '.action-feature', function(e) {
e.preventDefault();
touch_pos = $(window).scrollTop();
}).on('click touchend', '.action-feature', function(e) {
e.preventDefault();
if(e.type=='touchend' && (Math.abs(touch_pos-$(window).scrollTop())>3)) return;
alert("only accessed when it's a click or not a swipe");
});
Run Code Online (Sandbox Code Playgroud)