JS объект "потерял ссылку" на элемент DOM - PullRequest
0 голосов
/ 16 апреля 2020

Со вчерашнего дня я неожиданно начал испытывать некоторые странные вещи, связанные с элементами DOM.

Дело в том, что в скрипте JS я создаю некоторые константы, ссылающиеся на элементы в моем документе HTML , но когда я пытаюсь получить к ним доступ (например, обновить innerHTML или установить событие, например onclick), это не имеет эффекта; Возиться с кодом, я видел, что кажется, что они теряют ссылку на фактический элемент. Позвольте мне объяснить:

В конце сценария JS я печатаю произвольный const на консоль, скажем, console.log(resultsContainer);. И это на самом деле печать элемента, но когда я нажимаю кнопку «Нажмите, чтобы выбрать узел в инспекторе» на консоли Firefox, он перенаправляет меня на тег body. Например, если реального элемента resultsContainer в документе не существует (но он есть, я могу найти его сам в инспекторе).

Что делает его более странным, так это то, что если я определю resultsContainer в точно так же, как я делаю это со своим сценарием, но на консоли и затем печатаю его, кнопка теперь волшебным образом возвращает меня к реальному элементу. И после этого, если я изменяю один из его атрибутов (например, innerHTML) из консоли браузера, он теперь отражает то, что я хочу.

Это похоже на то, когда я определяю их в сценарии JS, они сохранены как предыдущее состояние элемента, но они не обновляются или что-то в этом роде.

То, как я определяю resultsContainer и использую это

<!-- HTML file -->
<div id="resultsContainer" class="resultsContainer">
    <!-- Content -->
</div>
// JS file
let resultsContainer = document.getElementById('resultsContainer');

...
resultContainer.innerHTML = 'Some results'; // This is kinda working, see details below.
...
// This prints the element to the console, with the new innerHTML setted 
// before, but it does't reference my HTML element, as the innerHTML didn't change on the page.
console.log(resultsContainer); 

// If I execute this exact same code on console, it does what it's supposed to.

Не знаю Я действительно думаю, что это как-то связано с тем, как я размещаю код, потому что он буквально работал нормально несколько дней go, и я не касался этих файлов. (Я даже вернулся к одному коммиту, когда я был уверен, что он работал хорошо). Но да, я вызываю скрипт в конце моего тега body.

И это происходит со случайными объектами (я имею в виду, они всегда одинаковы, но между ними нет никакой корреляции) ).


Еще одна деталь, которая может помочь, заключается в том, что это происходит в основном на JS файлах, где я делаю XMLHTTP-запросы. Например, я определяю некоторые элементы, которые хочу обновить, основываясь на ответе HTTP. Если я устанавливаю запрос как асинхронный, это происходит, и когда я обновляю их содержимое, оно обновляется только в объекте JS, но не на странице HTML. Если вместо этого установить асинхронное значение false, оно будет работать нормально. Но это не всегда так :(. В некоторых случаях работает только установка асинхронного на false, но не во всех, как с resultsContainer, как я покажу ниже:

const searchPromise: (string) => Promise<Object> = 
    (query: string) => new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest();
        xhr.open('get', `/buscar?q=${query}`, false);

        xhr.onload = () => {
            let response = JSON.parse(xhr.response);

            if (response.code <= 0) {
                reject(response.message);
                return;
            }

            resolve(response.object);          
        };

        xhr.send();
    });

const searchAndPopulate = () => {
    const query: string = searchInput['value'].trim();

    searchPromise(query).then(list => {
        resultsContainer.innerHTML = '';
        for (const o in list) {
            resultsContainer.innerHTML += resultView(list[o]);
        }
    }).catch(error => {
        resultsContainer.innerHTML = `
            <p style="padding: 1em;">${error}</p>
        `;
    });
}

let searchButton = document.getElementById('searchButton');
document.getElementById('searchButton').onclick = searchAndPopulate;

С этим кодом, когда Я нажимаю на мой searchButton, он ничего не делает. Если я выполняю последние 2 строки в консоли браузера, то я могу вызвать функцию searchAndPopulate. Это делает петицию (Не правильно, хотя мне нужна строка query , но я не могу получить его, пока я не определю searchInput с консоли, даже если он определен в файле, но я не показываю его здесь), и я получу ожидаемый ответ, но тогда он не отражает на странице, если я не выполню let resultsContainer = document.getElementById('resultsContainer'); на консоли.

Сначала я подумал, что петиции HTTP должны были быть причиной моей проблемы, но, как вы можете видеть, я даже не могу установить .onclick event.


Я могу сделать несколько обходных путей, например, установить события onclick из самого HMTL, а не из сценария JS, но это начало происходить по всему моему проекту и без какой-либо логической причины. Единственное замечательное, что Я обновлял Windows 10.

Я действительно отчаянно пытался найти решение (или хотя бы причину этого), я был бы очень признателен за вашу помощь. Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...