29

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();
};
1
  • 3
    Wouldn't a user style (e.g. using Stylish) with h1.logo.floatLeft { display: none; } do the trick? Commented Sep 6, 2016 at 10:36

2 Answers 2

66

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
    
Sign up to request clarification or add additional context in comments.

6 Comments

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?
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
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
it is not clear. wher to put my scripts? after document-start of before?
After // ==/UserScript==, on a new line.
|
0

In my case I had to modify some inline JSON. MutationObserver did not work but simply overriding JSON.parse() did the trick.

var oldJsonParse = JSON.parse;
JSON.parse = function(content) {
    if (content.includes("someProp")) {
        var jsonContent = oldJsonParse(content);
        jsonContent.someProp = 2;
        return jsonContent;
    } else {
        return oldJsonParse(content);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.