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

javascript - Delaying click event - Stack Overflow

programmeradmin2浏览0评论

I'm wondering whether there's a simple way to delay the click event from being processed for a specified period of time. For example we could have

$('#someElement').on('click', 'a', function(event) {
    var duration = 1000;
    someAsynchronousFunction(); // Start as soon as click occurs
    ... // Code to delay page transition from taking place for duration specified
});

So in this case the asynchronous function would be guaranteed some amount of time to run. If it hasn't completed it's work in this time I wouldn't care and would just like to continue with the page transition. I know that it's possible to accomplish something close with

event.preventDefault();
...
setTimeout(function(){
    window.location = $(this).attr('href');
}, duration);

But this only works when the link being clicked goes to a full page. I want to be able to deal with links that are used for ajax calls (which don't change the url) as well.

I noticed that the mixpanel library has a function track_links which seems to accomplish the delay on the page transition, though that function doesn't seem to work well with the support for ajax links that I mentioned.

Any help would be great! Thanks.

Edit: So I suppose my question wasn't exactly clear, so I'll try to provide some more details below.

I don't care if the async function finishes running! I only want to give it the guarantee that it has some set amount of time to execute, after which I don't care if it finishes, and would prefer to go ahead with the page transition.

i.e. I want to delay not the start of the async function, but the start of the page transition. The async function would start running as soon as the click occured.

Hopefully this is a bit more clear!

I'm wondering whether there's a simple way to delay the click event from being processed for a specified period of time. For example we could have

$('#someElement').on('click', 'a', function(event) {
    var duration = 1000;
    someAsynchronousFunction(); // Start as soon as click occurs
    ... // Code to delay page transition from taking place for duration specified
});

So in this case the asynchronous function would be guaranteed some amount of time to run. If it hasn't completed it's work in this time I wouldn't care and would just like to continue with the page transition. I know that it's possible to accomplish something close with

event.preventDefault();
...
setTimeout(function(){
    window.location = $(this).attr('href');
}, duration);

But this only works when the link being clicked goes to a full page. I want to be able to deal with links that are used for ajax calls (which don't change the url) as well.

I noticed that the mixpanel library has a function track_links which seems to accomplish the delay on the page transition, though that function doesn't seem to work well with the support for ajax links that I mentioned.

Any help would be great! Thanks.

Edit: So I suppose my question wasn't exactly clear, so I'll try to provide some more details below.

I don't care if the async function finishes running! I only want to give it the guarantee that it has some set amount of time to execute, after which I don't care if it finishes, and would prefer to go ahead with the page transition.

i.e. I want to delay not the start of the async function, but the start of the page transition. The async function would start running as soon as the click occured.

Hopefully this is a bit more clear!

Share Improve this question edited Jul 18, 2013 at 14:08 000 27.2k10 gold badges73 silver badges103 bronze badges asked Jul 17, 2013 at 2:41 nitarshannitarshan 1,5012 gold badges12 silver badges11 bronze badges 6
  • i don't get it, do you want to execute the function after a delay ? r what ? – Qchmqs Commented Jul 17, 2013 at 2:47
  • I should be more specific, sorry. I want the asynchronous function to start as soon as the link is clicked, but I want it to be guaranteed a certain amount of time to run (and hopefully finish what it's doing) before the page is changed. – nitarshan Commented Jul 17, 2013 at 2:50
  • It looks like you're falling into the oldest trap in JavaScript: delaying something in the hopes it will execute after an asynchronous event has completed. Don't do that: use a callback or a promise. You don't know how long the someAsynchronousFunction(); call will take. – msanford Commented Jul 17, 2013 at 2:50
  • then you got your question answered, use callbacks, and .done() – Qchmqs Commented Jul 17, 2013 at 2:52
  • I think this might be the same question: stackoverflow.com/questions/12116505/… – Jamie De Palmenaer Commented Jul 17, 2013 at 2:56
 |  Show 1 more comment

4 Answers 4

Reset to default 15

I figured out a way to solve the problem:

var secondClick = false;
var duration = 1000;

$('#someElement').on('click', 'a', function(event) {
    var that = $(this);
    
    if(!secondClick) {
        event.stopPropagation();
        setTimeout(function(){
            secondClick = true;
            that.click();
        }, duration);
        
        someAsynchronousFunction();
    } else {
        secondClick = false;
    }
});

When the user clicks the link, it internally prevents that click from actually having any effect, and gives the asynchronous function a set amount of time to do it's work before doing a second click on the link which behaves normally.

setTimeout allows you to delay running code by however many ms you want

setTimeout(function(){
    console.log('Stuff be done'); //This will be delayed for one second
}, 1000);

In reality, if you're dealing with ajax you want to respond when the ajax call is complete. It may take more or less than 1000ms. $.ajax allows you do this with the .done() method. This is an example from the docs:

$.ajax({
    url: "test.html",
    context: document.body
}).done(function() {
    $(this).addClass("done");
});

window.setTimeout will execute any given function after a specified delay.

You'd call it like this:

$('yourElement').click(function (event) {
    setTimeout(function () { console.log('hi'); }, 1000);
});

But I have to wonder why you need to do this. What's the problem you're trying to solve? Usually delaying stuff doesn't really solve anything.

jQuery's ajax functionality provides exactly what you are looking for. You can define a callback function to run after your ajax request.

Something like this:

$('#someElement').click(function(event){
    event.preventDefault();
    var loc = $(this).attr('href');
    $.ajax({
        url: "test.html",
        complete: function(){
            // Handle the complete event
            loc = $(this).attr('href');
            window.location.href = loc;
        }
    });
});

You may want to use ajaxStop instead of complete, it seems like your motivation for delaying navigation is because you have a bunch of asynchronous stuff going on and you want to make sure all your ajax stuff is complete before you navigate to that page.

Regardless I would recommend looking at http://api.jquery.com/Ajax_Events/ (a very useful page of documentation).

发布评论

评论列表(0)

  1. 暂无评论