【问题标题】:Permit horizontal pan events only if the gesture is not already scrolling vertically仅当手势尚未垂直滚动时才允许水平平移事件
【发布时间】:2015-01-27 10:12:48
【问题描述】:

我想设置 Hammer.js,以便我可以响应水平平移事件。我的第一次尝试是这样的:

var mc = new Hammer(document.body);
mc.on("panleft panright", runBind(this, 'updatePosition'));
mc.on("panend", runBind(this, 'finalisePosition'));

这几乎得到了我正在寻找的行为:如果我向左或向右平移,则调用 updatePosition 函数,当我停止平移时调用 finalisePosition 函数。

但是,如果手势在垂直滚动时向左或向右漂移,也会触发这些功能。例如,假设我触摸屏幕顶部附近,然后将手指向下拖动到屏幕的一半:这应该注册为滚动事件。现在假设我继续对角拖动:向下和向左。在这种情况下,我想忽略手势的水平部分,仅将手势视为垂直滚动事件,但 Hammer.js 会像以前一样触发 panrightpanleft 事件。

我的下一次尝试是这样的:

var mc = new Hammer(document.body, {
  recognizers: [
    [Hammer.Swipe],
    [
      Hammer.Pan,
      {event: 'panvertical', direction: Hammer.DIRECTION_VERTICAL}
    ],
    [
      Hammer.Pan,                               // RecognizerClass
      {direction: Hammer.DIRECTION_HORIZONTAL}, // options
      ['swipe'],                                // recognizeWith
      ['panvertical']                           // requireFailure
    ],
  ]
});
mc.on("panleft panright", runBind(this, 'updatePosition'));
mc.on("panend", runBind(this, 'finalisePosition'));

这指定仅当panvertical 事件失败时才应触发水平平移事件。果然,这可以防止我上面描述的问题。如果我开始垂直滚动手势然后开始水平移动,则不会触发 panleftpanright 事件。但是这个版本有一个更严重的问题:默认的滚动行为没有发生!因此无法滚动应用。

谁能提出更好的解决方案?

我使用的是 Hammer.js 版本 2.0.4。

【问题讨论】:

    标签: javascript scroll touch hammer.js


    【解决方案1】:

    我也遇到过同样的问题 我已经设法使它与这个非常丑陋的代码一起工作

       var first = false, lock = false;
       var containerHandler = function(event) {
    
           if(event.type == 'panend' || event.type == 'pancancel') {
             // iOS bug fix
             lock = false;
             first = false;
    
           } else if(event.type == 'swipe' && event.direction & Hammer.DIRECTION_VERTICAL) {
             // iOS bug fix
             lock = true;
             first = true;
           }
           else if(event.type == 'panmove') {
             // iOS bug fix ... 
             if(first === false && event.direction & Hammer.DIRECTION_VERTICAL) {
               lock = true;
             }
    
             first = true;
             if(lock === true)
             return;
    
             //your code etc...
        };
    
        var focusMC = new Hammer.Manager(mainContainer[0], {domEvents:true});
        var pan = new Hammer.Pan({threshold: 5, direction:Hammer.DIRECTION_HORIZONTAL});
        focusMC.add( pan );
        focusMC.on('panstart panmove panend pancancel swipe', containerHandler);
    

    小门槛很重要..

    据我所知,此问题仅在 iOS Safari 上,但在 WP 上即使没有此代码也能正常工作

    编辑: 尝试强制使用touch-action 属性,而不是上面的解决方案 给pan-y

    我保留这两个答案,因为它们都应该有效

    【讨论】:

      【解决方案2】:

      Hammer.js 将根据您的识别器自动推断触摸动作属性。这可能会使应用程序更具响应性,但不会因为用户正在与元素交互而阻止垂直页面滚动。

      我遇到了与您相同的问题,并找到了一个非常简单的解决方案,可以很好地解决问题。

      var isScrolling = false;
      
      var galleryHammer = new Hammer(element, {
          recognizers: [
              [Hammer.Pan, { direction: Hammer.DIRECTION_HORIZONTAL }]
          ]
      });
      
      // Making the event listener passive means we don't get any delays between
      // the user scrolling and the browser having checked if it should prevent
      // that event
      window.addEventListener('scroll', function() {
          isScrolling = true;
      }, { passive: true });
      
      window.addEventListener('touchend', function() {
          isScrolling = false;
      });
      
      galleryHammer.on('pan', function(event) {
          if (isScrolling) {
              return;
          }
      
          // Normal logic...
      });
      

      【讨论】:

        【解决方案3】:

        这对我有用(代码来自一个类,this.hm 只是一个 Hammer 实例):

        this.hm.on('panleft', function(e){ // ...and same for panright
           if(e.pointerType == 'touch' && (Math.abs(e.deltaY) > Math.abs(e.deltaX))){ return false; }
           // do stuff
        }
        

        额外的 pointerType 检查是因为我在台式计算机上没有任何问题(鼠标事件)。所以整体只应用于触摸设备/事件。

        【讨论】:

          猜你喜欢
          • 2012-09-23
          • 2014-05-05
          • 1970-01-01
          • 1970-01-01
          • 2020-01-31
          • 1970-01-01
          • 2017-12-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多