2011-10-26 40 views
0

我写了一个GreaseMonkey脚本来为blogger.com的HTML视图添加一个按钮。我有警报到处,所以我知道一切都在运行。脚本触发但没有结果

奇怪的是,它发射两次,每次都略有不同。 当我导航到blogger.com帖子编辑时,脚本首先在黑色页面上触发,并以正确的顺序(包括“内部”顺序)遍历所有警报。

在页面加载后的第二次运行中,除“内部”之外的每个警报都会运行并且不会产生错误。

// ==UserScript== 
// @name Blogger: Remove HTML Space 
// @include http://www.blogger.com/blogger.g?blogID*editor/target*\ 
// ==/UserScript= 

function contentEval(source) { 
    // Check for function input. 
    alert("asdas"); 
    if ('function' == typeof source) { 
    // Execute this function with no arguments, by adding parentheses. 
    // One set around the function, required for valid syntax, and a 
    // second empty set calls the surrounded function. 
    source = '(' + source + ')();' 
    } 

    alert("asdas2"); 
    // Create a script node holding this source code. 
    var script = document.createElement('script'); 
    alert("asdas3"); 
    script.setAttribute("type", "application/javascript"); 
    alert("asdas4"); 
    script.textContent = source; 
    alert("asdas5"); 

    // Insert the script node into the page, so it will run, and immediately 
    // remove it to clean up. 
    alert("asdas6"); 
    document.body.appendChild(script); 
    alert("asdas7"); 
} 

    alert("test") 
    contentEval(function(){ alert("inside"); document.getElementById("postingHtmlToolbar").firstChild.innerHTML += '<div id="SP" class="goog-inline-block goog-toolbar-button" title="SP" role="button" style="-moz-user-select: none;"><div class="goog-inline-block goog-toolbar-button-outer-box"><div class="goog-inline-block goog-toolbar-button-inner-box"><button type="button" onclick="document.getElementById(\'postingHtmlBox\').value = document.getElementById(\'postingHtmlBox\').value.replace(/&amp;nbsp;/g, \' \');"><b>SP</b></button></div></div></div>'}); 

alert("testw"); 

blogger.com是否有反脚本注入的东西?

回答

1

关于射击两次:

如果页面包含 S,userscript将在他们每个人的火。

您需要确定您是否在之内。最简单的方式火只在主网页,而不是内部框架,是包装所有代码:

if(top==self) 
{ 
    ... 
} 

要查看是否有在页面是<iframe>s(以HTML或者硬编码或动态生成的),我一直用的AdBlock Plus(“打开可锁定项目”对话框)。

但我不确定为什么第二个“内部”警报不会启动。我创建了一个简单的HTML页面,包含,我得到两个警报。

关于脚本一般:

你在这里做重复工作。您不必包装所有内容来执行脚本。 Greasemonkey在页面加载后执行代码行(在DOMContentLoaded上)。所以你不必创建<script>标签,设置它的正文并附加到文档中。你可以只写

document.getElementById("postingHtmlToolbar").firstChild.innerHTML += ...

,它应该做你想做的(你不需要contentEval职能)。

我没有博客上的博客,所以我不能记录和看到任何URL和有问题的行为,但与代码一步一步播放应该足以进行调试。

编辑2:

看来你应该改变firstChildfirstElementChild

innerHTML财产Element(因为火狐3.5),但不是在Node。 是的,它有时会非常不协调和烦人。我最近遇到了类似的问题。

编辑3:

有一对夫妇的事情出现。请不要告诉我这不还是工作:)

var func = function() { 
    var obj = document.getElementById("postingHtmlToolbar"); 
    if(obj !== null){ // only if object exists, so we don't have errors 
     //alert(obj); 
     obj.style.display = 'block'; // it's hidden by default 
     obj.firstElementChild.innerHTML += "FOO"; 
    } 
} 

window.setTimeout(func, 3000); // execute with delay -- let's give Google's JS time to be loaded first 
+0

有趣的是,如果我的脚本为什么没有做它应该做的事情,我还是不知道。 总而言之,我不关心脚本最终是否会触发100次。 您是否认为问题可能只是由于多次运行而发生? – Jonathon

+0

我之前并没有在脚本中详细看过,请查看编辑内容,准确地说出发生了什么以及发生了什么。问题是追加HTML或点击按钮? 'document.getElementById(“postingHtmlToolbar”)。firstChild.innerHTML + =“FOO”'工作吗? 关于多次发射,我认为每次执行都在单独的页面上下文中,所以它们不应该互相影响(但我不完全确定)。 –

+0

@edit:我不认为greasemonkey可以做这样的事情,它不能直接编辑页面。 不要问我为什么通用汽车公司不能以简单的方式来运行你100%信任的代码,但出于安全原因,我不明白他们限制你可以做的事情。 – Jonathon

0

GM可以直接修改网页这是通用汽车

的那<button>标签的用处......没有你的意思是输入?

我相信是执行两次,因为做这种方法,我猜是你的解决方法,不能够直接修改页面。

你正在做的是你正在创建一个命名匿名函数,如果你对JS不是很有经验,那么“哇”就是想出来。这将是问题:

if ('function' == typeof source) { 
    // Execute this function with no arguments, by adding parentheses. 
    // One set around the function, required for valid syntax, and a 
    // second empty set calls the surrounded function. 
    source = '(' + source + ')();' 
} 

当您设置之间的SOURCE + +您所呼叫的功能,因为当你在串联和功能是不是一个字符串,然后CONCAT正试图将其转换为它会执行该函数,但最后empty()会再次执行,而不会在concat中执行。我没有测试它,但我确实相信这一切正在发生。

所以jakub正确地指出你的代码的复杂性是不必要的,最终会给你带来错误。

相关问题