Javascript JQuery可拖动,带触摸冲压停止垂直滚动

Javascript JQuery可拖动,带触摸冲压停止垂直滚动,javascript,jquery,html,css,Javascript,Jquery,Html,Css,我使用jquerydraggable函数和touchpunch生成一个水平滑块列表,通过单击和拖动可以滚动。它在触摸和点击设备中工作得非常好。我面临的问题是,如果我尝试在触摸设备中向上或向下滚动,它将无法工作 我查看了一下,发现从TouchPunch中删除event.preventDefault允许垂直滚动,这个修复程序的问题是,它只在某些设备上有效,而不是在所有设备上有效 我想知道是否有人有任何其他的解决方案,或替代方法,生产相同的水平滑块,工作在触摸和点击事件 下面是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.leftmin ui.position.left=min; 如果ui.position.left 浮箱 浮箱 浮箱 两个

浮箱 浮箱 浮箱 编辑 基于基于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

编辑 基于基于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,这就是我目前正在使用的,可拖动的功能,问题是,我不能上下滚动。我认为这是个好主意,我在其他设备上测试过,效果很好。它会稍微影响用户体验,如果没有其他答案,我一定会考虑这个问题。谢谢露伊斯!请你核对一下我的答案,看看你能不能完成?谢谢我已经做了一些基于你的超级伟大的方向决定的想法。我很快就会编辑。做得很好,这是最接近的解决方案,所以:在我看来,这是一个伟大的想法,我在其他设备上进行了测试,效果很好。它会稍微影响用户体验,如果没有其他答案,我一定会考虑这个问题。谢谢露伊斯!请你核对一下我的答案,看看你能不能完成?谢谢我已经做了一些基于你的超级伟大的方向决定的想法。我将很快进行编辑。做得很好,它与中的解决方案最接近,因此: