Search code examples
javascriptfirefoxyoutubetampermonkeytogglebutton

Youtube toggle related section - Tampermonkey


I have modified an existing script to create a button for hide/show the related sidebar on youtube. The related section supposed to be hidden by default. Similarly like the FF add-on YT Clean.

The button works well if the 'related' block is visible by default (no button.click() in the code). Also works if I reload the ...watch page.

But if I am coming from the default youtube page or search results (click on a video to watch), I have to click on the button twice to hide the 'related' block.

I am really a beginner (I did not write this), so appreciate any help.

// ==UserScript==
// @name            Youtube - toggle related
// @namespace       -
// @version         1.0
// @match           https://www.youtube.com/*
// @grant           none
// @require         https://code.jquery.com/jquery-3.3.1.min.js
// @run-at          document-end
// @noframes
// ==/UserScript==

(function(){
  'use strict';
  console.log('X');
  let target = document.querySelectorAll('body')[0];
  let options = {'childList': true, 'subtree' : true};

  function callback(observer, node){
    if (node.nodeName.toLowerCase() == '#secondary-inner'){
      $('#secondary-inner').hide(); 
    }
  }

  let observer = new MutationObserver(function(mutations){
    mutations.forEach(function(mutation){
      if (mutation.type === 'childList'){
        mutation.addedNodes.forEach(function(node){
          callback(observer, node);
        });
      }
    });
  });

  let button = document.createElement('button');
      button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="48" height="24" viewBox="0 0 24 24"><g fill="currentColor"><path d="M4 14h4v-4H4v4zm0 5h4v-4H4v4zM4 9h4V5H4v4zm5 5h12v-4H9v4zm0 5h12v-4H9v4zM9 5v4h12V5H9z"/></g></svg>';
      button.style = `
                      background: transparent;
                      border: 0;
                      color: rgb(96,96,96);
                      cursor: pointer;
                      outline: 0;
      `;
  
  let hide = false;

    button.onclick = ()=>{
    hide = !hide;
    if (hide){
      if ($('#secondary-inner')[0]) 
        $('#secondary-inner').hide()
      else
        observer.observe(target, options);
      
      console.log(`hide`);
    }
    else{
      observer.disconnect();
      console.log(`show`);

      $('#secondary-inner').show();
    }
  }

  button.click();
  
  let menu = $('#end')[0];
      menu.insertBefore(button, menu.lastElementChild);

  console.log('inserted');

} )()


Solution

  • If you want to have the element hidden all the time by default without any buttons, you can do:

    // ==UserScript==
    // @name            Youtube - Hide Related Sidebar
    // @namespace       -
    // @version         1.0
    // @match           https://www.youtube.com/*
    // @grant           none
    // @require         https://code.jquery.com/jquery-3.6.0.min.js
    // @run-at          document-end
    // @noframes
    // ==/UserScript==
    
    (function(){
        'use strict';
    
        const callback = () => $('#secondary-inner').hide();
    
        const observer = new MutationObserver(function(mutations){
            mutations.forEach(function(mutation){
                if (mutation.type === 'childList'){
                    mutation.addedNodes.forEach(function(node){
                        callback();
                    });
                }
            });
        });
    
        observer.observe(document.body, {'childList': true, 'subtree' : true});
    })(
    

    )