Распространение событий и пост ajax
У меня есть следующий код:
<div id="parentDiv">
<a href="someurl"> ... </a>
</div>
HTML внутри div взят из внешнего источника, и я не знаю его структуру и не могу его контролировать.
Мне нужно опубликовать некоторые данные, когда эта ссылка была нажата. Поэтому я добавил обработчик события onclick для элемента div, надеясь, что событие будет распространяться, и разместил данные с помощью функции jQuery ajax.
Это работало нормально во всех браузерах, кроме Safari - он не возвращает никаких ошибок, вызывает функцию обратного вызова, но по какой-то причине не достигает сервера. Я пишу в базу данных каждый раз, когда получаю запрос. Попытался вручную загрузить URL-адрес поста в браузере - работает нормально, и запись в БД создается. Также пробовал FF и Chrome - работает как положено.
Когда в функцию обратного вызова помещается предупреждение, оно вызывается, но в Safari data = null.
$('#parentDiv').delegate( 'a', 'click', function()
{
$.post('posturl',
{ param1: 'test'},
function(data)
{
alert('data = '+data);
},
"json"
);
});
Правильно ли ожидать, что AJAX будет работать в этой ситуации вообще? И есть ли лучшее решение этой проблемы?
Спасибо!
2 ответа
Похоже, вам нужно объединить delegate
с асинхронным AJAX. Обратите внимание, что это почти никогда не бывает хорошо - единственное реальное исключение - это когда вы хотите сделать AJAX-запрос непосредственно перед тем, как покинуть страницу.
Ваш код может выглядеть примерно так:
$('#parentDiv').delegate( 'a', 'click', function()
$.ajax({
type: 'POST',
url: 'posturl',
{ param1: 'test'},
dataType: 'json',
async: false
});
});
Это ожидает завершения запроса POST, прежде чем продолжить переход по ссылке. Обратите внимание, что это лучше, чем использование location = url
в случае успешного обратного вызова, поскольку это решение позволяет выполнять обычные действия браузера, такие как нажатие средней кнопкой мыши, как обычно.
Вы хотите посмотреть на JQuery's .delegate()
метод. Он говорит элементу прослушивать определенное событие, всплывающее из определенного элемента, и выполнять поведение, когда оно наблюдается. Вы также хотите запретить действие ссылки по умолчанию и отправить браузер по ссылке после завершения операции ajax.
Документы: http://api.jquery.com/delegate/
Образец кода:
$( '#parentDiv' ).delegate( 'a', 'click', function( e )
{
var url = this.href;
e.preventDefault();
$.post(
'posturl',
{
param1: 'test'
},
function(data)
{
alert('data = ' + data);
window.location = url;
},
'json'
);
} );
Это:
- делегирует мероприятие
- предотвращает дефолт
- ждет ответа ajax
- отправляет браузер по ссылке