Userscript doesnt work when injected but works when run in console

249 Views Asked by At

i am trying to make a userscript to add a download button to youtube, i tried tampermonkey and greasemonkey but they dont work. the script doesnt throw any errors when run manually on console. it adds the button when i copy and paste it into the console.

the userscript:

// ==UserScript==
// @name         Youtube Downloader
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Download Youtube Videos With One Click!
// @author       qweren
// @match        https://www.youtube.com/*
// @icon         https://upload.wikimedia.org/wikipedia/commons/thumb/0/09/YouTube_full-color_icon_%282017%29.svg/1024px-YouTube_full-color_icon_%282017%29.svg.png
// ==/UserScript==

(function() {
    'use strict';

    // Check if the "actions" div exists
    var actionsDiv = document.getElementById('actions');
        // Create a new button element
    var newButton = document.createElement('button');
    newButton.textContent = 'Click Me';

    // Add an event listener to the button
    newButton.addEventListener('click', function() {
        alert('Button clicked!');
    });

    // Append the button to the "actions" div
    actionsDiv.appendChild(newButton);
    console.log("adding button")
})();

i tried changing the userscript extension from greasemonkey to tampermonkey both dont work. i tried to write an onload for actionsdiv it doesnt work too.

1

There are 1 best solutions below

0
cssyphus On

wOxxOm is correct about the need to wait for elements to appear on modern websites, but there are options.

Although MutationObserver is definitely the correct way to wait for elements to appear before continuing your code, there are simpler methods - such as a simple setTimeout() (as demonstrated - unnecessarily! - below) or using a Promise-driven sleep() function.

However, for your test case there is no need of any of these. Even the setTimeout in the below script is not necessary - the script will work without it.

Try this method:

// ==UserScript==
// @name         Youtube Downloader
// @namespace    ErensScripts
// @version      0.1
// @description  Download Youtube Videos With One Click!
// @author       qweren
// @match        https://www.youtube.com/*
// ==/UserScript==

(function() {
    'use strict';

    const $ = document.querySelector.bind(document);
    $('body').insertAdjacentHTML('beforeend', init() );

    setTimeout( () => {
        //Give time for element to appear in DOM...
        $('#myButt').addEventListener('click', () => { 
            alert('Thanks!');
        });
    },100);


})();
function init(){
    return `
    <button id='myButt' class="myfix">Scratch Me</button>
    <style>
        .myfix{position:fixed;top:0;right:10%;}
        #myButt{font-size:5rem;color:yellow;background:firebrick; z-index:99999;}
    </style>
    `;
}