Дамы и Господа, решил осложнить структуру сайта...
И после того, как вопрос отметили как дубликат, а я в дубликате не нашел решения, решил вопрос переформулировать. Тем более дали пару подсказок Особая благодарность Дмытрык-у.
Вопрос более подробно описан комментариями в коде
Есть такой ajax код: (в отдельном файле)
function ajax(url, callback, data, request) {
try {
request = new(this.XMLHttpRequest || ActiveXObject)('MSXML2.XMLHTTP.3.0');
request.open(data ? 'POST' : 'GET', url, 1);
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
request.setRequestHeader('Content-type', 'application/json');
request.onreadystatechange = function () {
request.readyState > 3 && callback && callback(request.responseText, request);
};
request.send(data)
} catch (e) {
window.console && console.log(e);
}
};
и вот такая структура главного index.html
И далее я подгружаю контент ajax-ом вот код
document.addEventListener("DOMContentLoaded", function() { const iDroot = document.getElementById('root'); ajax('../pages/index.html', function(res) { iDroot.innerHTML = res; const blockRight = document.getElementById('blockRight'); const blockLeft = document.getElementById('blockLeft'); ajax('../pages/header/index.html', function(res) { blockRight.innerHTML = res; let h1 = document.querySelector('h1') console.log(h1); // как видно из скрина этот console.log срабатывает h1.addEventListener('click', function() { console.log(h1); // этот console.log не срабатывает но ошибки не выдает
}) // но если обернуть h1.addEventListener('click', // в setTimeout(function() { то все работает }) ajax('../pages/main/index.html', function(res) { blockLeft.innerHTML += res; let main = document.querySelector('main') console.log(main); // как видно из скрина этот console.log срабатывает main.addEventListener('click', function() { console.log(main); // этот console.log срабатывает }) }) ajax('../pages/footer/index.html', function(res) { blockRight.innerHTML += res; }) }) })
И есть еще другой файл main.js в котором
setTimeout(function() { let menuWrapper = document.querySelector('menuWrapper') menuWrapper.addEventListener('click', function() {
console.log(menuWrapper); })
}, 500)
и если убрать обертку в виде setTimeout то эта функция тоже не работает. Судя по сему, вопрос такой. Является ли в данном случае использование setTimeout костылем? Если да, то есть ли какой-нибудь более изящный вариант выйти из ситуации
Ответ
blockRight.innerHTML += res;
Каждый раз когда ты изменяешь innerHTML, все существовавшие там dom-элементы уничтожаются, а вместо них создаются новые.
Соответственно, после выполнения этой строки ты подписан на клик по элементу, который уже не на странице.
Если нужно добавить кусок разметки к существующему элементу, то следует использовать
blockRight.insertAdjacentHTML('beforeend', res);
ajax('../pages/header/index.html', function(res) {
blockRight.innerHTML = res;
...
})
ajax('../pages/main/index.html', function(res) {
blockLeft.innerHTML += res;
...
})
ajax('../pages/footer/index.html', function(res) {
blockRight.innerHTML += res;
})
Это вообще неправильно. Нельзя ожидать, что ответы придут именно в таком порядке. Порядок этих вызовов может быть любым.
function ajax(url, callback, data, request) {
try {
...
} catch (e) {
Этот catch не ловит ничего полезного. В случае ошибки при ajax-запросе catch не вызовется.
Комментариев нет:
Отправить комментарий