最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Overwriting tap event with preventDefault - Stack Overflow

programmeradmin2浏览0评论

I had a lot of:

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

I searched many questions about the tap event problem firing twice, and I solved my problem using e.preventDefault(), now I have a lot of:

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

Ok, but as I said, I have many of these calls and I don't like much to write every time e.preventDefault(), then I typed $.fn.tap on chrome's console and it showed me:

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

I tried to overwrite it this way:

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

But it didn't worked as it did in the previous e.preventDefault().

I'm not seeing anything obvious and I'm out of ideas for this.

Any help or idea is appreciated. Thanks in advance.

I had a lot of:

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

I searched many questions about the tap event problem firing twice, and I solved my problem using e.preventDefault(), now I have a lot of:

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

Ok, but as I said, I have many of these calls and I don't like much to write every time e.preventDefault(), then I typed $.fn.tap on chrome's console and it showed me:

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

I tried to overwrite it this way:

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

But it didn't worked as it did in the previous e.preventDefault().

I'm not seeing anything obvious and I'm out of ideas for this.

Any help or idea is appreciated. Thanks in advance.

Share Improve this question asked Feb 1, 2016 at 13:37 user4227915user4227915 5
  • 1 $.fn.tap creates a function called as $('#element').tap(), it does not create an event – adeneo Commented Feb 1, 2016 at 13:41
  • 1 function(e) { e.preventDefault(); e.stopPropagation(); } – Vasim Shaikh Commented Feb 1, 2016 at 13:46
  • try returning false. if you fire on function in jqyer – Vasim Shaikh Commented Feb 1, 2016 at 13:48
  • @adeneo. Seeing @BG101 answer I think I got the idea, but.. then, how to overwrite the .on('tap', func..? Or is it only possible to overwrite the .tap(func.. ? – user4227915 Commented Feb 1, 2016 at 14:01
  • 1 @WashingtonGuedes - nope, you can change jQuery's event proccessing directly, I'll post something – adeneo Commented Feb 1, 2016 at 14:42
Add a ment  | 

4 Answers 4

Reset to default 10

This is how you can create your $.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 - overwrite the default tap-event to always use e.preventDefault() rather than changing from $(element).on('tap', function(){}) to $(element).tap(function(){})

You could add a delegate event to body for tap, without specifying a target. This will then fire for all tap events on the body, which you can then check if the target has its own tap event, so you can then e.preventDefault();.

NOTE: This will not work for delegated tap events as shown.

// 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./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery./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>

One of the cool features of jQuery (I usually don't use 'jQuery' and 'cool' in a single sentence) is that it lets you specify custom behaviour for events, using the $.event.special object.

There is very little documentation on the subject, so a little example would be in order. A working fiddle using the click event (as this was more convenient for me to write on my laptop) can be found here

Translated to your request to have all tap events have e.preventDefault() invoked before the actual handler, would look like:

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

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

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

What this code does (should do, as I haven't actually tested the tap version above) is telling jQuery that you want a special treatment for the tab event, more particularly you want to provide a 'wrapping handler' which does nothing more than call e.preventDefault() before calling the provided event handler.

UPDATE: prevented the default tap-settings from being overwritten, for future visitors


NOTE: Before you make any attempt on changing the default behaviour of things, you should ask yourself why the defaults don't work for you. Mostly because changing default (=expected) behaviour will upset your future self (or worse, another person) while maintaining your code and adding features.

In order to create a maintainable (and predictable) flow in your code the suggested solution to create a special case function ($.fn.tap) is in fact a very viable solution, as it does not interfere with the default (=expected) behaviour of things.

From the links I provided you should also be able to create your own event type (e.g. tapOnly) and make it more obvious there is some custom work involved. Then again, both of these solutions will require you to change your event bindings, which is what you are trying to prevent.

I knew can be a bad idea but I've just tested this in Chrome

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

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

and if you don't need this for all elements:

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

I had a similar problem, in which e.preventDefault() would work on some cases, but not on others. It showed no errors, and using try-catch was not displaying the catch alert. Adding e.stopImmediatePropagation() did the trick, in case it helps anyone

发布评论

评论列表(0)

  1. 暂无评论