Javascript JQuery可拖动,带触摸冲压停止垂直滚动
我使用jquerydraggable函数和touchpunch生成一个水平滑块列表,通过单击和拖动可以滚动。它在触摸和点击设备中工作得非常好。我面临的问题是,如果我尝试在触摸设备中向上或向下滚动,它将无法工作 我查看了一下,发现从TouchPunch中删除event.preventDefault允许垂直滚动,这个修复程序的问题是,它只在某些设备上有效,而不是在所有设备上有效 我想知道是否有人有任何其他的解决方案,或替代方法,生产相同的水平滑块,工作在触摸和点击事件 下面是JQuery可拖动的示例代码: $function{ var slides=$'list1 ul'.children.length; var slideWidth=$'list1'。宽度; var min=0; var max=-slides-1*slideWidth; $list1 ul.width幻灯片*可拖动的幻灯片宽度{ 轴:“x”, 拖动:functionevent,ui{ 如果ui.position.left>min ui.position.left=min; 如果ui.position.leftJavascript JQuery可拖动,带触摸冲压停止垂直滚动,javascript,jquery,html,css,Javascript,Jquery,Html,Css,我使用jquerydraggable函数和touchpunch生成一个水平滑块列表,通过单击和拖动可以滚动。它在触摸和点击设备中工作得非常好。我面临的问题是,如果我尝试在触摸设备中向上或向下滚动,它将无法工作 我查看了一下,发现从TouchPunch中删除event.preventDefault允许垂直滚动,这个修复程序的问题是,它只在某些设备上有效,而不是在所有设备上有效 我想知道是否有人有任何其他的解决方案,或替代方法,生产相同的水平滑块,工作在触摸和点击事件 下面是JQuery可拖动的示例
$(function() {
var slides = $('#list1 ul').children().length;
var slideWidth = $('#list1').width();
var min = 0;
var max = -((slides - 1) * slideWidth);
$(".draggable").width(slides * slideWidth).draggable({
axis: 'x',
drag: function(event, ui) {
if (ui.position.left > min) ui.position.left = min;
if (ui.position.left < max) ui.position.left = max;
}
});
var startTouchX=0;
var startTouchY=0;
var actualPosX;
var actualPosY;
var eventCounter=0;
var directionDetermined=false;
var direction;
var thisTouchX;
var thisTouchY;
var lastTouchY;
$(document).on("touchstart", function(e) {
// Actual document position
actualPosX = $(document).scrollLeft();
actualPosY = $(document).scrollTop();
// StartTouches
startTouchX = parseInt(e.originalEvent.touches[0].pageX);
startTouchY = parseInt(e.originalEvent.touches[0].pageY);
});
$(document).on("touchmove", function(e) {
// Arbitrary considering ONLY the fourth event...
// Touchmove fires way too many times!
// We only need to determine the main direction ONCE.
// This prevents an "s" swipe from messing this code.
eventCounter++;
if(eventCounter==4 && !directionDetermined){
thisTouchX = parseInt(e.originalEvent.touches[0].pageX);
thisTouchY = parseInt(e.originalEvent.touches[0].pageY);
if ( (Math.abs(thisTouchX - startTouchX)) / Math.abs(thisTouchY - startTouchY) > 1){ //check swipe direction
// HORIZONTAL
$("#debug").html("HORIZONTAL");
directionDetermined=true;
// NO NEED here. This is re-enabled on touchend, if it has been disabled.
//$(".draggable").draggable('enable');
}
else{
// VERTICAL
$("#debug").html("VERTICAL");
directionDetermined=true;
direction="vertical";
$(".draggable").draggable('disable'); // Disable draggable.
}
}
// Getting all the Y touches...
// The "last" value will be used on touchend.
lastTouchY = parseInt(e.originalEvent.touches[0].pageY);
//$("#debug").html(lastTouchY);
});
$(document).on("touchend", function(e) {
if(direction=="vertical"){
//$("#debug").html(lastTouchY);
var thisMoveY = -parseInt(lastTouchY - startTouchY);
//$("#debug").html(thisMoveY);
var newPosY = (actualPosY + thisMoveY);
//$("#debug").html(actualPosX+ " " +newPosY);
//window.scrollTo(actualPosX, newPosY);
$("html,body").animate({ scrollTop: newPosY },400);
}
// Reset everything for a future swipe.
startTouchX=0;
startTouchY=0;
eventCounter=0;
directionDetermined=false;
direction="";
$("#debug").html("");
// Re-enable draggable.
$(".draggable").draggable('enable');
});
});
请注意,它使用来检测双击
还有一些额外的CSS
编辑
基于基于touchemove的pageY属性确定擦除方向的思想
我认为从长远来看,避免恼人的双击是一个好主意,请参阅下面的第一个答案。
在这个问题上仍然有一个折衷方案,但它要合理得多
我尝试了很多东西。。。我得到的最好结果是当我放弃在touchmove上模拟滚动时
下面是我现在使用三个触摸事件的方法:
touchstart获取初始变量,如:window scrollTop和pageY
touchmove确定滑动方向并获取最后一页
touchend计算页面应该滚动到的位置。
为了美观,我将结果值放入了.animate中。
我惊喜地发现,它非常平滑地补偿了页面仅在touchend上滚动的事实。
我认为很少有用户会注意到它
由于触摸打孔默认用于水平滑动,因此折衷方案仅影响垂直滚动
代码如下:
和一个可以在触控设备上试用的程序
$(function() {
var slides = $('#list1 ul').children().length;
var slideWidth = $('#list1').width();
var min = 0;
var max = -((slides - 1) * slideWidth);
$(".draggable").width(slides * slideWidth).draggable({
axis: 'x',
drag: function(event, ui) {
if (ui.position.left > min) ui.position.left = min;
if (ui.position.left < max) ui.position.left = max;
}
});
var startTouchX=0;
var startTouchY=0;
var actualPosX;
var actualPosY;
var eventCounter=0;
var directionDetermined=false;
var direction;
var thisTouchX;
var thisTouchY;
var lastTouchY;
$(document).on("touchstart", function(e) {
// Actual document position
actualPosX = $(document).scrollLeft();
actualPosY = $(document).scrollTop();
// StartTouches
startTouchX = parseInt(e.originalEvent.touches[0].pageX);
startTouchY = parseInt(e.originalEvent.touches[0].pageY);
});
$(document).on("touchmove", function(e) {
// Arbitrary considering ONLY the fourth event...
// Touchmove fires way too many times!
// We only need to determine the main direction ONCE.
// This prevents an "s" swipe from messing this code.
eventCounter++;
if(eventCounter==4 && !directionDetermined){
thisTouchX = parseInt(e.originalEvent.touches[0].pageX);
thisTouchY = parseInt(e.originalEvent.touches[0].pageY);
if ( (Math.abs(thisTouchX - startTouchX)) / Math.abs(thisTouchY - startTouchY) > 1){ //check swipe direction
// HORIZONTAL
$("#debug").html("HORIZONTAL");
directionDetermined=true;
// NO NEED here. This is re-enabled on touchend, if it has been disabled.
//$(".draggable").draggable('enable');
}
else{
// VERTICAL
$("#debug").html("VERTICAL");
directionDetermined=true;
direction="vertical";
$(".draggable").draggable('disable'); // Disable draggable.
}
}
// Getting all the Y touches...
// The "last" value will be used on touchend.
lastTouchY = parseInt(e.originalEvent.touches[0].pageY);
//$("#debug").html(lastTouchY);
});
$(document).on("touchend", function(e) {
if(direction=="vertical"){
//$("#debug").html(lastTouchY);
var thisMoveY = -parseInt(lastTouchY - startTouchY);
//$("#debug").html(thisMoveY);
var newPosY = (actualPosY + thisMoveY);
//$("#debug").html(actualPosX+ " " +newPosY);
//window.scrollTo(actualPosX, newPosY);
$("html,body").animate({ scrollTop: newPosY },400);
}
// Reset everything for a future swipe.
startTouchX=0;
startTouchY=0;
eventCounter=0;
directionDetermined=false;
direction="";
$("#debug").html("");
// Re-enable draggable.
$(".draggable").draggable('enable');
});
});
请注意,它使用来检测双击
还有一些额外的CSS
这是我最接近它的一次,我想知道是否有人可以改进这段代码:
$(watchlist).on("touchstart", function(e) {
touchY = e.originalEvent.touches[0].pageY;
touchX = e.originalEvent.touches[0].pageX;
});
$(watchlist).on("touchmove", function(e) {
var fTouchY = e.originalEvent.touches[0].pageY;
var fTouchX = e.originalEvent.touches[0].pageX;
if ((Math.abs(fTouchX - touchX)) / Math.abs(fTouchY - touchY) > 1){ //check swipe direction
$("#watchlist ul").draggable( 'enable'); //if swipe is horizontal
}
else{
$("#watchlist ul").draggable( 'disable'); //if swipe is horizontal
}
});
此代码的问题在于,它仅在触摸移动完成后而不是在移动过程中停用可拖动功能。如果有人可以修改此代码,以便在满足条件时,即在touchmove期间,而不是之后,禁用可拖动功能,我将向他们提供奖励。这是我最接近的一次,我想知道是否如此 meone可以改进这一代码:
$(watchlist).on("touchstart", function(e) {
touchY = e.originalEvent.touches[0].pageY;
touchX = e.originalEvent.touches[0].pageX;
});
$(watchlist).on("touchmove", function(e) {
var fTouchY = e.originalEvent.touches[0].pageY;
var fTouchX = e.originalEvent.touches[0].pageX;
if ((Math.abs(fTouchX - touchX)) / Math.abs(fTouchY - touchY) > 1){ //check swipe direction
$("#watchlist ul").draggable( 'enable'); //if swipe is horizontal
}
else{
$("#watchlist ul").draggable( 'disable'); //if swipe is horizontal
}
});
此代码的问题在于,它仅在触摸移动完成后而不是在移动过程中停用可拖动功能。如果有人可以修改此代码,以便在条件满足时,在touchmove期间,而不是之后,禁用可拖动功能,我会给他们奖金。试试这个@kyunghwanjung,这就是我目前使用的可拖动功能,问题是,我不能上下滚动。试试这个@kyunghwanjung,这就是我目前正在使用的,可拖动的功能,问题是,我不能上下滚动。我认为这是个好主意,我在其他设备上测试过,效果很好。它会稍微影响用户体验,如果没有其他答案,我一定会考虑这个问题。谢谢露伊斯!请你核对一下我的答案,看看你能不能完成?谢谢我已经做了一些基于你的超级伟大的方向决定的想法。我很快就会编辑。做得很好,这是最接近的解决方案,所以:在我看来,这是一个伟大的想法,我在其他设备上进行了测试,效果很好。它会稍微影响用户体验,如果没有其他答案,我一定会考虑这个问题。谢谢露伊斯!请你核对一下我的答案,看看你能不能完成?谢谢我已经做了一些基于你的超级伟大的方向决定的想法。我将很快进行编辑。做得很好,它与中的解决方案最接近,因此: