views:

1406

answers:

4

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 suspect I'm going about this the wrong way, any feedback is greatly appreciated.

+1  A: 

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");
});
stereofrog
Now this actually works. Didn't think of that. On a negative note though, when pressing "back" in the browser, it doesn't go to the page that actually launched the url.
pavsaund
could this be a FF issue? this functionality works fine in IE8 and chrome, from what I've tested
pavsaund
+1  A: 

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;
});
Victor
thx, but no luck here. Same end result. link opening gets stopped, and href gets updated
pavsaund
+1  A: 

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;
Tzury Bar Yochay
as I mentioned to @stereofrog updating the location.href does cause a correct redirect. However, when clicking back in the browser, the user skips the page that initiated the click (seemingly back 2 slots). Which isnt desireable
pavsaund
sorry did not notice that. so may you try to use jQuery's trigger right after the long-url arrival. But that would require and if condition within the handler. That is, if href is of short-url - get the long one and prevent defaults, otherwise, do nothing, and let the browser treat it as standard link click
Tzury Bar Yochay
link to jQuery's trigger http://docs.jquery.com/Events/trigger#eventdata
Tzury Bar Yochay
regarding location.href: could this be a FF issue? this functionality works fine in IE8 and chrome, from what I've tested
pavsaund
A: 

@stereofrog and @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 combining 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-compatibility 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!

pavsaund