Как использовать событие нажатия jQuery для асинхронного изменения значения href на основе запроса JSON

Я использую сервис сокращения URL bit.ly для сокращения отправки определенных URL в функцию "поделиться в твиттере". Я бы хотел загружать URL-адрес bit.ly только тогда, когда пользователь фактически нажимает кнопку "Поделиться" (из-за ограничения по 5 параллельным запросам в bit.ly). REST API Bit.ly возвращает JSON-вызов с сокращенным URL-адресом, что делает весь сценарий асинхронным.

Я попробовал следующее, чтобы остановить событие click и подождать, пока вызов JSON вернет значение, прежде чем запускать click.

У меня есть следующий упрощенный код в jQuery(документ).ready():

Обновленный код (упрощенно)!

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();
    });
});

И следующий код для обработки укороченного сокращения (работает просто отлично):

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)

Href меняет свое значение, но последнее событие.click() никогда не запускается. Это прекрасно работает при определении статического значения для href, но не при использовании асинхронного метода JSON.

4 ответа

Решение

Tzury Bar Yochay указал мне правильное направление, предложив использовать location.href для обновления URL. Также Victor помог с его ответом.

У меня все получалось, сочетая ответы, но у меня были проблемы с историей в Firefox. Кажется, что обновление window.location действительно перенаправило пользователя, но также удалило "исходную страницу" из истории. Этого не произошло в Chrome, Safari, ie8, ie8-совместимость или ie7.

Основываясь на этом ответе на другой вопрос, я смог создать обходной путь, предоставив следующий рабочий код + внес несколько изменений:

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;
});

Спасибо за помощь!

Как вы сами обрисовали:

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

Это означает, что БРАУЗЕР НЕ НАХОДИТСЯ НА ЭТОТ URL, если вы действительно хотите перейти к местоположению с длинным URL, просто сделайте что-то вроде:

document.location.href = longurl;

Я думаю, что вы на самом деле хотите, чтобы return false; из события click, чтобы предотвратить фактическое следование href, верно?

Подобно:

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;
});

iirc, jquery не вызывает "щелчок" по элементам A. Я бы попробовал старый добрый "location.href= что угодно" в обратном вызове.

 bitlyJSON(function(shortUrl) {
      link.attr("href", function() {
      //process shortUrl
      //return finalized url;                   
    });
    location.href = link.attr("href");
});
Другие вопросы по тегам