JS 實作 #6 | 清除已新增資料的欄位;querySelectorAll()、Array.prototype.slice.call()、forEach()、focus()

在上一節 JS 實作 #5 | 將新增資料顯示在 UI 上;insertAdjacentHTML() 中,已完成新增資料且顯示在 UI 上(insertAdjacentHTML()),接著需要將欄位資料清除。

開始實作

1. 在 UI Controller 裡新增一個公開方法 clearFields() 並且在 Global App Controller 裡呼叫它,同時使用 querySelectorAll() 來獲取 NodeList

// UI CONTROLLER
var UIController = (function() {

    var DOMstrings = {
        inputType: '.add__type',
        inputDescription: '.add__description',
        inputValue: '.add__value',
        inputBtn: '.add__btn',
        incomeContainer: '.income__list',
        expenseContainer: '.expenses__list'
    };

    return {
        getInput: function() {
            ...
        },
        getDOMstrings: function() {
            return DOMstrings;
        },
        addListItem: function(obj, type) {
            ...
        },
        **clearFields: function () {
            var fields;

            fields = document.querySelectorAll(DOMstrings.inputDescription + ', ' + DOMstrings.inputValue);
        }**
    };

})();
// GLOBAL APP CONTROLLER
var controller = (function(budgetCtrl, UICtrl){

    var setupEventListeners = function() {
				...
    };

    var ctrlAddItem = function() {

        var input,newItem;

        // 1. Get the field input data
        input = UICtrl.getInput();
        // 2. add the item to the budget controller
        newItem = budgetController.addItem(input.type, input.description, input.value);
        // 3. add the item to the UI
        UICtrl.addListItem(newItem, input.type);
        **UICtrl.clearFields();**
        // 4. Calculate the budget
        // 5. Display the budget on the UI
    }
    
    return {
        init: function() {
            console.log('Application has started.');
            setupEventListeners();
        }
    }
})(budgetController, UIController);

controller.init();

2. Array.prototype.slice.call():獲得的 NodeList 是一種物件而不是 Array,因此我們將它透過這個方法來做轉換,NodeList → Array。

這裡的訣竅是,在一般情況下,slice 用做 array 的切割,切割後會回傳一個 array。

而 NodeList 本身不是 Array 沒有 slice 方法可以用。

所以使用了 call() 來借用 Array 的此方法。也就是透過 **Array.prototype.slice.call(NodeList)** 可以得到一個 Array,且裡面的元素仍然指向 DOM。

// UI CONTROLLER
var UIController = (function() {

    var DOMstrings = {
        inputType: '.add__type',
        inputDescription: '.add__description',
        inputValue: '.add__value',
        inputBtn: '.add__btn',
        incomeContainer: '.income__list',
        expenseContainer: '.expenses__list'
    };

    return {
        getInput: function() {
            ...
        },
        getDOMstrings: function() {
            return DOMstrings;
        },
        addListItem: function(obj, type) {
            ...
        },
        clearFields: function () {
            var fields, **fieldsArr**;

            fields = document.querySelectorAll(DOMstrings.inputDescription + ', ' + DOMstrings.inputValue);
						// fiedls.slice 無法使用
            **fieldsArr = Array.prototype.slice.call(fields);**

        }
    };

})();

更多參考:

3. 使用 forEach() 遍歷 array 清除值,最後 focus() 在說明的 input 欄位

// UI CONTROLLER
var UIController = (function() {

    var DOMstrings = {
        inputType: '.add__type',
        inputDescription: '.add__description',
        inputValue: '.add__value',
        inputBtn: '.add__btn',
        incomeContainer: '.income__list',
        expenseContainer: '.expenses__list'
    };

    return {
        getInput: function() {
            ...
        },
        getDOMstrings: function() {
            return DOMstrings;
        },
        addListItem: function(obj, type) {
						...
        },
        clearFields: function () {
            var fields, fieldsArr;

            fields = document.querySelectorAll(DOMstrings.inputDescription + ', ' + DOMstrings.inputValue);
            fieldsArr = Array.prototype.slice.call(fields);

            **fieldsArr.forEach(function(current, index, originalArray){**
                **current.value = "";**
            **});**

            **fieldsArr[0].focus();**
        }
    };

})();

Zeen is a next generation WordPress theme. It’s powerful, beautifully designed and comes with everything you need to engage your visitors and increase conversions.