Comment appeler cette fonction YouTube de Greasemonkey?

J'essaie d'afficher une alerte avec le temps surveillé de la vidéo avec Greasemonkey.

Mon script :

// ==UserScript== // @name Time YouTube // @description Does not work ! Help ! // @namespace time_youtube // @include *youtube.com/watch* // @grant GM_setValue // @icon http://aux3.iconpedia.net/uploads/520882026785186105.png // @version 1.3 // ==/UserScript== ytplayer = document.getElementById ("movie_player"); var time = document.createElement ('a'); time.innerHTML = '<a style="position: fixed; top: 200px; left: 3px; color:black;">Time</a>'; //time.addEventListener ('click', function(){GM_setValue('url_time',(document.location.href) + '&t=' + (ytplayer.getCurrentTime()));}, false); time.addEventListener ('click', function () { alert (ytplayer.getCurrentTime() ); }, false ); document.body.appendChild (time); 

Mais cela ne fonctionne pas.

Pouvez-vous m'aider? Je vous remercie!

En raison de divers problèmes de sécurité et de portée, vous ne pouvez pas exécuter ytplayer.getCurrentTime() partir de la portée du script Greasemonkey.

De même, le gestionnaire d'événement de click doit être exécuté dans la portée de la page cible pour accéder à cette fonction. Les tentatives de faire autrement produiront des combinaisons de undefined et Error: Bad NPObject as private data! .

Cela signifie que vous devez "Injecter" le gestionnaire de click pour votre bouton d'heure.
Mais d'abord, voici quelques autres questions à considérer:

  1. Youtube, et la plupart des sites Google, utilisent largement <iframe> s. Pour éviter les problèmes liés à plusieurs exécutions de votre script, utilisez des contrôles comme window.top === window.self pour vous assurer que le script ne s'exécute que dans la (les) image (s) ou contenant la page que vous ciblez.
  2. Évitez d'utiliser innerHTML et les styles en ligne autant que possible. Cela rendra le code plus facile à maintenir, plus rapidement dans de nombreux cas, et moins susceptibles de déclencher des effets secondaires inattendus.

En mettant tout cela ensemble, voici votre script complet refacturé:

 // ==UserScript== // @name Time YouTube // @description Does not work ! Help ! // @namespace time_youtube // @include *youtube.com/watch* // @icon http://aux3.iconpedia.net/uploads/520882026785186105.png // @grant GM_setValue // @grant GM_addStyle // @version 1.3 // ==/UserScript== //-- Only run in the top page, not the various iframes. if (window.top === window.self) { var timeBtn = document.createElement ('a'); timeBtn.id = "gmTimeBtn"; timeBtn.textContent = "Time"; //-- Button is styled using CSS, in GM_addStyle, below. document.body.appendChild (timeBtn); addJS_Node (null, null, activateTimeButton); } function activateTimeButton () { var timeBtn = document.getElementById ("gmTimeBtn"); if (timeBtn) { timeBtn.addEventListener ('click', function () { var ytplayer = document.getElementById ("movie_player"); //-- IMPORTANT: GM_functions will not work here. console.log ("getCurrentTime(): ", ytplayer.getCurrentTime() ); //alert (ytplayer.getCurrentTime() ); }, false ); } else { alert ("Time button not found!"); } } //-- Style and position our button the CSS way. GM_addStyle ( " \ #gmTimeBtn { \ position: fixed; \ top: 200px; \ left: 3px; \ color: black; \ margin: 0; \ padding: 0; \ } \ " ); //-- This is a standard-ish utility function... function addJS_Node (text, s_URL, funcToRun, runOnLoad) { var D = document; var scriptNode = D.createElement ('script'); if (runOnLoad) { scriptNode.addEventListener ("load", runOnLoad, false); } scriptNode.type = "text/javascript"; if (text) scriptNode.textContent = text; if (s_URL) scriptNode.src = s_URL; if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()'; var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement; targ.appendChild (scriptNode); } 

Enfin, à partir de votre script, il semble que vous espérez éventuellement utiliser GM_setValue() , etc., lorsque vous cliquez sur ce bouton. Cela nécessite des messagerie à travers les étendues. Consultez cette réponse ou ouvrez une nouvelle question lorsque vous parvenez à cette partie.