【问题标题】:My userscript only works when the page is refreshed or on iframes, not the main page?我的用户脚本仅在页面刷新或 iframe 上有效,而不是主页?
【发布时间】:2017-06-13 16:39:07
【问题描述】:

这个简单的代码不适用于 Facebook 页面。此代码仅在我刷新 the page 时发出警报。如果我用鼠标从my Facebook profile 转到那个页面;脚本停止工作。

没有警报或错误。 :(
在我刷新之前,整个脚本似乎都无法运行。

// ==UserScript==
// @name Purge My Facebook
// @namespace http://www.arda.com
// @description test
// @include https://*.facebook.com*
// @include http://*.facebook.com*
// @version 1
// ==/UserScript==
window.setTimeout (isParent, 500);

function isParent () {

    if (window.self == window.top) {
        alert ("main window");
    } else
        window.setTimeout (isParent, 500);
}

我也试过这个,除其他外:

// ==UserScript==
// @name        Purge My Facebook
// @namespace   http://www.arda.com
// @description test
// @include     http://www.facebook.com/*/allactivity*
// @include     https://www.facebook.com/*/allactivity*
// @version     1
// ==/UserScript==

try{
  if (window.self == window.top)
    alert(document.domain+"\nmain window");
  else
    alert(document.domain+"\nin a iframe");
}
catch(e){
  alert(document.domain+"\nHad a problem:\n"+e);
}

【问题讨论】:

  • 这会在主窗口中引发警报,没问题。它不会在 iframe 上触发,因为 @include 指令未涵盖它们。链接setTimeout 只会导致浏览器在 iframe 上冻结/崩溃。不要那样做! 究竟是什么,这个脚本在“主窗口”中不起作用吗?
  • 不......它在主窗口上不起作用。这是我的测试脚本..我在 userscripts.org 上阅读了你所有的答案和论坛..我现在正在拉扯我的头发。
  • 我测试过;它确实适用于主窗口。你叫什么主窗口?给出:(1) 准确的测试 URL,(2) 预期行为,(3) 实际行为。
  • 我刚开始写我的代码,当它失败时我删除了所有代码并今天开始新的..我将在活动日志部分运行这个脚本但是如果我用鼠标点击它不会工作..如果我在地址栏输入地址或者如果我刷新该页面,它就可以工作。我只是想从主窗口中获取元素
  • 不,您的两个脚本都在主框架上 100% 工作。您所描述的是 AJAX 问题,而不是 iframe 问题,waitForKeyElements 绝对可以解决这个问题。 提供我之前要求的那 3 个项目! 它们也是问题从一开始就应该包含的内容。

标签: javascript ajax facebook userscripts


【解决方案1】:

问题是 AJAX 问题。当您键入 URL 或刷新页面时,您的脚本将起作用。当您单击“活动日志”按钮时,脚本不会。 iframe 不是您报告的症状的一个因素。

这是因为单击该链接永远不会加载新页面;它会触发替换部分内容的 AJAX 调用,使其看起来像一个新页面,但实际上并非如此。

因此,如果您希望脚本在“新”“主页”上触发,则必须使用 this answer 中的技术。

在 Facebook 的情况下,通常唯一会发生变化的是报告的 URL(但不会触发 hashchange!),以及 #mainContainer div 的内容。

您还必须 @include 所有 FB 页面,因为像 https://www.facebook.com/*/allactivity* 这样的页面通常只能通过 AJAX 访问,因此您的脚本需要在上一个页面上运行。

此脚本将解决您的问题中提出的问题:

// ==UserScript==
// @name        Purge My Facebook
// @namespace   http://www.ardaterekeci.com
// @description test
// @include     http://www.facebook.com/*
// @include     https://www.facebook.com/*
// @version     1
// ==/UserScript==

var pageURLCheckTimer = setInterval (
    function () {
        if (    this.lastPathStr  !== location.pathname
            ||  this.lastQueryStr !== location.search
            ||  this.lastPathStr   === null
            ||  this.lastQueryStr  === null
        ) {
            this.lastPathStr  = location.pathname;
            this.lastQueryStr = location.search;
            gmMain ();
        }
    }
    , 222
);

function gmMain () {
    if (window.self === window.top)
        alert ('"New" main (top) page loaded.');
    else
        alert ('"New" iframed page loaded.');
}


但是,由于页面大量使用 AJAX,您会发现在页面首次加载时触发几乎总是为时过早。

明智的做法是在您真正关心的页面的特定部分使用waitForKeyElements(问题中没有说明。 )

Here's an example of using waitForKeyElements. 请注意,要在 Chrome 中使用 @require,您必须使用 Tampermonkey(无论如何您都应该这样做)。

【讨论】:

    猜你喜欢
    • 2016-11-02
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 2014-03-23
    • 2013-02-10
    • 1970-01-01
    • 2012-10-07
    相关资源
    最近更新 更多