Suspend Default Event in jQuery

2020-08-20 08:41发布

I am trying to delay the default event or events in a jQuery script. The context is that I want to display a message to users when they perform certain actions (click primarily) for a few seconds before the default action fires.

Pseudo-code: - User clicks link/button/element - User gets a popup message stating 'You are leaving site' - Message remains on screen for X milliseconds - Default action (can be other than href link too) fires

So far, my attempts look like this:

$(document).ready(function() {
    var orgE = $("a").click();
    $("a").click(function(event) {
        var orgEvent = event;
        event.preventDefault();
        // Do stuff
        doStuff(this);

        setTimeout(function() {
            // Hide message
            hideMessage();
            $(this).trigger(orgEvent);
        }, 1000);
    });
});

Of course, this doesn't work as expected, but may show what I'm trying to do.

I am unable to use plugins as ths is a hosted environment with no online access.

Any ideas?

4条回答
Juvenile、少年°
2楼-- · 2020-08-20 08:53

Something like this should do the trick. Add a new class (presumably with a more sensible name than the one I've chosen) to all the links you want to be affected. Remove that class when you've shown your popup, so when you call .click() again your code will no longer run, and the default behavior will occur.

$("a").addClass("fancy-schmancy-popup-thing-not-yet-shown").click(function() {
    if ($(this).hasClass("fancy-schmancy-popup-thing-not-yet-shown"))
        return true;

    doStuff();
    $(this).removeClass("fancy-schmancy-popup-thing-not-yet-shown");

    var link = this;
    setTimeout(function() {
      hideMessage();
      $(link).click().addClass("fancy-schmancy-popup-thing-not-yet-shown";
    }, 1000);

    return false;
});
查看更多
虎瘦雄心在
3楼-- · 2020-08-20 08:54

This might work:

$(document).ready(function() {
  $("a").click(function(event) {
    event.preventDefault();
    doStuff(this);

    setTimeout(function() {
      hideMessage();
      $(this).click();
    }, 1000);
  });
});

Note: totally untested

查看更多
Summer. ? 凉城
4楼-- · 2020-08-20 09:00

I would probably do something like this.

$("a").click(function(event) {
   event.preventDefault();
   doStuff(this);
   var url = $(this).attr("href");

   setTimeout(function() {
      hideMessage();
      window.location = url;
   }, 1000);
});

I'm not sure if url can be seen from inside the timed function. If not, you may need to declare it outside the click handler.

Edit: If you need to trigger the event from the timed function, you could use something similar to what karim79 suggested, although I'd make a few changes.

$(document).ready(function() {
  var slept = false;
  $("a").click(function(event) {
    if(!slept) {
        event.preventDefault();
        doStuff(this);

        var $element = $(this);
        // allows us to access this object from inside the function

        setTimeout(function() {
          hideMessage();
          slept = true;
          $element.click(); //triggers the click event with slept = true
        }, 1000);
        // if we triggered the click event here, it would loop through
        // this function recursively until slept was false. we don't want that.
    } else {
        slept = false; //re-initialize
    }
  });
});

Edit: After some testing and research, I'm not sure that it's actually possible to trigger the original click event of an <a> element. It appears to be possible for any element other than <a>.

查看更多
Fickle 薄情
5楼-- · 2020-08-20 09:14

Probably the best way to do this is to use unbind. Something like:

$(document).ready(function() {
    $("a").click(function(event) {
        event.preventDefault();
        // Do stuff
        this.unbind(event).click();
    });
})
查看更多
登录 后发表回答