How to jump to the middle of one passage from another?

I’m using
Compiler: Tweego v 2.1.1
Story Format: SugarCube v 2.36.1

I’d like to be able to “return” from a passage (call it B) to the location where it was invoked in the previous passage (call it A). Am I overlooking an option in the <<return>> or <<link>> macros?

<<return>> and <<link>> seem always to open a passage with the reader’s viewpoint at the top of the passage. This can be annoying if the reader would like to continue reading from the point in Passage A where the link to Passage B was invoked.

For example passage A might contain

:: Passage A

lotsa text

<span id="return_here"> </span>
<<link "Passage B">> <</link>>

lots more text

What should Passage B contain to get the reader back to the location of the span with the id “return_here” ?

Or is there another way to define an anchor point in Passage A which could be used as a return point?


I tried using this “obvious” construct in Passage B

<<link "Passage A#return_here">> <</link>>

but that generated a link which tried to open an external file. Am I using the wrong syntax?

I tried using the macro <<ScrollTo... at the top of Passage A but it didn’t seem to do anything. In particular, the construct

<<ScrollTo "return_point">>
lotsa text
<<span id="return_point">> <</span>>>
lotsa text

left the viewpoint at the top of Passage A.

The construct

<link "go to return_point">> <<ScrollTo "return_point">> <</link>>

does work, but that’s an extra step for the reader which I’d prefer to avoid.

I’ve considered displaying Passage B in a popup or as a previously hidden section of Passage A. Those options are OK in some situations, but less so in others.

Thanks for whatever help you can provide.

HTML elements that are generated from the processing of a Passage’s content are temporarily stored in a buffer until the entire content has been processed, and then it is added to the Document Object Model of the web-page.

So if you used JavaScript to target one of the generated elements while the Passage’s content is still being processed then that element won’t be found in the DOM, because it doesn’t ‘exist’ yet.

SugarCube includes a number of Navigation Events that can be used to execute JavaScript at specific points in the Passage Transition process, and you’ll need to use one of them to delay the execution of your ‘scroll-to’ action until after the target element exists.

The following TWEE Notation based example uses a $scrollTo variable to track which link within the First Passage was used to visit the Second Passage. And a :passagedisplay event handler is used to determine if a ‘scroll-to’ action should be performed on the current Passage. The Story Javascript Passage in the following represents the same named area of your project.

:: Story Javascript [script]
$(document).on(':passagedisplay', function (ev) {
	/* does the scrollTo variable exist? */
	if ('scrollTo' in State.variables) {

		const el = document.getElementById(State.variables.scrollTo);

		/* does the target HTML element exist? */
		if (el) {

			/* scroll to the target element. */
			el.scrollIntoView();

			/* scrollTo variable has served its purpose, get rid of it! */
			/* note: the following is the equivalent of <<unset 'scrollTo'>> */
			delete State.variables.scrollTo;
		}
	}
});

:: Start
[[First]]

:: First
<p style="height: 300px;">lotsa text</p>

@@#option1;<<link "Option 1" "Second">><<set $scrollTo to "option1">><</link>>@@

<p style="height: 300px;">more lotsa text</p>

@@#option2;<<link "Option 2" "Second">><<set $scrollTo to "option2">><</link>>@@

:: Second
Blah Blah Blah...
<<link "Return" `previous()`>><</link>>

note: You didn’t state if you wanted the ‘scroll-to’ behaviour to be available within all the passages of your project, or just from within a specific set of them. So I have assumed in all of them, and placed the setting up of the :passagedisplay event handler within an equivalent of a project’s Story JavaScript area.

1 Like

@Greyelf

Thanks, a lot! I greatly appreciate the time you put into this.I would never have thought of those possibilities. I’ll give your solution a try.

It works great!

At first it worked in a simple example (a copy of what you’d provided plus a couple of required Story passages) but seemed to fail in the much more complex situation where I actually wanted to use it. Then I discovered I’d put the function into a backup copy of the file and not into the active one. sigh When the script was in the correct file, it worked!!!

Thanks, again.

1 Like