Страницы

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

четверг, 9 января 2020 г.

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

#javascript


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



И после того, как вопрос отметили как дубликат, а я в дубликате не нашел решения,
решил вопрос переформулировать. Тем более дали пару подсказок Особая благодарность
Дмытрык-у.
Вопрос более подробно описан комментариями в коде

Есть такой 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 костылем? Если да, то есть ли какой-нибудь более изящный вариант выйти из ситуации


Ответы

Ответ 1



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 не вызовется.

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

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