0

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.

Eren
  • 36
  • 6
  • frames? the console uses the frame where you inspected an element, while default monkeying around will use the main frame. – Dave S Aug 14 '23 at 19:56
  • i open the console with f12, i dont inspect any element. – Eren Aug 14 '23 at 19:58
  • Well is the script waiting for the page to be fully loaded before it runs? There is no onload event for a div.... – epascarello Aug 14 '23 at 19:58
  • default @run-at runs the script when DOMContentLoaded event is dispatched – Eren Aug 14 '23 at 20:00
  • 1
    YouTube is a modern site that constructs the page dynamically after your userscript has run. You can wait for the element by using MutationObserver. – wOxxOm Aug 14 '23 at 20:39

1 Answers1

0

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>
    `;
}
cssyphus
  • 37,875
  • 18
  • 96
  • 111