Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

How to define and invoke global funcitons in Snowman

I have this very basic quesiotn. I tired looking for the answear but so far all I found suggests that what I'm doing should be working and it isn't.

Using Snowman. When I define a function and invoke it in the same passage it works. When I define the function in the Story JavaScript I get an undefined error.

the example I'm using:
Story JavaScript:
function test() {
	document.write('testing123');
};
Passage:
<% test() %>

Comments

  • Your issue is one of Scope, generally Javascript variables and functions are not gobal by default. In your case the function is defined locally in one passage (Story Javascript) and there-for not visible in another passage.

    One method used to make a Javascript variable or function (the same thing really) have global scope is to define it on the global window object like so.
    window.myfunc = function myfunc() {
    	console.log('myfunc called');
    };
    
    // or if you want to make sure it does not exist first...
    if (! window.myfunc) {
    	window.myfunc = function myfunc() {
    		console.log('myfunc called');
    	};
    }
    
    ... and you call the global function like so:
    <% myfunc %>
    

    One problem with defining variables/function directly against the window object is you can accentually override existing variables/functions. You can use a namespace pattern to get a this issue, you add your functions to the namespace object, which in turn gets added to the window object.
    var MyNameSpace = {};
    MyNameSpace.myfunc = function myfunc() {
    		console.log('MyNameSpace.myfunc called');
    };
    window.MyNameSpace = MyNameSpace;
    
    ... and you call the global namespace functions like so:
    <% MyNameSpace.myfunc() %>
    

    note: You can name your namespace whatever you like, just make sure whatever it is that it does not already exist on the window object.
  • greyelf, that's a really excellent answer -- just wanted to note a small thing, that the story JavaScript is evaluated in a separate context as you explained, but doesn't exist as a separate passage per se.
  • klembot wrote: »
    ...but doesn't exist as a separate passage per se.
    I noticed that it was added as a script element but did not want to get that deeply into describing the Snowman DOM structure in my explanation if I didn't have to.
  • Thanks for your help. I've also noticed you can use story.state like below and it also works. This addresses the window object related issues as I found somewhere in the Snowman description.

    Define:
    story.state.test = function test() {
    	document.write('testing123');
    };
    
    and call:
    <% s.test() %>
    
  • The contents of the story.state variable is serialized and inserted into the web-browser's History system whenever you navigate between passages if Snowman's History is active and you are using Checkpoints. If the reader uses the back button to undo their last action the reverse occurs, the story.state is overwritten with the de-serialized value from the History system.

    Any functions you add to the story.state variable may not survive the serialize/de-serialize process, which would result in them disappearing and producing undefined errors.
  • That's another piece of useful information. Thanks.
Sign In or Register to comment.