ajax-функция jQuery не работает в Safari (Firefox, Chrome, IE в порядке) - PullRequest
1 голос
/ 05 июля 2010

Я не специалист по javascript, но немного озадачен тем, как это работает в трех основных браузерах, но не в Safari ... что-то не так с этим кодом? По сути, я просто использую это в сочетании с обратным вызовом php / mysql по указанному URL для отслеживания кликов по ссылкам.

Drupal.behaviors.NodeDownloadCounter = function() {

    $('a.ndc-link').click(function() {
        $.post('http://www.pixeledmemories.com/node-download-counter/log/' + this.name);
        return true;
    });

};

Использование здесь поведения Drupal вместо

$(document).ready(function() {

(правильный метод Drupal), но я пробовал оба способа, и это не имеет значения.

Я также пытался удалить «вернуть истину», но безрезультатно.


Хорошо, дальнейшее тестирование показывает, что при срабатывании щелчка срабатывает СЕЙЧАС в Safari:

$('a.ndc-link').click(function() {
    alert('testing (ignore)');
    $.post('http://www.pixeledmemories.com/node-download-counter/log/' + this.name);
    return true;
});

Но все еще ничего не регистрируется в mysql. Вот моя функция обратного вызова:

function node_download_counter_log($nid)
{
    global $user;
  $timestamp = time();
    $title = db_result(db_query("SELECT title FROM {node} WHERE nid = %d", $nid));

  db_query("INSERT INTO {node_download_counter} (nid, title, download_count, last_download, last_uid) VALUES (%d, '%s', %d, %d, %d) 
                    ON DUPLICATE KEY UPDATE download_count=download_count+1, last_download = %d, last_uid = %d", $nid, $title, 1, $timestamp, $user->uid, $timestamp, $user->uid);

  db_query("INSERT INTO {node_download_counter_log} (nid, title, uid, timestamp) VALUES (%d, '%s', %d, %d)", $nid, $title, $user->uid, $timestamp);

}

Ответы [ 3 ]

3 голосов
/ 05 июля 2010

Похоже, проблема в том, что браузер меняет страницу до того, как публикация данных может быть завершена.Вы можете попробовать добавить return false, чтобы посмотреть, начнет ли он работать тогда.Если это произойдет, вам нужно будет добавить небольшую задержку перед переходом по ссылке.

ОБНОВЛЕНИЕ: Поскольку это работает, попробуйте добавить следующее перед «return true;»

if(jQuery.browser.safari){
  setTimeout("window.location.href= '"+this.href+"'",500);
  return false;
}
2 голосов
/ 05 июля 2010

Хорошо, основываясь на нашей беседе с комментариями выше, попробуйте

$('a.ndc-link').click(function() {
    var href = this.href;
    $.post('http://www.pixeledmemories.com/node-download-counter/log/' + this.name,
       function() {
           window.location.href = href;
       }
    );
    return false;
});
1 голос
/ 05 июля 2010

Во-первых, вы должны быть осторожны, чтобы не прикреплять обработчик более одного раза к каждому 'a.ndc-link', один из способов сделать это - пометить элементы пользовательским классом.

Drupal.behaviors.NodeDownloadCounter = function() {
    $('a.ndc-link:not(.node-download-counter-processed)').addClass('node-download-counter-processed').click(function(event) {
        // ...
    });
};

Одна из причин, по которой я не вижу этого, состоит в том, что, поскольку он закрывает страницу, чтобы открыть цель ссылки, Safari отменит запрос $.post, прежде чем он будет фактически отправлен на сервер. Возврат false и вызов event.preventDefault (событие является первым аргументом вашего обработчика событий) должно предотвратить это, но также не позволит браузеру фактически загрузить цель ссылки. Один из способов решить эту проблему - отложить изменение страницы до завершения запроса POST.

Drupal.behaviors.NodeDownloadCounter = function() {
    $('a.ndc-link:not(.node-download-counter-processed)').addClass('node-download-counter-processed').click(function(event) {
        var link = this;
        event.preventDefault();
        $.post('http://www.pixeledmemories.com/node-download-counter/log/' + this.name, function() {
          window.location.href = link.href;
        });
        return false;
    });
};

Но это будет работать только в том случае, если в запросе POST нет ошибок.

Лучшим решением было бы перехватить обработчик на стороне сервера для цели ссылки, чтобы добавить запись click , а затем вызвать оригинальный обработчик.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...