// under the mouse right now (if any) let currentElem = null; table.onmouseover = function(event) { // before entering a new element, the mouse always leaves the previous one // if currentElem is set, we didn't leave the previous , // that's a mouseover inside it, ignore the event if (currentElem) return; let target = event.target.closest('td'); // we moved not into a - ignore if (!target) return; // moved into , but outside of our table (possible in case of nested tables) // ignore if (!table.contains(target)) return; // hooray! we entered a new currentElem = target; target.style.background = 'pink'; }; table.onmouseout = function(event) { // if we're outside of any now, then ignore the event // that's probably a move inside the table, but out of , // e.g. from to another if (!currentElem) return; // we're leaving the element – where to? Maybe to a descendant? let relatedTarget = event.relatedTarget; while (relatedTarget) { // go up the parent chain and check – if we're still inside currentElem // then that's an internal transition – ignore it if (relatedTarget == currentElem) return; relatedTarget = relatedTarget.parentNode; } // we left the . really. currentElem.style.background = ''; currentElem = null; };