function cardsEqual(a, b) { return a.getAttribute('data-color') === b.getAttribute('data-color') && a.getAttribute('data-shape') === b.getAttribute('data-shape') && a.getAttribute('data-count') === b.getAttribute('data-count') && a.getAttribute('data-infill') === b.getAttribute('data-infill'); } function replaceCard(a, b) { a.innerHTML = b.innerHTML; a.setAttribute('data-color', b.getAttribute('data-color')); a.setAttribute('data-shape', b.getAttribute('data-shape')); a.setAttribute('data-count', b.getAttribute('data-count')); a.setAttribute('data-infill', b.getAttribute('data-infill')); } function markNewCard(card) { card.classList.add('new'); setTimeout(() => { card.classList.remove('new'); }, 3000); } function update() { var req = new XMLHttpRequest(); req.addEventListener('load', (ev) => { var parser = new DOMParser(); var doc = parser.parseFromString(req.responseText, 'text/html'); // Replace playing field cards var field = document.getElementById('playingfield'); var aNodes = Array.from(field.children); var bNodes = Array.from(doc.getElementById('playingfield').children); for (var i = 0; i < Math.min(aNodes.length, bNodes.length); ++i) { if (!cardsEqual(aNodes[i], bNodes[i])) { replaceCard(aNodes[i], bNodes[i]); markNewCard(aNodes[i]); } } if (bNodes.length < aNodes.length) { for (var i = bNodes.length; i < aNodes.length; ++i) { aNodes[i].remove(); } } if (bNodes.length > aNodes.length) { for (var i = aNodes.length; i < bNodes.length; ++i) { field.appendChild(bNodes[i]); markNewCard(bNodes[i]); } } // Replace gamestats and scores document.getElementById('gamestats').innerHTML = doc.getElementById('gamestats').innerHTML; document.getElementById('scorelist').innerHTML = doc.getElementById('scorelist').innerHTML; }); req.open('GET', window.location.href); req.send(); } setInterval(update, 500);