0 votes
by (550 points)

I've have some successes with Snowman but I still don't know enough Javascript to understand half of what's going on. Sorry about that. 

I want to have some text on screen, with a link that when clicked, appends more text to the screen, including other links. The problem is that I can't make the second link work.

I fuzzily know that some stuff in Snowman only works right when the page is first rendered, not later. I don't know if that's the problem.

This is my testing code. The second link does nothing at all. Seeing it with the inspector, it's totally inactive.

::a
<a id="link">Link</a>
<div id="link-target"></div>
<%
$(function () {
	$('#link').one('click', function () {
		$('#link-target').append(story.render("b"));
	});
});
%>

::b
<a id="link2">Link2</a>
<div id="link-target2"></div>
<%
$(function () {
	$('#link2').one('click', function () {
		$('#link-target2').append(Passage.render("End"));
	});
});
%>

Thanks!

1 Answer

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

You are correct that using...

$(function () {
	...
});

...causes the execution of the contained Javascript to be delayed until after the current Passage has been shown, and also correct that that doesn't work for Passage content being included (rendered) via a user interaction.

In this particular use case you only need to delay the attaching of the click event handlers to just after their related target elements have been added to the DOM, and it appears that you can use a embedded script element to do that.(or at least you could in the Chrome & Firefox tests I ran)

:: a
<a id="link">Link</a>
<div id="link-target"></div>
<script>
	$('#link').one('click', function () {
		$('#link-target').append(story.render("b"));
	});
</script>

:: b
<a id="link2">Link2</a>
<div id="link-target2"></div>
<script>
	$('#link2').one('click', function () {
		console.log('link2 clicked');
		$('#link-target2').append(Passage.render("End"));
	});
</script>

note: When using TWEE notation there should be (at least) a single space character between the double columns :: symbol used to indicate that start of a new Passage and the Title / Name of that passage.

by (550 points)

Thanks greyelf! Using <script> instead of <% function() does make it work as expected. Is it possible that not using the Snowman <% block has disadvantages? According to the readme, perhaps I wouldn't be able to use s.variable. That wouldn't be a fatal problem for me.

 

by (159k points)

Using <script> instead of <% function()...

I used a script element instead of <% ... %> markup in this particular use-case because the #link (and #link2) element doesn't exist at the time that the code within the <% ... %> markup is executed. You can test this yourself by first replacing the relevant code in Passage A with the following and then look at the Console output after running it.

<%
	console.log('link inline: ' + $('#link').length);
%>

... the output should read link inline: 0 which indicates that the #link ID'ed element hasn't been added to the page's DOM yet.

If you replace the above in Passage A with the following and do the same test.

<script>
	console.log('link script: ' + $('#link').length);
</script>

... then the output should read link script: 1 which indicates that enough time has passed for the #link ID'ed element to of been added to the page's DOM.

According to the readme, perhaps I wouldn't be able to use s.variable...

That is correct, you can't access a story variable from within a script element using that syntax however you can access them via the story.state object.

The following passage content uses Javascript to output the current value of the health story variable to the console.

<% s.health = 100 %>

<%
	console.log('via markup: health: ' + story.state["health"]);
%>
<script>
	console.log('via script: health: ' + story.state["health"]);
</script>

 

by (550 points)
Thanks a lot!
...