如何从Greasemonkey调用此YouTube功能? [英] How to call this YouTube function from Greasemonkey?

查看:100
本文介绍了如何从Greasemonkey调用此YouTube功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Greasemonkey显示带有观看视频时间的提醒。

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.

你能帮帮我吗?谢谢!

推荐答案

由于各种安全和范围问题,您无法运行 ytplayer.getCurrentTime()来自Greasemonkey脚本范围的

Due to various security and scoping issues, you cannot run ytplayer.getCurrentTime() from the Greasemonkey script scope.

同样,单击事件处理程序必须在目标页面的范围内运行才能访问该函数。尝试不这样做会产生 undefined 组合错误:坏NPObject作为私人数据!

Likewise, the click event handler must run in the target page's scope to access that function. Attempts to do otherwise will yield combinations of undefined and Error: 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:


  1. Youtube和大多数Google网站大量使用< iframe> 秒。为避免多次执行脚本时出现问题,请使用 window.top === window.self 等检查,以确保脚本仅在框架中运行或包含您要定位的页面。

  2. 尽量避免使用 innerHTML 和内联样式。这将使代码更容易维护,在许多情况下更快,并且不太可能触发意外的副作用。

  1. Youtube, and most Google sites, make extensive use of <iframe>s. To avoid problems with multiple executions of your script, use checks like window.top === window.self to ensure that the script only runs in the frame(s) or containing page that you are targeting.
  2. Avoid using 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:

// ==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()等。这需要跨范围进行消息传递。 请参阅此答案 ,或在您到达该部分时打开一个新问题。


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.

这篇关于如何从Greasemonkey调用此YouTube功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆