2013-01-08 2 views
1

Я пытаюсь отобразить предупреждение с просмотренным временем видео с Greasemonkey.Как назвать эту функцию YouTube от Greasemonkey?

My 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); 


Но это не работает.

Вы можете мне помочь? Спасибо!

ответ

2

Из-за различных проблем безопасности и неопределенности вы не можете запустить ytplayer.getCurrentTime() из области сценария Greasemonkey.

Аналогично, для доступа к этой функции должен выполняться обработчик событий click в области целевой страницы. Попытки сделать иначе, получат комбинации undefined и Error: Bad NPObject as private data!.

Это означает, что вы должны «ввести» обработчик click для вашей кнопки времени.
Но первый, вот еще несколько вопросов, чтобы рассмотреть:

  1. Youtube, и большинство сайтов Google, широко использовать с. Чтобы избежать проблем с несколькими сценариями вашего сценария, используйте проверки, такие как window.top === window.self, чтобы убедиться, что сценарий работает только в кадре (-ах) или содержит страницу, на которую настроен таргетинг.
  2. Избегайте использования innerHTML и встроенных стилей в максимально возможной степени. Это упростит работу кода, быстрее во многих случаях и с меньшей вероятностью вызовет неожиданные побочные эффекты.

Собирает все вместе, вот ваш полного сценария переработан:

// ==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); 
} 

Наконец, из вашего сценария, похоже, вы надеетесь, в конечном счете использовать GM_setValue() и т.д., когда щелкнув эту кнопку. Для этого требуется обмен сообщениями по областям. См. this answer или откройте новый вопрос, когда вы доберетесь до этой части.

+0

Большое спасибо за ответ и объяснение. Действительно, я бы использовал 'GM_setValue()'. Итак, мне нужно открыть новый вопрос? Еще раз спасибо :-) – Romaric

+0

Добро пожаловать. Рад помочь. –

Смежные вопросы