В моем текущем приложении у меня есть элементы на моей странице, которые начинаются «пустыми» и загружают свои отображаемые данные из вызова AJAX.
Простой способ реализовать это — использовать класс (скажем, .ajax-loader
) и выполнить цикл по каждому из них и загрузить данные AJAX из data-
атрибутов самого элемента.
Что-то вроде этого (jsfiddle):
<div class="ajax-loader" data-url="/echo/html/" data-html="<p>hello world</p>" data-delay="1">Loading...</div>
<script>
$('.ajax-loader').each(function() {
var ele = $(this);
var url = ele.data('url');
var html = ele.data('html');
var delay = ele.data('delay');
return $.post({
url: url,
data: {
html: html,
delay: delay
}
}).done(function(d) {
ele.html(d);
});
});
</script>
Пока это работает нормально, однако проблема возникает, когда мне нужно динамически вставить эти элементы .ajax-loader
на страницу. Моя функция .each()
запускается только один раз и не запускается снова, если на страницу вставляется новый элемент .ajax-loader
(вы можете увидеть это в предыдущем jsfiddle, нажав кнопку).
Поэтому я добавил наблюдатель мутаций для обнаружения изменений DOM. Теперь мой код выглядит так (jsfiddle):
<button class="insert-ele">Click to insert new AJAX object</button>
<div id="container">
<div class="ajax-loader" data-url="/echo/html/" data-html="<p>Hello World!</p>" data-delay="1">Loading...</div>
</div>
<script>
$(document).ready(function() {
// Insert new ".ajax-loader" objects on button click
$('.insert-ele').on('click', function(e) {
$('#container').append('<div class="ajax-loader" data-url="/echo/html/" data-html="<p>I was inserted via JS.</p>" data-delay="1">Loading...</div>');
e.preventDefault();
});
// Define our ajaxLoader function
var ajaxLoader = function() {
var ele = $(this);
ele.addClass('ajax-load-started');
var url = ele.data('url');
var html = ele.data('html');
var delay = ele.data('delay');
return $.post({
url: url,
data: {
html: html,
delay: delay
}
}).done(function(d) {
ele.html(d);
ele.addClass('ajax-load-completed');
ele.removeClass('ajax-load-started');
});
};
// Loop through each .ajax-loader, and load their AJAX request.
$('.ajax-loader:not(.ajax-load-completed):not(.ajax-load-started)').each(ajaxLoader);
// Observe DOM changes, and load AJAX data when it does change
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(function(mutations) {
$('.ajax-loader:not(.ajax-load-completed):not(.ajax-load-started)').each(ajaxLoader);
});
// Activate the observer
var container = document.getElementById('container');
observer.observe(container, {
attributes: true,
childList: true,
subtree: true
});
});
</script>
Однако, глядя на Совместимость браузера для Mutation Observers, я видите, он поддерживается только в IE 11. Мне нужно поддерживать IE 9 и, возможно, IE 8, хотя это не так важно.
Есть ли лучший способ сделать это? Или просто другой способ, который даст мне лучшую совместимость с браузером?
Я также понимаю, что могу запустить функцию $('.ajax-loader').each()
в обработчике $('.insert-ele').on('click')
, но я бы также хотел избежать этого решения, если это возможно.
.ajax-loader
(например, нажатие кнопки). Способ вставки этих элементов зависит от приложения. - person romellem   schedule 29.02.2016