Страницы

Поиск по вопросам

понедельник, 18 февраля 2019 г.

После загрузки контента AJAX-ом на сайт DOM элементы для JS не доступны

Дамы и Господа, решил осложнить структуру сайта...

И после того, как вопрос отметили как дубликат, а я в дубликате не нашел решения, решил вопрос переформулировать. Тем более дали пару подсказок Особая благодарность Дмытрык-у. Вопрос более подробно описан комментариями в коде
Есть такой 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

On-Line



И далее я подгружаю контент 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 не вызовется.

Комментариев нет:

Отправить комментарий