Search code examples
javascripttampermonkeygreasemonkey-4

Greasemonkey Script Failing To Remove Element


A lot of this script is basically cut and paste from other people's scripts that are working for them, but I'm having a strange issue with either .remove or .removeChild failing to run. The script crashes out the userscript engine at this point.

// ==UserScript==
// @name     Strip Gocomics Sidebar
// @version  1
// @grant    none
// @include  https://www.gocomics.com/*
// ==/UserScript==

window.addEventListener('load', setkillsidebar);

function setkillsidebar() {
  var interval = Math.random() * 5000 + 1000;
  setTimeout(killsidebar, interval);
}

function killsidebar() {
  console.log("Start Session");
  // const adSidebar = document.querySelectorAll('.gc-container-fluid .layout-2col-sidebar, .gc-page-header--hero .layout-2col-sidebar');
  var adSidebar = document.getElementsByClassName('.gc-container-fluid .layout-2col-sidebar, .gc-page-header--hero .layout-2col-sidebar');
  console.log("Got Elements " + adSidebar.length );
  if (adSidebar) {
    console.log("Found SideBar");
    var myParent = adSidebar.parentNode;
    console.log("Made Parent");
    // myParent.remove();
    adSidebar.parentNode.removeChild(adSidebar);
    console.log("Stripped SideBar");
    var interval = Math.random() * 5000 + 1000;
    console.log("Timer Time " + interval );
    setTimeout(killsidebar, interval);
    console.log("Set Timer");
  }
}

So with the addition of the console.log items, I get the following in the Firefox's Web Console:

  • Start Session
  • Got Elements
  • Found SideBar
  • Made Parent

And that's a wrap, I have a death at either the .remove or the .removeChild so either I am not doing something correctly, or I am having an issue with a security setting that is preventing me from deleting elements from webpages that nobody has told me about.

And for more interesting information, although the title of this post is Greasemonkey, this fails with Tampermonkey as well.

P.S. This is being used in addition to some Stylish CSS that permits me to have a bigger comic view on a small monitor. Doesn't matter if Stylish is running or not.


Solution

  • There are many problems with that userscript, but they mostly boil down to: You need to note the error messages in the console and google the functions that are causing them.
    For example:

    • That's not how getElementsByClassName works.
    • querySelectorAll does not return a node.
    • parentNode and removeChild both act on a single node.

    Also: the second setTimeout does not appear to be needed. And the load event listener is also (probably) superfluous.

    Here is the script with those deficiencies corrected:

    // ==UserScript==
    // @name     Gocomics, Strip Sidebar
    // @match    https://www.gocomics.com/*
    // @version  2
    // @grant    none
    // ==/UserScript==
    
    var interval = Math.random () * 5000 + 1000;
    setTimeout (killsidebar, interval);
    
    function killsidebar () {
        //-- querySelector() and querySelectorAll () are not the same.
        var adSidebar = document.querySelector ('.gc-container-fluid .layout-2col-sidebar, .gc-page-header--hero .layout-2col-sidebar');
        if (adSidebar) {
            adSidebar.parentNode.removeChild (adSidebar);
        }
    }
    

    Although, this script will probably perform better:

    // ==UserScript==
    // @name     Gocomics, Strip Sidebar
    // @match    https://www.gocomics.com/*
    // @version  2
    // @require  https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
    // @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
    // @grant    GM_addStyle
    // @grant    GM.getValue
    // ==/UserScript==
    //- The @grant directives are needed to restore the proper sandbox.
    
    waitForKeyElements (
        ".gc-container-fluid .layout-2col-sidebar, .gc-page-header--hero .layout-2col-sidebar",
        removeNode
    );
    
    function removeNode (jNode) {
        jNode.remove ();
    }
    

    It uses waitForKeyElements -- which is faster and more robust that a straight setTimeout.