Element.inner HTML разрывает соединение между элементом и Document в DOM (isConnected = false)? - PullRequest
0 голосов
/ 25 марта 2020

Так что в основном я пытался сделать сообщение об ошибке, которое по умолчанию скрыто, когда пользователь вводит неверную информацию. Однако сообщение не появилось. Поэтому я использовал отладчик и обнаружил, что элемент узла ошибки находится в верхней части js. Код успешно обнаружил элемент в HTML, а также успешно изменил его свойства. И все же ничего не происходило. Поэтому после небольшого исследования я обнаружил, что есть свойство isConnected, которое показывает, связан ли узел с документом. Оказывается, моя была подключена (true) сразу после нахождения элемента, но была отключена (false) к тому времени, когда вошла в errorHandler () fun c. Итак, еще раз после небольшой отладки я обнаружил, что суть проблемы onPageLoad c была причиной проблемы. Раньше это был rootUl.inner HTML + = template (countryObj); но это сломало это. Однако, когда я переместил свой элемент ошибки в HTML из ul наружу id = "root" div, он работал нормально. Он ломался только тогда, когда элемент находился внутри ул. В конце дня я исправил это, используя вместо этого Element.insertAdjacent HTML (), который не разорвал бы связь между элементом error и Document. Итак, после часа борьбы мне любопытно, почему это происходит и в чем разница между rootUl.inner HTML + = template (countryObj); и rootUl.insertAdjacent HTML ('beforeend', template (countryObj)); Просто добавьте, rootUl.innerHTML + = template (countryObj) разрывает соединение, даже когда используется другой функцией, которая здесь не показана.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>List Towns</title>
    <script src="../handlebars.min.js"></script>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <p style="text-align: center; font-size: 18px; font-weight: 700; font-family: Arial, Helvetica, sans-serif;">
        Input in the following format: "{Country}: {town}, {town} {Country}: {town}, {town}" and so on. Matching is case-insensitive. Non-english characters are not supported. Numbers are not supported. Check regex for more info. Reset button deletes entire database and refreshes page. 
    </p>
    <form action="#" class="content">
        <label for="towns">Towns</label>
        <input id="towns" type="text" placeholder="ex. Bulgaria: Burgas, Varna Turkey: Ankara"/>
        <button id="btnLoadTowns">Load</button>
    </form>
    <div id="root">
        <ul>
            <!--When the element was here, innerHTML wasn't working correctly-->
            <h4 id="error" style="color: rgb(136, 9, 0); display: none;" >Error. Input string not in correct format. Look at instructions above.</h4>
        </ul>
    </div>
    <!--When the element was here, innerHTML was working fine-->
    <!-- <h4 id="error" style="color: rgb(136, 9, 0); display: none;" >Error. Input string not in correct format. Look at instructions above.</h4> -->
    <button id="reset">Reset</button>
    <h4 id="empty-database" style="color: rgb(136, 9, 0); display: none;" >Database is currently empty.</h4>
</body>
<script src="./app.js"></script>

</html>
async function pageApp(){
    //Misc
    let error = document.querySelector('#error');
    let emptyDatabase = document.getElementById('empty-database');
    // Grab the unordered list of countries
    let rootUl = document.querySelector('#root ul');
    // Extract(GET request) data from database
    let database = await getRequestForCountries();
    // Get the two templates: One is for both country and town, another is just for town when country already exists
    let template = await getTemplate();
    let templateTown = await getTemplateTown();
    // Load countries on page load
    onPageLoad();
    //Attach load event to button
    attachLoadEvent();
    //Reset button for deleting the database
    resetButton()

    function errorHandler(){
        error.style.display = 'block';
        setTimeout(function(){
            error.style.color = 'rgb(136, 9, 0)';
            error.style.background = 'none';
        }, 150)
        error.style.color = 'red';
        error.style.background = 'rgb(136, 9, 0)';
    }

    function onPageLoad(){
        database.forEach(entry => {
            let townsArr = entry.towns;
            let countryName = entry.countryName;
            let townsArrObj = townsArr.reduce((acc, cur) =>{
                let townObj = {
                    name: cur
                }
                acc.push(townObj);
                return acc;
            },[]);
            let countriesObj = {
                countries:[
                    {
                        name: countryName, 
                        towns: townsArrObj
                    }
                ]
            }
            //Was rootUl.innerHTML += template(countriesObj); But that breaks the DOM of error and makes error.isConnected = false; 
            // rootUl.innerHTML += template(countriesObj);
            rootUl.insertAdjacentHTML('beforeend', template(countriesObj)); 
        })
    }

1 Ответ

0 голосов
/ 25 марта 2020

Element.innerHTML +=, получает HTML код внутри элемента и добавляет его чем-то.

document.querySelector('p').innerHTML += `<span>Appended span</span>`;
<p>
  Lorem Ipsum
  <span style="color: red">Something</span>
<p>

Принимая во внимание, что Element.insertAdjacentHTML('beforeend', 'To be inserted node') добавит новый узел перед указанным элементом.

document.querySelector('p').insertAdjacentHTML('beforeend', '<div>I am div</div>');
<p>Lorem ipsum</p>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...