JQuery加载/获取执行脚本

时间:2012-11-13 06:31:14

标签: javascript jquery userscripts

我正在试图“劫持”网站的ui。

目标:我不想在标签页或窗口中打开网页链接,而是想在主页上的网格中打开它们。我可能会使用像gridster这样的东西。基本上我会为每个网格元素放一个网页。

以下代码演示了我正在尝试做的事情。对于stackoverflow,它将主页包装在由角落中的小“按钮”控制的可隐藏div中。单击链接将在同一窗口中打开它。要返回“主页”,只需再次单击该按钮即可。

效果与标签非常相似,但目标是让标签更多标签免费,并允许更好的组织。可以有多个“按钮”以允许所有在同一“页面”上的多个链接。 (考虑它的一种方法是一种迷你标签功能,您可以通过非常小的按钮访问标签)。

我希望每页显示多个元素。以下代码仅显示一个问题。

在任何情况下,真正的问题不是布局,而是jquery.load不执行脚本。这是一个主要问题,因为某些网页根本不起作用。由于这些脚本被注入域中,因此不存在跨域问题。问题是脚本未执行或未正确执行。我花了最后8个小时尝试各种方法,但没有工作。

此代码的目标是采用像youtube(或堆栈交换)之类的东西,并将链接合并到单个页面(如果需要)。想一想通过在网格布局中的同一页面上显示多个视频(没有所有额外信息可见)来浏览YouTube视频的功能。并非一个人想要一次观看10个视频,但它比打开10个标签更有效。

考虑它的另一种方法是,如果你必须在站点之间翻转,你可以轻松地将一个站点加载到一个网格元素中,而将另一个站点加载到另一个网格元素中。

甚至可以使用非常简单的导航类型界面轻松地“滚动”网站。想想一个有很多帖子的论坛。您无需阅读长列表,您可以设计一个界面,只需使用左右按钮一次一个地显示帖子,即可在帖子中移动。 (显然这些方法需要对每个站点进行特定编码,但是大部分代码都会重叠。以下代码几乎可以在任何站点上使用(至少不使用绝对选择器的站点)并且可以轻松访问“主页”只需单击按钮即可)

如果它不能用于包含脚本的页面,那么至少对我来说,它的用处非常有限。我无法理解为什么它不起作用。沙盒iframe应该可以工作但与jquery.load / get具有相同的问题。我在使用getscript加载html后尝试执行每个脚本都无济于事。

// ==UserScript==
// @name        Stackanator
// @namespace   http://userscripts.org/
// @version     1.0
// @require     https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js
// @include     http://stackoverflow.com/
// ==/UserScript==
var $ = unsafeWindow.jQuery;


// Wrap main div with a div and style it to be floating
$('body').wrap('<div id="CBP" />');
$('<div id="CBPA"></div>').insertBefore($('#CBP'));
$('#CBP').css({'position': 'absolute', 'top': '0px', 'left': '0px', 'width' : '100%', 'height' : '100%', 'z-index': '9999', 'background-color': 'white'});

// Create a small toggle box to show and hide the main div 
$('#CBPA').attr('style', 'margin:0px;padding:0px;height:10px;width:10px;background-color:green;position:fixed;display:block;left:0px;right:0px;float:left;z-index:30000;');

// Setup toggle button
toggleCBPAs = false;
toggleCBPA = false;
$('#CBPA').click(function() {
    if (toggleCBPAs == false) return;
    if (toggleCBPA == true)
    {
        toggleCBPA = false;
        $(this).css('background-color', 'red');
        $('#CBP').css('visibility', 'visible');
    } else
    {
        toggleCBPA = true;
        $(this).css('background-color', 'green');
        $('#CBP').css('visibility', 'hidden');
    }
});

// Take over click's
$('body A').live('click', function() { 
        toggleCBPAs = true;
        var url = $(this).attr("href");         
        name = url.split("/"); 
        debugger;
        //var p = $('<iframe id="CBF" src="'+$(this).attr("href")+'" sandbox="allow-forms allow-same-origin allow-scripts"></iframe>').insertAfter($('#CBP'));

        $('<div id="CBG"></div>').insertAfter($('#CBP'));
        $("#CBG").load(url);

        toggleCBPA = true;
        $(this).css('background-color', 'green');
        $('#CBP').css('visibility', 'hidden');

        return false; 
});

1 个答案:

答案 0 :(得分:1)

首先,您无法将stackoverflow.com(以及几乎所有大型网站)放入<iframe>

所有主要网站都旨在防止被诬陷,以确保其网页不会用于欺诈目的。因此会有一些脚本来检测页面是否显示在一个框架中,如果是这样,它会做一些自杀工作,使页面消失。

其次,您无法使用$.load()将整个页面放入另一个div中。

尽管$.load()在每个块上显式eval()的方法可能会执行代码,但它可能会破坏事件处理程序和一些$(selector)引用。

某些事件(如onload)永远不会被触发,而某些$(selector)将是错误的(例如。$('#id')将在后面加载的元素与页面上已有的ID共享相同ID时失败。)

此外eval()使用与页面上运行的所有其他代码相同的代码上下文,它会同时相互冲突,因此不能将其视为任何方面的解决方案。

第三,您无法使用innerHTML替代$.load(),但DOM看起来不错

根据script tag create with innerHTML of a div doesn't workinnerHTML将不会执行脚本。我之前提供的可能的解决方案证明是不够的。

所以最后的答案是使用常用方法使用脚本是不可能完成的。

一些想法:

  1. 构建您自己的浏览器,即使在window.top === null
  2. 中也会声明<iframe>
  3. 管理编写一个非常智能的脚本,它将自动修改检索到的代码(html,js,css),使其与当前页面冲突,然后将页面嵌入<div>
  4. 管理一种检测防止被删除的代码的方法,并将其删除。然后将处理过的代码放在空<iframe>