diff --git a/Hide sticky elements.user.js b/Hide sticky elements.user.js index db48952..23e1f64 100644 --- a/Hide sticky elements.user.js +++ b/Hide sticky elements.user.js @@ -4,7 +4,8 @@ // @match http*://*/* // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand -// @version 1.0.0 +// @grant GM_addStyle +// @version 1.1.0 // @author blankie // @description Adds a button to the monkey menu to hide sticky elements // @inject-into content @@ -12,29 +13,65 @@ "use strict"; -let stickyElements = []; +let stickyElements = new Set(); +let style = null; +let observer = new MutationObserver(function(mutations) { + for (let mutation of mutations) { + handleOneNode(mutation.target); + for (let node of mutation.addedNodes) { + handleNode(node); + } + for (let node of mutation.removedNodes) { + handleNode(node, true); + } + } +}); + let hideStickyElements = true; let menuId; -function hideAllStickyElements() { - for (let element of document.body.querySelectorAll("*")) { - let style = getComputedStyle(element); - if (style.position !== "sticky" && style.position !== "fixed") { - continue; - } +function handleOneNode(node, removed = false) { + if (node.nodeType !== Node.ELEMENT_NODE) { + return; + } - let originalDisplayValue = element.style.getPropertyValue("display"); - let originalDisplayPriority = element.style.getPropertyPriority("display"); - element.style.setProperty("display", "none", "important"); - stickyElements.push([element, originalDisplayValue, originalDisplayPriority]); + let computedStyle = getComputedStyle(node); + let isSticky = computedStyle.position === "sticky" || computedStyle.position === "fixed"; + if (!stickyElements.has(node) && isSticky && !removed) { + node.classList.add("hseSticky"); + stickyElements.add(node); + } else if (stickyElements.has(node) && (!isSticky || removed)) { + node.classList.remove("hseSticky"); + stickyElements.delete(node); } } -function unhideAllStickyElements() { - for (let [element, originalDisplayValue, originalDisplayPriority] of stickyElements) { - element.style.setProperty("display", originalDisplayValue, originalDisplayPriority); +function handleNode(node, removed = false) { + if (node.nodeType !== Node.ELEMENT_NODE) { + return; } - stickyElements = []; + + handleOneNode(node, removed); + for (let element of node.querySelectorAll("*")) { + handleOneNode(element, removed); + } +} + +function hideAllStickyElements() { + style = GM_addStyle(".hseSticky { display: none !important; }"); + handleNode(document.body); + observer.observe(document.body, {subtree: true, childList: true, attributes: true}); +} + +function unhideAllStickyElements() { + observer.disconnect(); + style.remove(); + style = null; + + for (let element of stickyElements) { + element.classList.remove("hseSticky"); + } + stickyElements.clear(); }