2016-01-20 92 views
14

我在带有大链接的页面上使用FastClick,因为我想绕过移动浏览器中水龙头的300毫秒延迟。对于链接':active状态,我有一个“高亮”风格,并且由于FastClick的原因,它正在快速正常启动。有没有办法可以防止fastclick在滚动中触发“活动”状态?

我的问题是 - 在移动Safari至少 - 它也会触发,而你点击和滑动滚动页面。这让你觉得你不能在没有它的情况下滚动页面,因为它认为你想要点击链接。

有人可以在有人滚动时阻止它开火吗?

回答

2

也许你可以将needsclick类添加到身体?

<body class="needsclick"> 

... 

</body> 

只是一个想法:)

+0

谢谢...这实际上会阻止FastClick从控件工作的。 –

2

有趣的问题! +1

此问题与FastClick无关,但FastClick确实为您的问题提供了更复杂的解决方案。所以我会坚持使用纯JavaScript和Raw Touch Events)

在移动触摸设备上,由于平台特有的原因,webview的实现与桌面Web浏览器显着不同。 在这种情况下,一个重要的功能是在web视图中动态滚动。 Momentum Scrolling是设备的硬件加速功能。因此,当屏幕上有可滚动区域时,硬件会识别触摸并将200毫秒倒数计时器附加到可滚动区域,当触发时,该区域将进入硬件加速滚动。当硬件处于该状态时,它不会广播触摸事件,因为它们特定于硬件加速滚动。可以取消定时器,并通过在提供的200毫秒内对触摸事件使用preventDefault来防止动量滚动。

下面是我如何解决这个问题。我假设你使用本地滚动,即overflow:scroll。 该方法将一个touchstart事件附加到您想要触摸的元素。 一旦touchstart事件触发,事件处理程序将touchend,touchmovetouchcancel事件附加到目标元素。启动setTimout计时器,可在140ms后删除新添加的事件。

这里是我的生产代码中的一些片断: 我从集合添加和删除事件的两个事件方法:

var eventify = (function() { 
    function eventify(type, el, callback, phase) { 
     phase = phase || false; 
     if ((el.constructor.toString().contains('NodeList')) || (el.constructor.toString().contains('HTMLCollection'))) { 
      [].forEach.call(el, function (element) { 
       if (!element.hasEvent(type)) { 
        element.addEvent(type); 
        HTMLElement.prototype.addEventListener.apply(element, [type, callback, phase]); 
       } 
      }); 
     } else { 
      if (!el.hasEvent(type)) { 
       el.addEvent(type); 
       HTMLElement.prototype.addEventListener.apply(el, [type, callback, phase]); 
      } 
     } 
     return callback; 
    } 

    return eventify 
})(); 

var uneventify = (function() { 
    function uneventify(type, el, callback) { 
     if ((el.constructor.toString().contains('NodeList')) || (el.constructor.toString().contains('HTMLCollection'))) { 
      [].forEach.call(el, function (element) { 
       if (element.hasEvent(type)) { 
        element.removeEvent(type); 
        HTMLElement.prototype.removeEventListener.apply(element, [type, callback]); 
       } 
      }); 
     } else { 
      if (el.hasEvent(type)) { 
       el.removeEvent(type); 
       HTMLElement.prototype.removeEventListener.apply(el, [type, callback]); 
      } 
     } 
    } 

    return uneventify 
})(); 

然后我有在滚动自来水事件tapify方法:

var tapify = (function() { 
    function tapify(el, callback) { 
     eventify('touchstart', el, function (e) { 
      var that = this; 
      var start = e.pageY; 
      var target = e.target; 
      function dynamicEvents() { 
       var endfn = eventify('touchend', target, function (evt) { 
        e.preventDefault(); 
        e.stopImmediatePropagation(); 
        evt.preventDefault(); 
        evt.stopImmediatePropagation(); 
        uneventify('touchmove', target, movefn); 
        uneventify('touchend', target, endfn); 
        uneventify('touchcancel', target, cancelfn); 
        callback && callback(target); 
       }); 
       var cancelfn = eventify('touchcancel', target, function (evt) { 
        e.preventDefault(); 
        e.stopImmediatePropagation(); 
        evt.preventDefault(); 
        evt.stopImmediatePropagation(); 
        uneventify('touchmove', target, movefn); 
        uneventify('touchend', target, endfn); 
        uneventify('touchcancel', target, cancelfn); 
        callback && callback(target); 
       }); 
       var movefn = eventify('touchmove', target, function (evt) { 
        var distance = start - evt.pageY; 
        if (distance > 20) { 
         uneventify('touchend', target, endfn); 
         uneventify('touchcancel', target, cancelfn); 
         uneventify('touchmove', el, movefn); 
        } 
       }); 
       setTimeout(function() { 
        uneventify('touchmove', target, movefn); 
        uneventify('touchend', target, endfn); 
        uneventify('touchcancel', target, cancelfn); 
       }, 140); 
      } 
      if (global.isIos) setTimeout(function() { 
       dynamicEvents(); 
      }, 60); 
      else dynamicEvents(); 
     }, false); 
    } 
    return tapify; 
})(); 

我使用global.isIos来标识目标设备。 Android停止将触发事件发送到webview ater 200ms。

然后向事件附加到一个元素或元素的集合,使用方法:

tapify(document.querySelectorAll('button'), function (e) { 
     //your event handler here!! 
}); 

希望这有助于

+0

可以使用相同的方法在原生滚动表面上进行滑动和拖动事件。 –

+0

感谢您的回复! 现在我希望能够尝试与FastClick兼容的东西......并且作为一名JS新手,我承认自己的答案已经超出了我的观点,但是我没有看到它与FastClick的联系。 但是,如果我变得勇敢,我会尝试将一些代码添加到我的项目中。 –

+0

我建议你只在需要它的元素上附加FastClick,而不是在document.body –

相关问题