【问题标题】:Prevent vertical scroll on swipe -vanilla JS防止滑动时垂直滚动-vanilla JS
【发布时间】:2018-02-22 10:41:52
【问题描述】:

我编写了这段代码来为图像滑块添加滑动功能。滑块工作正常。

但是,当我向右或向左滑动时,会出现一些垂直滚动,这会让人分心和烦人。

我将 touchstart 的引用存储在触摸对象中。

在 touchend 事件中,如果垂直距离 (lenY) 大于 50,我会在 touchstart 上触发 preventDefault。

这不起作用。

最简单的选择是直接在 touchStart 上调用 preventDefault。但是图像滑块占据了移动屏幕的很大一部分,使得向下滚动页面变得很棘手。

我需要将 lenY(垂直距离)传递给触摸启动处理程序以防止默认操作。

function triggerTouch() {
    "use strict";
    var tZone = document.getElementById('sl-m'),
        touch = {},
        startX = 0,
        startY = 0,
        endX = 0,
        endY = 0;

    if (tZone) {
        tZone.addEventListener('touchstart', function (e) {
            startX = e.changedTouches[0].screenX;
            startY = e.changedTouches[0].screenY;

            // store reference to touch event
            touch.start = e;
        }, false);

        tZone.addEventListener('touchend', function (e) {
           endX = e.changedTouches[0].screenX;
           endY = e.changedTouches[0].screenY;

           var lenX = Math.abs(endX - startX);
           var lenY = Math.abs(endY - startY);

           // check if user intended to scroll down
           if (lenY < 50 && lenX > 50) {
                touch.start.preventDefault();
                e.preventDefault();
                swipe(tZone, startX, endX);
           }
        }, false);
    }
}

【问题讨论】:

  • 您没有在touchstart 处为endYstartY 赋值,因此它们都保持0
  • 哦,我实际上忘了在这里添加它。在它失败后我回滚了。但它不会阻止滚动。
  • 事件 touchstart 和 touchend 不足以实现您想要的。如果用户向左/向右或向上/向下拖动,您必须使用 touchmove 来识别触摸时刻。然后只允许一个方向。

标签: javascript


【解决方案1】:

由于我没有得到答案,我发布了我自己的答案,希望有人能提供正确的实现。

我最终使用 css 溢出属性来暂时禁用垂直滚动。

虽然有一个小的副作用,但这很有效。滑动图像滑块后,滚动将被禁用。

需要向上滑动才能恢复滚动到页面。它并不明显,但我仍然想找到正确的方法。

var touch = {};

window.onload = function () {
    "use strict";
    document.body.addEventListener("touchstart", touchHandler);
    document.body.addEventListener("touchend", touchHandler);
};

function touchHandler(e) {
    "use strict";

    var el = e.target;

    if (el.parentNode.id === "sl-m") {
        if (e.type === "touchstart") {
            touch.startX = e.changedTouches[0].screenX;
            touch.startY = e.changedTouches[0].screenY;
        } else {
            touch.endX = e.changedTouches[0].screenX;
            touch.endY = e.changedTouches[0].screenY;

            touch.lenX = Math.abs(touch.endX - touch.startX);
            touch.lenY = Math.abs(touch.endY - touch.startY);

            if (touch.lenY < 20) {
                // disable scroll
                document.body.style.overflowY = "hidden";

                // do swipe related stuff
                swipe(el.parentNode);
            } else {
                // enable scroll if swipe was not intended
                document.body.style.overflowY = "scroll";
            }
        }
    } else {
        // keep scroll enabled if touch is outside the image slider 
        document.body.style.overflowY = "scroll";
    }
}

【讨论】:

    【解决方案2】:

    我想分享适合我的解决方案。上述解决方案不适用于 ios。我为我的英语感到抱歉。我不懂英文。

    function stop(e){
    e=e || event;
    e.preventDefault;
    }
    window.onscroll=stop(); //-->Yes, we will use it ..
    

    例如,您将在哪里使用;

    function move(event){
    
    var finish=event.touches[0].clientX;
    var verticalFinish=event.touches[0].clientY;
    var diff=finish-strt;
    var verticalDiff=verticalStrt-verticalFinish;
    var f;
    
    if(diff<0 && (Math.abs(diff)>Math.abs(verticalDiff)/3)){
        f=verticalDiff+widthOffset;
    slayt[x].style.left=diff+"px";
    slayt[x].style.transition="none";
    slayt[y].style.left=f+"px";
    slayt[y].style.transition="none";
    
      window.onscroll=stop(); //-->we used it here :)
    
      } 
    
    else if(diff>0 && (Math.abs(diff)>Math.abs(verticalDiff)/3)){
        f=diff-widthOffset;
    slayt[x].style.left=diff+"px";
    slayt[x].style.transition="none";
    slayt[z].style.left=f+"px";
    slayt[z].style.transition="none";
    
      window.onscroll=stop();//-->we used it here :)
    
        }
     }
    

    但是有一个小问题。如果有其他与滚动相关的功能,则取消。返回真;这没用。如果我有一个与touchend内外的滑块相关的功能,我也会写两次。

    function end(event){
    //"touchend" related codes...
    //bla bla
    window.onscroll=function(){m=window.pageYOffset;console.log(m);if(m>=850) 
    {buton.style.display="block";}else{buton.style.display="none";}}
    }
    

    如果有用的话,我会很高兴...

    更新: 我打错了。我想修复。实际上,很遗憾不能取消滚动事件。所以上面我们取消的事件,scroll不是垂直滚动事件。所有事件。

    window.onscroll=stop(); // ==>improper use
    stop(); // ==> actually - Correct usage
    

    只需要写成这样 stop()。

    【讨论】:

    • 您好 macitsamet,感谢您的代码,我会检查一下。我实际上最终使用了 SwipeJs - github.com/thebird/Swipe。您可能会发现阅读代码很有用。我不得不修改和删除一些多余的功能以满足我的需要,但它就像一个魅力。
    【解决方案3】:
    html,
    body {
         overflow: hidden;
    }
    

    你试过了吗?

    【讨论】:

    • 这不接近 OP 的问题。你能解释一下吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多