+1 vote
by (680 points)

I am still not very well versed in javascript, so i'm trying to make a simple Mouseover script:

Chucked the following into my story Javascript:

setup.testFunction = function () {
    State.variables.equipmentslot = '1';
		new Wikifier(null, '<<Mouseover>>');
    };

My intention here is to set the story variable $equipmentslot to 1 and trigger a <<Mouseover>> widget (which is basically just a replace macro that replaces another div somewhere on the page).

 

The following is the trigger for the function within a story passage:

<span id="eq1" onmouseover="setup.testFunction()">Mouseover Me!</span>

 

And for some reason I keep getting an Uncaught Reference Error: setup is not defined.

3 Answers

+1 vote
by (159k points)
selected by
 
Best answer

The setup special variable is not actually global in scope, the engine makes it available to known things like macros and passage content so it just appears like it is. The Javascript contained within your span element's onmouseover event property is being executed in a different scope so you receive the error that you did.

I don't know the correct way to make the setup special variable available in the scope you want to access it in, although you could create your own unique Namespace and define your customer Javascript functions on that instead. Place code like the following within your story's Story Javascript area.

if (!window.GE) {
	window.GE = {};
}

GE.testFunction = function() {
	console.log('testFunction called');
};

... the use code like the following in a Passage to reference the custom function.

<span id="eq1" onmouseover="GE.testFunction()">Mouseover Me!</span>

note: You should rename the GE namespace you something that makes sense to your story, just remember to update both the Javascript and the Passage contents with the new name.

by (8.6k points)
In "global" (window) scope, the setup object is available via SugarCube.setup, in case you need it.
by (68.6k points)
edited by

In "global" (window) scope, the setup object is available via SugarCube.setup, in case you need it.

The global SugarCube object is, as I have said before, for debugging purposes only.  It is unstable and should not be relied upon.  The fact that it's undocumented should be a hint.  If necessary, I will remove it to protect users from its misuse.

by (159k points)

In "global" (window) scope...

...for debugging purposes only. 

Thus the reason I didn't mention that particular object as a potential solution for this issue, and why I stated....

I don't know the correct way to make the setup special variable available in the scope you want to access it in...

by (68.6k points)
edited by

greyelf,

I'm unsure if your last comment was meant for me, however, as should have been clear from the quote, I was responding to Akjosch.  You never made mention of the SugarCube global.

Regardless.  There is no single correct way.  Though, using SugarCube global is most definitely the wrong way.

Your answer, placing SugarCube scoped functions on the window object somehow (either as a static method in a namespace object or simply on its own), is certainly one correct way.

Another correct way would be to not use the old and moldy on… event attributes in the first place, instead attaching the event handler either directly using <<script>> or via a post-processing event/task.

+1 vote
by (68.6k points)

The reason for the error is that code within the on... event attributes is executed within the global scope, which is separate from SugarCube's.  The setup object is a member of SugarCube's internal scope, thus cannot be directly referenced in the global scope.

One possible way to avoid the issue is given by greyelf in their answer.

Another would be to create your element and attach the event handler directly using the <<script>> macro, instead of using the old and moldy on... event attributes.  For example:

<<script>>
$(document.createElement('span'))
	.wiki('Mouseover Me!')
	.on('mouseover', function (ev) {
		State.variables.equipmentslot = '1';
		$.wiki('<<Mouseover>>');
	})
	.appendTo(output);
<</script>>

 

0 votes
by (8.6k points)
For yet another way on how to do an inventory with detailed descriptions on mouseover, see my answer to another question here:

https://twinery.org/questions/839/there-trigger-macro-through-mouseover-mouse-twine-sugarcube?show=861#a861
by (680 points)
Thanks, Akjosch.  Sorry for the late reply.  Works like a charm :)
...