Посмотрите на этот пример:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope,$http) {
var getJoke = function(){
return $http.get('http://api.icndb.com/jokes/random').then(function(res){
return res.data.value;
});
}
getJoke().then(function(res) {
console.log(res.joke);
});
});
Как вы можете видеть, getJoke
возвращает разрешенное обещание (оно разрешено при возврате res.data.value
). Таким образом, вы ждете, пока запрос $ http.get не будет завершен, а затем выполнится console.log (res.joke) (как обычный асинхронный поток).
Это plnkr:
Селектора jQuery выбирают совпадающие элементы, которые существуют в DOM при выполнении кода и не динамически обновляются. Когда вы вызываете функцию, например .hover()
, чтобы добавить обработчик событий, она добавляет их только к этим элементам. Когда вы выполняете вызов AJAX и заменяете раздел своей страницы, вы удаляете эти элементы с привязанными к ним обработчиками событий и заменяете их новыми элементами. Даже если эти элементы теперь соответствуют этому селектору, они не получают привязки обработчика события, потому что уже выполненный код.
Обработчики событий
В частности, для обработчиков событий (т. Е. .click()
), вы можете использовать делегирование событий, чтобы обойти это. Основной принцип заключается в том, что вы привязываете обработчик событий к статическому (существует, когда страница загружается, не заменяется) элемент, который будет содержать весь ваш динамический (загруженный AJAX) контент. Вы можете узнать больше о делегировании событий в документации jQuery .
Для вашего обработчика событий click
обновленный код будет выглядеть так:
$(document).on('click', "#click", function () {
$('#click').css({
"background-color": "#f00",
"color": "#fff",
"cursor": "inherit"
}).text("Open this window again and this message will still be here.");
return false;
});
Это привяжет обработчик события ко всему документу (поэтому он никогда не удаляется до выгрузки страницы), который будет реагировать на события click
на элементе с свойством id
в click
. В идеале вы должны использовать что-то ближе к своим динамическим элементам в DOM (возможно, <div>
на вашей странице, которая всегда присутствует и содержит все содержимое вашей страницы), поскольку это немного улучшит эффективность.
Проблема возникает, когда вам нужно обрабатывать .hover()
. В JavaScript нет реального события hover
, jQuery просто предоставляет эту функцию как удобное сокращение для привязки обработчиков событий к событиям mouseenter
и mouseleave
. Однако вы можете использовать делегирование делегирования:
$(document).on({
mouseenter: function () {
$(this).stop().animate({
width: xwidth * 3,
height: xheight * 3,
margin: -(xwidth / 3)
}, 200); //END FUNCTION
$(this).addClass('image-popout-shadow');
},
mouseleave: function () {
$(this).stop().animate({
width: xwidth,
height: xheight,
margin: 0
}, 200, function () {
$(this).removeClass('image-popout-shadow');
}); //END FUNCTION
}
}, '.image-popout img');
плагины jQuery
Что касается привязок обработчика событий. Однако это еще не все, что вы делаете. Вы также инициализируете плагин jQuery (colorbox), и нет возможности делегировать их элементам. Вам придется просто называть эти строки снова, когда вы загрузили свой контент AJAX; самым простым способом было бы переместить их в отдельную именованную функцию, которую вы можете вызвать в обоих местах (при загрузке страницы и в обратном вызове AJAX success
):
function initialiseColorbox() {
$(".iframe").colorbox({
iframe: true,
width: "1000px",
height: "500px"
});
$(".inline").colorbox({
inline: true,
width: "50%"
});
$(".callbacks").colorbox({
onOpen: function () {
alert('onOpen: colorbox is about to open');
},
onLoad: function () {
alert('onLoad: colorbox has started to load the targeted content');
},
onComplete: function () {
alert('onComplete: colorbox has displayed the loaded content');
},
onCleanup: function () {
alert('onCleanup: colorbox has begun the close process');
},
onClosed: function () {
alert('onClosed: colorbox has completely closed');
}
});
}
Была та же проблема, прежде чем я смог найти решение, которое сработало для меня. Поэтому, если кто-то в будущем может дать ему шанс и сообщить мне, было ли это правильно, поскольку все решения, которые я смог найти, были немного сложнее этого.
Так, как сказал Тамер Дургун, мы также разместим ваш код внутри ajaxStop, поэтому ваш код будет восстановлен каждый раз, когда какое-либо событие будет завершено ajax.
$( document ).ajaxStop(function() {
//your code
}
Работал для меня:)
Ваши обработчики событий теряются при замене содержимого. Когда вы устанавливаете события hover
, jQuery устанавливает их в событиях на странице в настоящее время. Поэтому, когда вы заменяете их на ajax, события не связаны с этими элементами, потому что они новы.
Чтобы исправить это, вы можете либо вызвать функцию, которая их связывает, либо вместо этого вы можете установить обработчик событий документ, как в этом ответе , используя $ (document) .on
Таким образом, событие устанавливается в документе, и любые новые элементы получат вызванное событие.
Вы можете использовать полную функцию jQuery ajax после извлечения формы данных где-нибудь, она увидит обновленные элементы после завершения ajax
Вы можете использовать метод jQuery для пользователя delegate () , который присоединяет обработчик к одному или нескольким событиям для всех элементов, которые соответствуют селектору, сейчас или в будущем, на основе определенного набора корневых элементов. В моем случае он работает как ожидалось
, этот $(selector).click(function(e){}
стал таким после использования метода delegate ()
$( "body" ).delegate( "selector", "click", function(e) {}
Надеюсь, это поможет;)