javascriptdomdom-manipulationmutation-eventsdom-node

DOMNodeInserted and DOMNodeRemoved events


The code below is working fine, apart from the counter. When I add an item to the list, the counter is accurate, though when I remove an item from the list, it doesn't subtract one from the counter. Any ideas?

HTML

<nav>
    <div id ="counter">1</div>
        <ul id="list">
            <li class="test" id="liOne"><a href="#">test</a></li>
        </ul>
        <p id="contOne"></p>

        <a id="button" class="button btn" href="#">Add</a><br>
        <a id="button" class="button removeBtn" href="#">Remove</a>
</nav>

JavaScript

var elList, addLink, newEl, netText, counter, listItems, removeLink, removeEl;

elList = document.getElementById('list');
addLink = document.querySelector('.btn');
counter = document.getElementById('counter');
removeLink = document.querySelector('.removeBtn');

function addItem(e) {

if(e.preventDefault) {
    e.preventDefault();
} else {
    e.returnValue = false; //IE fallback code
}

newEl = document.createElement('li');
newText = document.createTextNode('New List Item');
newAnchor = document.createElement('a');
newAnchor.setAttribute('href', '#');
newAnchor.appendChild(newText);
newEl.appendChild(newAnchor);
elList.appendChild(newEl);

}   

function removeItem(e) {

if(e.preventDefault) {
    e.preventDefault();
} else {
    e.returnValue = false; //IE fallback code
}

var removeEl = document.querySelector('li');
var containEl = removeEl.parentNode;

containEl.removeChild(removeEl);

}

function updateCount() {                                 // Declare function
listItems = elList.getElementsByTagName('li').length;  // Get total of <li>s
counter.innerHTML = listItems;                         // Update counter
}

 removeLink.addEventListener('click', removeItem, false);
 addLink.addEventListener('click', addItem, false);
 elList.addEventListener('DOMNodeInserted', updateCount, false); // DOM                 updated. fires when a node is inserted into dom tree
 elList.addEventListener('DOMNodeRemoved', updateCount, false);

Solution

  • The problem is that the updateCount() function runs faster than the removeItem() function (before item is removed). I'd suggest:

    Remove following lines:

    elList.addEventListener('DOMNodeInserted', updateCount, false);
    elList.addEventListener('DOMNodeRemoved', updateCount, false);
    

    And call your updateCount() a the end of your addItem and removeItem methods as follows:

    function removeItem(e) {
    
        /* Your code here*/
    
        updateCount();
    }
    

    EDIT: See working JSFiddle example