Greasemonkey Script and Function Scope
Solution 1
Greasemonkey executes the script in a sandbox - the page doesn't have access to it for security reasons. All acceses to dom and window are via wrappers.
If you want to access the unsecured objects you can use wrappedJSObject
property.
For your case you can use unsafeWindow
(or window.wrappedJSObject
):
unsafeWindow.test = function() { ....
There are some security issues with this, see: http://wiki.greasespot.net/UnsafeWindow
Also, greasemonkey executes the script after the DOMContentLoaded (when the dom is ready) event so you don't need that onload nonsense.
Also, you can't use attributes to set event listeners, or properties for that matter - you must use dom api for that. Eg:
t.firstChild.addEventListener('click', test, false);
or:
t.firstChild.addEventListener('click', function(event){ blabla }, false);
Solution 2
iirc, greasemonkey runs within it's own scope, so test will not be in the global namespace.
Instead of poluting the global though, why not create your anchor element through DOM manipulation? That will return you a refernece which you can bind an anonymous function (or the greasemonkey scoped test).
Solution 3
Try adding the function test to the window object
window.test = function ...
Edit
Also, it's a good idea to run your code from a 'load' event handler instead of just by calling it at the end of your scripts. e.g.:
window.addEventListener("load", function(e) {
// Your main() here
}, false);
BuddyJoe
I like to code C# and work with the web. Still learning.
Updated on June 07, 2022Comments
-
BuddyJoe almost 2 years
Here is my script code:
// ==UserScript== // @name test // @description test // @include http://* // @copyright Bruno Tyndall // ==/UserScript== var main = function() { var b = document.getElementsByTagName('body')[0]; var t = document.createElement('div'); t.innerHTML = '<a href="javascript:void(0);" style="color:white;">Hello World</a>'; t.style.position = 'absolute'; t.style.zIndex = 1000; t.style.bottom = '5px'; t.style.right = '5px'; t.firstChild.setAttribute('onclick', 'test();'); b.appendChild(t); } var test = function() { alert("Hello World"); } main();
The only issue I have is when Hello World is clicked the page cannot find the test() function. Please tell me I don't have to solve it by innerHTML'ing the function onto the page like this. Is there another way?
Thanks.
-
BuddyJoe about 15 yearsThe window.test = function ... did not work for me. still gave me the test not defined error.
-
BuddyJoe about 15 yearsCan you elaborate a little? How would you do it if you want to keep the function "non-anonymous" (scoped in Greasemonkey). What do you mean by bind?
-
BuddyJoe about 15 yearsI'm creating the anchor through DOM manipulation now. But I don't see how to "bind" the function correctly.
-
Assaf Lavie about 15 yearsAre you calling window.test() in main?
-
BuddyJoe about 15 years+1. Thanks. I would appreciate your thoughts on where I am stuck now. I posted it over on userscripts.org/topics/21770 I can't get the inline anon function to work either.
-
BuddyJoe about 15 yearsI should add... I get zero help from the Error Console as far as to what is going wrong.
-
BuddyJoe about 15 yearsIn case anybody missed that I was using onclick instead of click.
-
annakata about 15 yearsI satrted answering this and then saw you got there already :)
-
user9303970 about 6 years@AssafLavie I'm stuck in a similar (but not surly identical) problem here. Care to have a look? Thanks anyway.