首页 > 解决方案 > JavaScript DOM 问题

问题描述

我在检索某些元素的 textContent 时遇到问题。问题出在第 88-91 行。第 91 行检索 null 值。我不明白为什么会这样。我能够通过将第 91 行设置为变量并将 console.log() 设置为控制台来验证这一点,并且该值返回为 null。此外,在第 99 行,我的控制台给了我一个错误,“未捕获的类型错误:无法读取未定义的属性 'firstChild'”。我假设这个错误与我在第 88-91 行遇到的问题有关,但我不完全确定,因为它说的是未定义而不是 null。HTML 元素里面有文本,所以我不知道为什么它会返回 null。我不确定我错过了什么。非常感谢任何见解。提前感谢各位大佬的见解!

HTML 标记:

(function(){
        const taskList = document.querySelector('ul');
        const completedList = document.querySelector('#completed-task');
        const editTask = document.querySelector('#edit-task');
        const cover = document.querySelector('.cover');
        const editedInfo = document.querySelector('#edited-info');
        const editedDate = document.querySelector('#edited-date');
        const editedName = document.querySelector('edited-item');
        let editedListItem;
    
        document.querySelector('button').addEventListener('click', function(e) {
            /* Preventing Page Default Page Refresh*/
            e.preventDefault();
        
            /* Grabbing User Input */
            let userInput = document.querySelector('input').value;
            let userDate = document.getElementById('date').value;
            let userInfo = document.getElementById('userInfo').value;
        
            /* Creating Elements */
            let listItem = document.createElement('li');
            let container = document.createElement('div');
            let item = document.createElement('span');
            let deletebutton = document.createElement('span');
            /* Update: February 4, 2019 --> Creating Info Box */
            let infoBox = document.createElement('div');
            let dueDate = document.createElement('p');
            let info = document.createElement('p');
            let span = document.createElement('span');
            /* Update: February 5, 2019 --> Creating Edit button */
            let edit = document.createElement('span');
    
            /* Adding Attributes */
            container.setAttribute('class', 'container');
            deletebutton.setAttribute('class','delete');
            infoBox.setAttribute('class','info');
            edit.setAttribute('class', 'edit');
    
            /* Setting User Input */
            item.textContent = userInput;
            span.textContent = userDate;
            info.textContent = userInfo;
            deletebutton.textContent = "Discard";
            dueDate.textContent = "Due: ";
            edit.textContent = "Edit";
            
    
            /* Adding Elements to List */
            taskList.appendChild(listItem);
            listItem.appendChild(container);
            container.appendChild(item);
            container.appendChild(deletebutton);
            listItem.appendChild(infoBox);
            infoBox.appendChild(dueDate);
            infoBox.appendChild(info);
            dueDate.appendChild(span);
            infoBox.appendChild(edit);
        });
    
        document.querySelector('#task-list').addEventListener('click',function(event){
            if(event.target.className == 'delete') {
                const li = event.target.parentElement;
                li.parentElement.removeChild(li);
            }
        });
    
        /* Update: February 4, 2019 --> Hide Tasks Checkbox */
        document.forms['hide-task'].addEventListener('change', function(event){
            const checkbox = document.querySelector('input[type="checkbox"]');
                
            if (checkbox.checked === true) {
                taskList.style.display = 'none';
            } else {
                taskList.style.display = 'block';
            }
        });
    
        taskList.addEventListener('click', function(event){
            if (event.target.className == 'complete') {
                let parent = event.target.parentElement.parentElement;
                completedList.appendChild(parent);
            }
   

    /******* ISSUE OCCURS IN THIS CODE BLOCK *************/
                if (event.target.className == 'edit') {
                    event.preventDefault();
                    editTask.style.display = 'flex';
                    cover.style.display = 'block';
                    editedDate.value = event.target.previousSibling.previousSibling.textContent;
                    editedInfo.value = event.target.previousSibling.textContent;
                    editedName.value = event.target.parentElement.previousSibling.firstChild.textContent;
                    editedListItem = event.target.parentElement.parentElement;
                }
            });
        
            document.querySelector('#change').addEventListener('click', function(event){
        
                editedListItem.firstChild.firstChild.textContent = editedName.value;
                editedListItem.lastChild.firstChild.textContent = editedDate.value;
                editedListItem.lastChild.lastChild.textContent = editedInfo.value;
                
                editTask.style.display = 'none';
                cover.style.display = 'none';
            });
        
        })()
<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">       
        <title>To Do List</title>
    </head>
    <body>
        <div class="cover"></div>
        <h1>To do List</h1>
        <form>
            <div id="input-button">
                <input type="text" placeholder="Add an item..." class="item">
                <button type="submit" class="add">&#43;</button>
            </div>
            <div>
                <input type="text" placeholder="Due Date..." id="date">
                <input type="text" placeholder="About the task..." id="userInfo">
            </div>
        </form>
        <hr>
        <ul id="task-list">
            <li>
                <div class="container">
                    <span class="title">Example Task</span>
                    <span class="delete">Discard</span>
                </div>
                <!-- Update: Feb #, 2019 --> 
                <div class="info">
                    <p>Due: <span>January 15, 2019</span></p>
                    <p>This is some example text that adds additional context or information for the task</p>
                    <span class="edit">Edit</span>
                </div>
            </li>
        </ul>
        <!-- Update: February 5, 2019 -->
        <ul id="completed-task">
            <li id="title">Completed Tasks</li>
        </ul>
        <!-- Update: February 4, 2019 -->
        <form id="hide-task">
            <div>
                <input type="checkbox" name="hide-task">
                <label for="hide-task">Hide Tasks</label>
            </div>
        </form>
        <form id="edit-task">
            <input type="text" placeholder="Edit item..." id="edited-item">
            <input type="text" placeholder="Edit Due Date..." id="edited-date">
            <input type="text" placeholder="Edit about the task..." id="edited-info">
            <button id="change" type="button">Change</button>
        </form>
    </body>
    </html>

标签: javascriptdom

解决方案


休息和吃过晚饭后,我开始以全新的眼光和不沮丧的心态进行调试,并发现了错误。现在一切正常。

第一个问题: querySelector 中的错字导致其中一个变量返回 textContent 错误。

解决方案:

const editedName = document.querySelector('#edited-item');

第 2 期: 在大多数情况下previousSiblingpreviousElementSibling返回元素,但 previousSibling将返回任何类型的兄弟。一些浏览器会在元素周围添加空白区域
,因此previousSibling会抓取元素周围的空白区域,但previousElementSibling始终会抓取元素。我最初的代码是抓取元素周围的空白区域。

解决方案:

    taskList.addEventListener('click', function(event){
    if (event.target.className == 'complete') {
        let parent = event.target.parentElement.parentElement;
        completedList.appendChild(parent);
    }

    if (event.target.className == 'edit') {
        event.preventDefault();
        editTask.style.display = 'flex';
        cover.style.display = 'block';
        editedDate.value = event.target.previousElementSibling.previousElementSibling.firstElementChild.textContent;
        editedInfo.value = event.target.previousElementSibling.textContent;
        editedName.value = event.target.parentElement.previousElementSibling.firstElementChild.textContent;
        editedListItem = event.target.parentElement.parentElement;
    }
});

document.querySelector('#change').addEventListener('click', function(event){
    editedListItem.firstElementChild.firstElementChild.textContent = editedName.value;
    editedListItem.lastElementChild.firstElementChild.firstElementChild.textContent = editedDate.value;
    editedListItem.lastElementChild.firstElementChild.nextElementSibling.textContent = editedInfo.value;

    editTask.style.display = 'none';
    cover.style.display = 'none';
});

推荐阅读