Greasemonkey脚本无法移除元素的问题求助
Let's break down why your script is crashing and fix it step by step:
1. Wrong Element Selection Method
You switched from querySelectorAll (which supports full CSS selectors) to getElementsByClassName—but this method only accepts a single class name, not a comma-separated CSS selector string. So your adSidebar variable ends up as an empty HTMLCollection, but since it’s still an object, the if (adSidebar) check passes anyway, leading to invalid operations later.
2. Trying to Access parentNode on a Collection
Even if you had matching elements, querySelectorAll/getElementsByClassName return a collection of elements, not a single element. You can’t call .parentNode on the entire collection—you need to loop through each element in the collection instead.
3. Incorrect Truthy Check
An empty HTMLCollection/NodeList is still a truthy value in JavaScript, so if (adSidebar) will always run, even when no elements are found. You need to check if the collection has elements with adSidebar.length > 0.
4. Simplify Element Removal
Modern browsers support the .remove() method directly on elements, which is cleaner than using parentNode.removeChild() and avoids issues if the parent node changes unexpectedly.
Fixed Script Code
// ==UserScript== // @name Strip Gocomics Sidebar // @version 1 // @grant none // @include https://www.gocomics.com/* // ==/UserScript== window.addEventListener('load', setkillsidebar); function setkillsidebar() { // Use a smaller interval for faster testing, adjust as needed const interval = Math.random() * 2000 + 500; setTimeout(killsidebar, interval); } function killsidebar() { console.log("Start Session"); // Use querySelectorAll with your original CSS selector const adSidebars = document.querySelectorAll('.gc-container-fluid .layout-2col-sidebar, .gc-page-header--hero .layout-2col-sidebar'); console.log("Got Elements: " + adSidebars.length ); if (adSidebars.length > 0) { console.log("Found SideBar(s)"); // Loop through each sidebar element and remove it adSidebars.forEach(sidebar => { sidebar.remove(); console.log("Stripped a SideBar"); }); } else { console.log("No sidebars found this run"); } // Optional: Only re-run the timer if you expect sidebars to re-appear dynamically const interval = Math.random() * 5000 + 1000; console.log("Timer Time: " + interval ); setTimeout(killsidebar, interval); console.log("Set Timer"); }
Key Changes Explained:
- Reverted to
querySelectorAllto support your multi-part CSS selector correctly. - Added a check for
adSidebars.length > 0to only run removal logic when elements exist. - Used
.forEach()to loop through each sidebar element and call.remove()on each one. - Cleaned up console logs to be more descriptive.
This should prevent the crash because we’re no longer trying to access parentNode on an empty collection, and we’re properly handling multiple elements if they exist.
内容的提问来源于stack exchange,提问作者Colin

