Данные localStorage не отображаются при перезагрузке окна

Я создаю макет приложения RSVP и не могу получить данные localStorage при обновлении страницы. Я стремлюсь иметь возможность вставить имя и добавить его в список приглашенных. Затем пользователь может либо повторить эти шаги для нескольких имен, либо отредактировать имена в списке. У меня эта часть отключена, но если я обновлю страницу, приглашенных больше не будет в списке под панелью ввода. Мне нужно туда, где будут храниться имена в списке, а кнопки на элементах списка (редактировать, удалить) все равно будут работать.

С приведенным ниже «основным кодом» элемент добавляется в localStorage и устанавливается как «rsvp», но видимый список не обновляется, пока я не обновлю страницу. Мне нужно, чтобы он обновлялся каждый раз, когда я нажимаю кнопку отправки. я пытался добавить

if (rsvp != null) {
   ul.outerHTML = rsvp;
}

прямо под

console.log(rsvp);

но когда я нажимаю «Отправить», список не обновляется, и в консоли вы видите данные, которые были загружены в предыдущий раз, когда вы использовали приложение.

Например, если я ввожу «Тест», нажимаю «Отправить», набираю «Тест2», нажимаю «Отправить», затем набираю «Тест3» и снова нажимаю «Отправить» — список явно не обновляется, вы получаете сообщение об ошибке в консоли «Uncaught DOMException: не удалось установить свойство «outerHTML» в «Элементе»: у этого элемента нет родительского узла», и список никогда не обновляется, пока вы не обновите страницу, не введете другое имя и не нажмете «Отправить». Опять же, если вы это сделаете, список не обновится, пока вы не повторите тот же процесс.

Основной код (без оператора rsvp 'if' в обработчике)

document.addEventListener('DOMContentLoaded', () => {

 const form = document.getElementById('registrar');
 const input = form.querySelector('input');

 const mainDiv = document.querySelector('.main');
 const ul = document.getElementById('invitedList');

 const div = document.createElement('div');
 const filterLabel = document.createElement('label');
 const filterCheckbox = document.createElement('input');



 filterLabel.textContent = "Hide those who haven't responded";
 filterCheckbox.type = 'checkbox';
 div.appendChild(filterLabel);
 div.appendChild(filterCheckbox);
 mainDiv.insertBefore(div, ul);

 // Creates the list item for the RSVP list
 function createLI(text) {
     function createElement(elementName, property, value) {
         const element = document.createElement(elementName);
         element[property] = value;
         return element;
     }

     function appendToLI(elementName, property, value) {
         const element = createElement(elementName, property, value);
         li.appendChild(element);
         return element;
     }

     const li = document.createElement('li');
     appendToLI('span', 'textContent', text);
     appendToLI('label','textContent', 'Confirm')
        .appendChild(createElement('input', 'type', 'checkbox'));
     appendToLI('button', 'textContent', 'edit');
     appendToLI('button', 'textContent', 'remove');
     return li;
 }


 form.addEventListener('submit', (e) => {
     e.preventDefault();
     const text = input.value;
     input.value = '';

     // Checks for empty string in the input area
     if (text === '') {
         alert("You have not entered a name, please try again.");
         return;
     }
     // Checks for duplicate names
     for (i = 0; i < ul.children.length; i++) {
         if (text === ul.children[i].children[0].textContent) {
             alert("This name has already been entered. Please enter a different name.");
             return;
         }
     }

     const li = createLI(text);
     ul.appendChild(li);

     localStorage.setItem('rsvp', JSON.stringify(ul.outerHTML));  


 });

 const rsvp = JSON.parse(localStorage.getItem('rsvp'));
 if (rsvp != null) {
    ul.outerHTML = rsvp;
 }


 // Changes list item from confirm to confirmed
 ul.addEventListener('change', (e) => {
     const checkbox = event.target;
     const checked = checkbox.checked;
     const label = checkbox.parentNode;
     const listItem = checkbox.parentNode.parentNode;

     if (checked) {
         listItem.className = 'responded';
         label.childNodes[0].textContent = 'Confirmed';
     } else {
         listItem.className = '';
         label.childNodes[0].textContent = 'Confirm';
     }
 });


 ul.addEventListener('click', (e) => {
     if (e.target.tagName === 'BUTTON') {
         const button = e.target;
         const li = button.parentNode;
         const ul = li.parentNode;
         const action = button.textContent; 
         const nameActions = {
             remove: () => {
                 ul.removeChild(li);
             },
             edit: () => {
                 const span = li.firstElementChild;
                 const input = document.createElement('input');
                 input.type = 'text';
                 input.value = span.textContent;
                 li.insertBefore(input, span);
                 li.removeChild(span);
                 button.textContent = 'save';
             },
             save: () => {
                 const input = li.firstElementChild;
                 const span = document.createElement('span');
                 span.textContent = input.value;
                 li.insertBefore(span, input);
                 li.removeChild(input);
                 button.textContent = 'edit';
             }
         };
         // select and run action in button's name
         nameActions[action]();
     }
 });

 // Filters out those who have not yet responded
 filterCheckbox.addEventListener('change', (e) => {
     const isChecked = e.target.checked;
     const lis = ul.children;

     if (isChecked) {
         for (let i = 0; i < lis.length; i++) {
             let li = lis[i];
             if (li.className === 'responded') {
                 li.style.display = '';
             } else {
                 li.style.display = 'none';
             }
         }
     } else {
         for (let i = 0; i < lis.length; i++) {
             let li = lis[i];
             li.style.display = '';
         }
     }

 });

});

person andrewlundy    schedule 26.10.2017    source источник


Ответы (1)


const rsvp = JSON.parse(localStorage.getItem('rsvp'))

вызывается в обработчике событий DOMContentLoaded

if (rsvp != null) {
  ul.outerHTML = rsvp;
}

вызывается сразу после .addEventListener(); также код в Вопросе не указывает, где localStorage.getItem('rsvp') устанавливается до вызова const rsvp = JSON.parse(localStorage.getItem('rsvp')).

Вы можете проверить, имеет ли localStorage ключ свойства "rsvp" перед определением rsvp, и использовать условие и оператор if с обработчиком событий DOMContentLoaded.

person guest271314    schedule 26.10.2017
comment
Я обновил код. Теперь он обновляет и сохраняет список, но кнопки рядом с именами имеют нулевую функциональность. - person andrewlundy; 27.10.2017