首页 > 解决方案 > 未捕获的类型错误:无法在 Object.addListitem、ctrlAddItem、HTMLDocument 处读取 null- 的属性“insertAdjacentHTML”

问题描述

我在将数据插入到计算器应用程序的 UI 时收到此错误 - “未捕获的 TypeError:无法在 Object.addListitem、ctrlAddItem、HTMLDocument 处读取 null 的属性 'insertAdjacentHTML'”。我只是一个初学者,无法理解这个错误。请帮我找出我的错误。这是我的 HTML 和 JavaScript 代码。

HTML代码-

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <link href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet" type="text/css">
        <link href="https://fonts.googleapis.com/css2?family=Kalam&family=Recursive&family=Rowdies:wght@300&display=swap" rel="stylesheet">
        <link rel="stylesheet" href="assets\stylesheet\main.css">
        <title>BUDGETOFY</title>
    </head>
<body class="container">
<div class="background">

    <div class="av-budget-heading">Available Budget:</div>
    <div class="av-budget">+2,500</div>
    <div class="income">
        <div class="inex-heading left">Income</div>
        <div class="inex-number little-right-1">+3,500</div>
    </div>

    <div class="expense">
        <div class="inex-heading left">Expenses</div>
        <div class="inex-number little-right-2">-1,000</div>
        <div class="ex-percent right percent-main">28%</div>
    </div>
    
    
</div>
   <hr> 
<div class="selections">

    <select class="drop-down add-type">
        <option value="inc" selected>+</option>
        <option value="exp">-</option>
    </select>

    <input type="text" class="drop-down add-description" placeholder="Add Description">
    <input type="number" class="drop-down add-value" placeholder="Value">
    <button id="button"><i class="ion-ios-checkmark-outline ok-btn"></i></button>
</div>

   <hr>

<div class="wrapper line">

    <div class="income-down">
        <h2 class="in">INCOME</h2>

    <!--
    <div class="income-list">
        <div class="allinc" id="income-0">
            <div class="add-income inc-left">salary</div>
            <div class="income-amt inc-amt">+2,000</div>
            <button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
        </div>
 
        <div class="allinc" id="income-1">
            <div class="add-income inc-left">sold car</div>
            <div class="income-amt inc-amt">+1,500</div>
            <button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
        </div>
    </div>
    -->
    </div>
    

    <div class="expense-down">
        <h2 class="ex">EXPENSES</h2>

    <!--
    <div class="expense-list">
        <div class="allexp" id="expense-0">
            <div class="add-expense exp-left">rent</div>
            <div class="expense-amt exp-amt">-900</div>
            <button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
        </div>
        
        <div class="allexp" id="expense-1">
            <div class="add-expense exp-left">grocery</div>
            <div class="expense-amt exp-amt">-100</div>
            <button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
        </div>
    </div>
    -->
    </div>
    
</div>


<script src="script.js"></script>
</body>
</html>

JavaScript 代码——

//BUDGET CONTROLLER

var budgetController = (function(){

    var Expense = function(id, description, value){
        this.id = id;
        this.decription = description;
        this.value = value;
    };

    var Income = function(id, description, value){
        this.id = id;
        this.decription = description;
        this.value = value;
    };

    var data = {
        allItems : {
            exp: [],
            inc: []
        },

        total : {
            exp: 0,
            inc: 0
        }
    };
 
    return {
        addItems: function(type, des, val){
            var newItem, ID;

            if(data.allItems[type].length > 0){
                ID = data.allItems[type][data.allItems[type].length - 1].id + 1;
            }else {
                ID = 0;
            }
            
            
            if(type === 'exp'){
                newItem = new Expense(ID, des, val);
            }else if(type === 'inc'){
                newItem = new Income(ID, des, val);
            }
        
        data.allItems[type].push(newItem);
        return newItem;
        },
        
        //testing purpose
        testing: function(){
            console.log(data);
        }
    };

})();


//UI CONTROLLER

var UIController = (function(){

    var DOMstrings = {
        inputType: '.add-type',
        inputDescription: '.add-description',
        inputValue: '.add-value',
        inputButton: 'button',
        incomeContainer: '.income-list',
        expensesContainer: '.expense-list',
    };

    return {

        getInput: function(){
            return{
                type: document.querySelector(DOMstrings.inputType).value, // inc or exp
                decription: document.querySelector(DOMstrings.inputDescription).value,
                value: document.querySelector(DOMstrings.inputValue).value
            };
        },

        addListitem: function(obj, type){
            var html, newHtml, element;
            
            //create HTML string with placeholder text

            if(type === 'inc'){

                element = DOMstrings.incomeContainer;

                html = '<div class="allinc" id="income-%id%"><div class="add-income inc-left">%description%</div><div class="income-amt inc-amt">%value%</div><button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button></div>';
            }else if(type === 'exp'){

                element = DOMstrings.expensesContainer;

                '<div class="allexp" id="expense-%id%"><div class="add-expense exp-left">%description%</div><div class="expense-amt exp-amt">%value%</div><button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button></div>';
            }
            
            //replace placeholder text with some actual data  
            
            newHtml = html.replace('%id%', obj.id);
            newHtml = newHtml.replace('%description%', obj.decription);
            newHtml = newHtml.replace('%value%', obj.value);

            //insert the HTML into DOM

            document.querySelector(element).insertAdjacentHTML('beforeend', newHtml);

        },

        getDOMstrings: function(){
            return DOMstrings;
        }
    };
})();


//CONTROLLER

var controller = (function(budgetCtrl, UICtrl){

    var setupEventListeners = function(){

        var DOM = UICtrl.getDOMstrings();

        document.getElementById(DOM.inputButton).addEventListener('click', ctrlAddItem);
        document.addEventListener('keypress', function(event){
        
            if(event.keyCode === 13 || event.which === 13){
            ctrlAddItem();
        }
      });
    };

        var ctrlAddItem = function(){
            var input, newItem;

        //get the field input data
            input = UICtrl.getInput();

        //add the item to the budget controller
            newItem = budgetCtrl.addItems(input.type, input.description, input.value);

        //add the item to UI
            UICtrl.addListitem(newItem, input.type);

        //calculate the budget

        //display budget on UI

        };

        return {

            init: function(){

                //testing purpose
                console.log('hello');
                setupEventListeners();
            }
        };
})(budgetController,UIController);

controller.init();

标签: javascripthtmldom

解决方案


非常简单的解决方案。您将元素定义为“收入列表”,然后将 HTML 与其相邻:

if(type === 'inc'){

    element = DOMstrings.incomeContainer;
...

}else if(type === 'exp'){

    element = DOMstrings.expensesContainer;

...

document.querySelector(element).insertAdjacentHTML('beforeend', newHtml);

这很好..但是看看你的HTML。收入列表被禁用:

 <!--
    <div class="income-list">
        <div class="allinc" id="income-0">
            <div class="add-income inc-left">salary</div>
            <div class="income-amt inc-amt">+2,000</div>
            <button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
        </div>
 
        <div class="allinc" id="income-1">
            <div class="add-income inc-left">sold car</div>
            <div class="income-amt inc-amt">+1,500</div>
            <button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
        </div>
    </div>
    -->

你应该做的是从 js 文件中删除你想要实现 HTML 的元素的 HTML 周围。

您还需要对 HTML 中的“.expense-list”执行相同的操作

它来自 udemy 的 Jonas Schmedtmann 课程。非常好的课程。我也拿了。我可以建议您注意细节并与他一起一步一步编写代码。祝你好运。


推荐阅读