问题 使用preventDefault覆盖tap事件


我有很多:

$('#element').on('tap', function(){
    // some code ..
})

我搜索了很多关于这个的问题 tap 事件发生两次问题,我解决了我的问题 e.preventDefault(),现在我有很多:

$('#element').on('tap', function(e){
    e.preventDefault();
    // some code ..
})

好的,但正如我所说,我有很多这样的电话,我不喜欢每次都写很多 e.preventDefault(),然后我打字 $.fn.tap 在chrome的控制台上,它告诉我:

function (a){return a?this.bind(c,a):this.trigger(c)}

我试图用这种方式覆盖它:

$.fn.tap = function (a) {
    a.preventDefault(); 
    return a?this.bind(c,a):this.trigger(c)
}

但它没有像以前那样有效 e.preventDefault()

我没有看到任何明显的东西,我对此缺乏想法。

任何帮助或想法表示赞赏。提前致谢。


9898
2018-02-01 13:37


起源

$.fn.tap 创建一个名为as的函数 $('#element').tap(),它不会创建一个事件 - adeneo
function(e){e.preventDefault(); e.stopPropagation(); } - Vasim Shaikh
尝试返回false。如果你在jqyer中启动功能 - Vasim Shaikh
@adeneo。看到@ BG101回答我想我得到了这个想法,但是......然后,如何覆盖了 .on('tap', func..?或者只能覆盖 .tap(func.. ?
@WashingtonGuedes - 不,你可以直接改变jQuery的事件处理,我会发布一些东西 - adeneo


答案:


jQuery的一个很酷的功能(我通常不会在一个句子中使用'jQuery'和'cool')是它允许你指定事件的自定义行为,使用 $.event.special 目的。

很少的文档 关于这个问题,所以一个小例子就是有序的。 一个工作小提琴使用 click 事件(因为这对我在笔记本电脑上写字更方便可以在这里找到

翻译成您的要求 所有  tap 事件有 e.preventDefault() 在实际处理程序之前调用,看起来像:

$.event.special.tap.add = function(options) {
  var handler = options.handler;

  options.handler = function(e) {
    e.preventDefault();

    return handler.apply(this, arguments);
  }
}

这个代码做了什么(应该做,因为我还没有真正测试过 tap 上面的版本)告诉jQuery你想要一个特殊的治疗方法 tab 事件,更具体地说,你想提供一个“包装处理程序”,除了调用之外什么都不做 e.preventDefault() 在调用提供的事件处理程序之前

更新:阻止默认值 tap设置被覆盖,为未来的访客


注意: 在您尝试更改事物的默认行为之前,您应该问自己为什么默认值不适合您。主要是因为更改默认(=预期)行为会在维护代码和添加功能的同时扰乱您未来的自我(或更糟糕的是,另一个人)。

为了在代码中创建可维护(且可预测)的流,建议的解决方案是创建一个特殊的案例函数($.fn.tap)实际上是一个非常可行的解决方案,因为它不会干扰事物的默认(=预期)行为。

从我提供的链接中,您还应该能够创建自己的事件类型(例如 tapOnly并且更明显地涉及一些定制工作。然后,这两个解决方案都将要求您更改事件绑定,这是您要阻止的。


3
2018-02-17 01:00



伙计,这真棒!!!我刚把你的代码更改为 $.event.special.tap.add = function(){... 因为 Object {tapholdThreshold: 750, emitTapOnTaphold: true} 被取代了 tap 事件失败了,但现在它工作得很好!
谢谢你介绍我 special。当之无愧的恩惠。 +1 - BenG
谢谢!我已经更新了代码示例,以反映您的建议@WashingtonGuedes,这确实可以防止其他值被覆盖。 - Rogier Spieker


这就是你如何创建你的 $.fn.tap: -

$.fn.tap = function(f) {
  $(this).on('tap', function(e) {
    e.preventDefault();
    f();
  });
  return this;
};

//usage
$('.selector').tap(function() {
  alert('foo bar')
})

@Washington Guedes  - 覆盖默认的tap事件以始终使用e.preventDefault()   而不是从$(元素).on('tap',function(){})更改为   $(元件).tap(函数(){})

您可以添加委托事件 body 对于 tap,没有指定目标。这将为所有人开火 tap 身体上的事件,然后您可以检查目标是否有自己的事件 tap 事件,所以你可以 e.preventDefault();

注意:这不适用于委派 tap 事件如图所示。

// global tap handler
$('body').on('tap', function(e) {
  if ($._data(e.target, "events").tap)
    e.preventDefault();
});

// tap event
$('a.tap').on('tap', function(e) {
  $(this).css('color', 'red');
});

// delegated tap event
$('body').on('tap', 'a.delegate', function(e) {
  $(this).css('color', 'green');
});
a {
  display: block;
  margin: 20px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.js"></script>

<a class="tap" href="www.google.co.uk">tap event, prevented.</a>
<a class="delegate" href="www.google.co.uk">delegate tap event, not prevented.</a>
<a href="www.google.co.uk">no tap event, not prevented</a>


10
2018-02-01 13:52





我知道这可能是一个坏主意,但我刚刚在Chrome中对此进行了测试

$('*').on('tap',function(e){
    e.preventDefault();
});

$('#element').on('tap', function(){
    // some code ..
});

如果你不需要这个所有元素:

$('*').not('#aCertainElement').on('tap',function(e){
    e.preventDefault();
});

1
2018-02-15 17:13





我有一个类似的问题,其中 e.preventDefault() 在某些情况下会有效,但在其他情况下则不会。它显示没有错误,并使用 try-catch 没有显示 catch alert。添加 e.stopImmediatePropagation() 做了伎俩,万一它可以帮助任何人


0
2018-02-01 13:51