24

I need to hide a section from an html page:

<h1 data-ng-show="!menuPinned &amp;&amp; !isSaaS" class="logo floatLeft" aria-hidden="false"><span>XXX&nbsp;</span><span style="font-weight: bold;">XXX&nbsp;</span><span>XXXXX</span></h1>

The following code works fine in Chrome dev. tools

var ibmlogo = document.querySelectorAll('h1.logo.floatLeft');
ibmlogo[1].remove();

But when I load the page with the script active, the section (h1) won't disappear. I believe this is because when the script runs, the DOM has not been completed loaded yet, hence the script fails to find the selector.

I have tried many different things (e.g. window.onLoad) but still my script is not effective. Last attempt (failed) is the following:

var logo = document.querySelectorAll('h1.logo.floatLeft');
logo.onload = function() {removeLogo()};

function removeLogo(){
    console.log("### logo array lenght: " + logo.length);
    logo[1].remove();
};
funnydman
  • 9,083
  • 4
  • 40
  • 55
gxvigo
  • 787
  • 4
  • 10
  • 20
  • 3
    Wouldn't a user style (e.g. using [Stylish](https://chrome.google.com/webstore/detail/stylish/fjnbnpbmkenffdnngjfgmeleoegfcffe?hl=en)) with `h1.logo.floatLeft { display: none; }` do the trick? – hsan Sep 06 '16 at 10:36

1 Answers1

54

Required:

  • @run-at: document-start in userscript metablock.

    // ==UserScript==
    ..............
    // @run-at        document-start
    ..............
    // ==/UserScript==
    

Now with the above your options are:

  1. Simply inject a style that hides the logo:

    (document.head || document.documentElement).insertAdjacentHTML('beforeend',
        '<style>h1.logo.floatLeft { display: none!important; }</style>');
    
  2. Use MutationObserver to detect and delete the element immediately after it's added into DOM.

     

    new MutationObserver(function(mutations) {
        // check at least two H1 exist using the extremely fast getElementsByTagName
        // which is faster than enumerating all the added nodes in mutations
        if (document.getElementsByTagName('h1')[1]) {
            var ibmlogo = document.querySelectorAll('h1.logo.floatLeft')[1];
            if (ibmlogo) {
                ibmlogo.remove();
                this.disconnect(); // disconnect the observer
            }
        }
    }).observe(document, {childList: true, subtree: true});
    // the above observes added/removed nodes on all descendants recursively
    
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • Thanks @woxxom, the first option does the trick even if I don't quite understand how. When the script run my element doesn't exist (I tested with document.querySelectorAll, so how can the insertAdjacentHTML inject something in a non existing node? And if it's create a node, when the page eventually loads, it shouldn't override my injected element? – gxvigo Sep 06 '16 at 20:55
  • Hi couldn't make he second option (much fancier) working, in your code I get a syntax error in the second to last line (can't understand why). I then tried the sample from mozilla web site and the code fails because the target is not an Node, and checking it, when I create the target the element doesn't exist (I even tried with 'html') and target is always null. . Cheers – gxvigo Sep 06 '16 at 20:55
  • 2
    1. It's what CSS sheets are for 2. The code should work as-is, don't change `document` parameter in `observe`. Anyway, I'm not psychic, so I can't tell what happens in your browser – wOxxOm Sep 06 '16 at 21:05
  • it is not clear. wher to put my scripts? after document-start of before? – Amir Aug 24 '22 at 13:01
  • After `// ==/UserScript==`, on a new line. – wOxxOm Aug 24 '22 at 17:57
  • awesome. this allowed me to inject window.onbeforeprint function into gmail print view without needing to close & restart the print dialogue!! – pablorenato Sep 11 '22 at 11:03