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

javascript - How to use jQuery click event to change href value asynchronously, based on a JSON query - Stack Overflow

programmeradmin4浏览0评论

I'm using the bit.ly url shortening service to shorten certain url's being sent to a "share on twitter" function. I'd like to load the bit.ly url only when a user actually presses the share button (due to bit.ly's max 5 parallel reqs limitation). Bit.ly's REST API returns a JSON callback with the shortened url, which makes the whole scenario async.

I've tried the following to stop the click event, and wait for the JSON call to return a value before launching the click.

I have the following simplified code in jQuery(document).ready():

Updated code (oversimplified)!

jQuery("#idofaelement").click(function(event) {
    event.preventDefault(); //stop the click action
    var link = jQuery(this);
    bitlyJSON(function(shortUrl) {
        link.attr("href", function() {
          //process shortUrl
          //return finalized url;                   
        }).unbind().click();
    });
});

And the following code to handle the bitly shortening (works just fine):

function bitlyJSON(func) {
//
// build apiUrl here
//
jQuery.getJSON(apiUrl, function(data) {
    jQuery.each(data, function(i, entry) {
        if (i == "errorCode") {
            if (entry != "0") {
                func(longUrl);}
        } else if (i == "results") {
            func(entry[longUrl].shortUrl);}
    });
});  
} (jQuery)

The href gets its value changed, but the final .click() event never gets fired. This works fine when defining a static value for the href, but not when using the async JSON method.

I'm using the bit.ly url shortening service to shorten certain url's being sent to a "share on twitter" function. I'd like to load the bit.ly url only when a user actually presses the share button (due to bit.ly's max 5 parallel reqs limitation). Bit.ly's REST API returns a JSON callback with the shortened url, which makes the whole scenario async.

I've tried the following to stop the click event, and wait for the JSON call to return a value before launching the click.

I have the following simplified code in jQuery(document).ready():

Updated code (oversimplified)!

jQuery("#idofaelement").click(function(event) {
    event.preventDefault(); //stop the click action
    var link = jQuery(this);
    bitlyJSON(function(shortUrl) {
        link.attr("href", function() {
          //process shortUrl
          //return finalized url;                   
        }).unbind().click();
    });
});

And the following code to handle the bitly shortening (works just fine):

function bitlyJSON(func) {
//
// build apiUrl here
//
jQuery.getJSON(apiUrl, function(data) {
    jQuery.each(data, function(i, entry) {
        if (i == "errorCode") {
            if (entry != "0") {
                func(longUrl);}
        } else if (i == "results") {
            func(entry[longUrl].shortUrl);}
    });
});  
} (jQuery)

The href gets its value changed, but the final .click() event never gets fired. This works fine when defining a static value for the href, but not when using the async JSON method.

Share Improve this question edited Jun 18, 2017 at 11:35 Cœur 38.7k26 gold badges203 silver badges277 bronze badges asked Oct 27, 2009 at 7:46 pavsaundpavsaund 6961 gold badge5 silver badges16 bronze badges 4
  • can you please provide here the case that does work for you (the static value one)? – Tzury Bar Yochay Commented Oct 27, 2009 at 7:55
  • staic value used for testing: jQuery("#idofaelement").click(function(event) {link.attr("href", "urlhere");}); – pavsaund Commented Oct 27, 2009 at 8:00
  • Is anything in //process shortUrl this async? – AnthonyWJones Commented Oct 27, 2009 at 8:35
  • Nope. just collects values and builds up the twitter url. If i replace the function and use the returned json url directly i still get the same problem: ie: ...link.attr("href", shortUrl).unbind().click();... – pavsaund Commented Oct 27, 2009 at 8:46
Add a ment  | 

4 Answers 4

Reset to default 5

As you outlined yourself:

event.preventDefault(); //stop the click action

That means, BROWSER IS NOT GOING TO THAT URL, if you wish to actually go forward to the long-url location, simply do something like:

document.location.href = longurl;

iirc, jquery doesn't trigger "click" on A elements. I'd try old good "location.href=whatever" in the callback.

 bitlyJSON(function(shortUrl) {
      link.attr("href", function() {
      //process shortUrl
      //return finalized url;                   
    });
    location.href = link.attr("href");
});

I think what you actually want is to return false; from the click event, to prevent the actual following of the href, right?

Like:

jQuery("#idofaelement").click(function(event) {
    //event.preventDefault(); //stop the click action
    var link = jQuery(this);
    bitlyJSON(function(shortUrl) {
        link.attr("href", function() {
        //process shortUrl
        //return finalized url;                   
        }).unbind().click();
    });
    return false;
});

@Tzury Bar Yochay pointed me in the right direction by suggesting I use location.href to update the url. Also @Victor helped with his answer.

I got things kinda working bining the answers, but had issues with the history in firefox. Seems that updating window.location indeed redirected the user, but also removed the "source page" from the history. This did not happen in chrome, safari, ie8, ie8-patibility or ie7.

Based on this response to another question I was able to create a workaround giving the following working code + made a few changes:

jQuery("#idofaelement").one("click", function(event) {
    bitlyJSON(function(shortUrl) {
        jQuery("#idofaelement").attr("href", function() {
            //process shortUrl
            //return finalized url;                   
        });
        setTimeout(function() {
            window.location = jQuery("#idofaelement").attr("href");
        }, 0);
    });
    return false;
});

Thanks for all the help!

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论