I'm trying to display an alert with the time watched of the video with Greasemonkey.
// ==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);
But this does not work.
Can you help me? Thank you!
Due to various security and scoping issues, you cannot run
ytplayer.getCurrentTime()
from the Greasemonkey script scope.Likewise, the
click
event handler must run in the target page's scope to access that function. Attempts to do otherwise will yield combinations ofundefined
andError: Bad NPObject as private data!
.This means that you must "Inject" the
click
handler for your time button.But first, here's a few more issues to consider:
<iframe>
s. To avoid problems with multiple executions of your script, use checks likewindow.top === window.self
to ensure that the script only runs in the frame(s) or containing page that you are targeting.innerHTML
and inline styles as much as possible. This will make the code easier to maintain, faster in many instances, and less likely to trigger unexpected side effects.Putting that all together, here is your complete script refactored:
Finally, from your script, it looks like you hope to eventually use
GM_setValue()
, etc., when clicking that button. That requires messaging across scopes. See this answer or open a new question when you get to that part.