我写了一个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(/&nbsp;/g, \' \');"><b>SP</b></button></div></div></div>'});
alert("testw");
blogger.com是否有反脚本注入的东西?
答案 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
。
firstChild
返回Node
firstElementChild
返回Element
。 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指出代码的复杂性是不必要的,最终会给你错误。