我正在开发一个 Greasemonkey 脚本,该脚本将一个按钮注入聊天系统(Gitter),允许您发送默认消息。 (不是垃圾邮件。管理员可以发送类似行为准则的消息)。
假设我已经注入了一个按钮:
<button onclick='setTimeout( function() { showMsg() }, 10 );'>Send default message</button>
根据这个问题的建议:Javascript:函数已定义,但错误提示..找不到函数! (奇怪的) https://stackoverflow.com/questions/5919781/javascript-function-is-defined-but-error-says-function-is-not-found-stran to use setTimeout()
因为GM中定义的函数在主窗口中是不可用的。
出于测试目的,该函数是一个简单的控制台日志:
function showMsg(){
console.log('showMsg triggered');
}
问题是这仍然返回给我“showMsg 未定义”。因此,按照前面提到的问题中提供的其他建议,我尝试了:
unsafeWindow.showMsg = function(){
console.log('showMsg triggered');
}
然而,这让我返回:
错误:访问对象的权限被拒绝
奇怪的是,似乎这只在创建 div 元素并使用时才会发生innerHTML
将按钮注入该 div 中。当实际创建一个这样的按钮时:
var btn = document.createElement('button');
btn.onclick = function(){ showMsg(); };
它按预期工作。
一些可能有助于找到答案的附加信息:
Gitter 聊天使用 iframe 来显示聊天消息和消息输入字段。 iframe 位于同一服务器上,因此不存在相同原始策略问题。
按钮被注入到主体中。以下是我如何尝试注入它们的两个示例。
(工作版本)
var iframe, iframeDoc;
var chatContainer;
var chatInput, chatText;
var msgMenu;
$(document).ready(function() {
iframe = document.getElementById('content-frame');
iframe.onload = function(){
iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
chatContainer = iframeDoc.getElementById('chat-container');
chatInput = iframeDoc.getElementById('chat-input');
chatText = iframeDoc.getElementById('chat-input-textarea');
loadButton();
}
});
function loadButton(){
var div = document.createElement('div');
var btn = document.createElement('button');
var btnText = document.createTextNode('Send default message');
// Lots of CSS here that ads absolute positioning
// and makes the div float in the middle of the screen
btn.onclick = function(){ showMsg(); };
btn.appendChild(btnText);
div.appendChild(btn);
div.setAttribute("id", "msgMenu");
document.body.appendChild(div);
msgMenu = document.getElementById('msgMenu');
return false;
}
function showMsg(){
console.log('showMsg triggered');
}
将 loadButton 函数更改为此时,会导致上述问题:
function loadButton(){
var div = document.createElement('div');
div.innerHTML = "<button onclick='setTimeout( function() { showMsg() }, 10 );'>Send default message</button>";
div.setAttribute("id", "msgMenu");
document.body.appendChild(div);
msgMenu = document.getElementById('msgMenu');
return false;
}