0 votes
by (470 points)
edited by

So I need handler at the beginning and the end(when you leave it with any link) of the passage. I found some events that should be supported by sugarcube, but I am not sure why are they not working for me. 

I have an image that should become a background on some passages and a lot of similar templates to make the game more flexible due to different sizes of images. Here is some code: 

<img src="/assets/images/pregame/desert_1.jpg" width="100%" class="image-background">
img.image-background {
  display: none;
$(document).on(':passagestart', function () {
	if ($('.image-background')) {
		/*$('.link-internal').bind('click', function() { //this was my previous attempt
			$('body').css('background-image','none');    //to create finish handler

When I start the game, there is nothing. I mean no errors but there is no background image set either. Any ideas? 

Also which event or event is better to use here? I can't understand what some of them do, like ':passageinit' for example. Description "Triggered before the modification of the state history." does not tell me much. I can just guess I need ":passagestart" and ":passageend". 

2 Answers

+1 vote
by (63.1k points)
selected by
Best answer
Are you using version 2.20.0 of SugarCube? You might need to update to use the new passage event features. The most recent version of Twine comes installed with v2.18.0 of SugarCube, for reference. If you don't want to update for some reason (you probably should, though) you can use task objects instead of the events.
by (470 points)
Oh... Riiiiight :D I forgot that I moved it to another domain and haven't yet downloaded 2.20...

Works now, thx! But still. The only 2 that worked were display and end events, but what are render, start and init for?
by (63.1k points)
edited by
So in order for you to use jQuery to manipulate page content, that content has to be on the page (rendered). The events that didn't work couldn't actually locate the elements they were meant to interact with because they hadn't been rendered yet.

Specifically, the :passageinit event occurs before the State is changed, which is just after a user clicks a link, but before anything on the page has changed. The :passagestart event occurs once the State history has changed, but before any incoming content is rendered. The :passagerender event happens after the content is rendered. I think the last event here might work for you, but I'd still use display or end.

These events generally are not useful for manipulating DOM elements, but can be useful for other things.
by (68.6k points)

Additionally.  Your IF statement has a bad conditional.  The following does not do what you probably think it does:

if ($('.image-background')) {

When invoked thus jQuery always returns an object, which will always be truthy when evaluated in a boolean context, so that IF statement's block will always executed as written.

If you intent is to only execute the block when an element containing the class image-background is found, then it should look something like the following:

if ($('.image-background').length > 0) {

That checks to see if any elements were matched by comparing the value of the return jQuery object's length property.

+1 vote
by (159k points)

edit: LOL It looks like someone else posted an answer while I was writing mine.

You need to use the question tags to state the name and full version number of the story format you are using as answers can vary based on that information. You mention the :passageinit event so I will assume you are using one of the SugarCube 2.x releases because events aren't implemented in SugarCube 1.x

As explained by the :passageinit event's documentation that particular event (as well as all the other events) requires you to be using at least v2.20.0 of that story format, and because the current version of Twine 2 only includes the v2.18.0 release I will assume you have manually downloaded and upgraded your local version of SugarCube 2.x

By default each time the reader traverses between Passages the story format's engine makes a copy of the state (values) of all known story variables, the original is associate with the name of Passage that is being left and stored within the State History system, the copy is made available to the Passage that is about to be processed and shown.

From what I understand the :passageinit event occurs somewhere between the previous Passage being left and the next Passage's contents being processed.

Which tasks or events you can uses depends greatly on which HTML element the image will be a background to and what method you are using to assign the background image to the particular element, because some elements are destroyed and recreated during the Passage processing/rending process so you may not be able to assign them a background image until after the element has been recreated.

Based on your example I will assume that the img element with the image-background CSS class has been placed within the content of one of your Passage, if this is true then that element wont actually exist in any state until at least step 3.0 of the event/task overview and at that time the element will only exist in the content buffer so you would need to be searching for the element in it instead of within the page's DOM.
The element won't exist in the actual page' DOM until step 4.0, which is the earliest point when your current IF statement condition could possible return true.

I suggest you change your code to either:
a. use one of the step 3.0 methods and to search the content buffer for the element you want.
b. use one of the step 4.0 methods and use your existing code.

a. I didn't actually test your body element based styling code so even if you use the correct events/tasks there may still be issues with it.
b. I would suggest looking at using CSS rules to define each of your different backgrounds and assigning a CSS class to the target element and instead of assigning the background image directly to the element.