脚本触发但没有结果

时间:2011-10-26 14:10:14

标签: javascript firefox google-chrome greasemonkey blogger

我写了一个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是否有反脚本注入的东西?

2 个答案:

答案 0 :(得分:1)

关于两次开火:

如果页面包含<iframe> s,则会在每个页面中触发用户脚本。

您需要确定自己是否在<iframe>内。仅在主页面而不是iframe中触发的最简单方法是使用以下代码包装所有代码:

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

要查看页面中是否有<iframe>s(以HTML格式编码或动态生成),我总是使用AdBlock Plus(“打开可阻止项目”对话框)。

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

关于脚本一般:

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

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

它应该做你想要的(你根本不需要contentEval功能)。

我没有关于博客的任何博客,所以我无法登录并查看任何URL和有问题的行为,但是一步一步地使用代码进行调试应该足以进行调试。

编辑2:

似乎您应该将firstChild更改为firstElementChild

innerHTML中有Element个属性(自Firefox 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

答案 1 :(得分:0)

GM可以直接修改GM的有用性的网页

那个<button>标签......你不是指INPUT吗?

我相信正在执行两次因为执行此方法,我想这是您无法直接修改页面的解决方法。

你正在做的是你正在创建一个命名匿名函数,如果你在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指出代码的复杂性是不必要的,最终会给你错误。