Identify text of last clicked link (including in current passage)

Twine Version: 2.6.2.0
[Sugarcube 2.36.1]

Hi, I’m looking for a way to identify the text of the last selected link in either the current passage or the previous passage (depending on whether something has been clicked in the current passage).

In the topic titled Log every link click (sorry unable to post the link) there is some javascript mentioned along with reference on how to identify the first item clicked (via $clickLog[0].label) however, I’m more interested in the last item clicked. Not sure how easy this is, and I know something similar could be achieved by setting a variable each time a link is clicked - however, this would mean repeating chunks of dialogue which I’d like to potentially avoid if at all possible!

So for example, say in passage one, there is a link called [[Next]], I’d like to be able to call the description via a variable (i.e. in the next passage I’d like to print something like $prvchoice which would return ‘Next’. I’d also like to be able to use this within a passage (which I guess it where this gets trickier) so for example if there was a <<link “I picked one”>> followed by the $prvchoice variable, I’d like this to return ‘I picked one’.

Hope that makes sense, and thanks in advance.

From this topic: log every link click you should just be able to look at the label of $clickLog[$clickLog.length-1] instead of $clickLog[0]

1 Like

Thanks, this is what I’ve tried:

:: Twine_UserScript [script]
/* Log Clicks - Start */

$(document).on(":passageend", function () {
	$("#passages a").on("click", function (ev) {
		if (!State.variables.clickLog) {
			State.variables.clickLog = [];
		}
		State.variables.clickLog.push({ passage: State.peek(1).title, type: "link", label: $(this).text(), time: new Date(Date.now()) })
	});
	$("#passages button").on("click", function (ev) {
		if (!State.variables.clickLog) {
			State.variables.clickLog = [];
		}
		State.variables.clickLog.push({ passage: passage(), type: "button", label: $(this).text(), time: new Date(Date.now()) })
	});
});
Save.onSave.add(function(save) {  // Requires SugarCube v2.36.0 or later//
	if (State.variables.clickLog) {
		save.state.history[save.state.index].variables.clickLog = State.variables.clickLog;
	}
});

:: Tracking Clicks 
[[I picked this option|passage1]]

:: passage1
[[Then I picked this option|passage2]]

:: passage2
$clickLog

$clickLog[0].label

$clickLog[$clickLog.length-1]

$clickLog[$clickLog.length-1].label

The results are as follows:

[object Object]

"I picked this option"

[object Object][1-1]

[object Object][1-1].label

I was hoping for a result of ‘Then I picked this option’ - but I think even if I could get the label, it would end up returning “I picked this option” as it doesn’t appear to be logging latest click in the next passage?

If I add another passage for example:

:: passage2
[["So then I tried this!"|passage3]]

:: passage 3
$clickLog[0].label
$clickLog[1].label
$clickLog[2].label

The results in passage 3 show as:

I picked this option
Then I picked this option
$clickLog[2].label

rather than:

I picked this option
Then I picked this option
So then I tried this!

I also found another script posted on the twinery Q & A which is showing similar behaviour: twinery[dot]org is there any way to add linkhistory (edited as it won’t allow me to post the link).

First, add the $linkHistory variable to the StoryInit passage.

<<set $linkHistory to []>>

Then paste the following script into the javascript passage.

postrender['link-tracker'] = function (content) {
	$(content).find('.link-internal')
		.on('click.link-tracker', function () {
			State.variables['linkHistory'].push($(this).text());
		});
};

Call using $linkHistory - however, if you put this in passage1 it returns nothing, in passage2 it returns the ‘I picked this option’ and in passage3 it returns ‘Then I picked this option’. So both scripts seem to only be returning the 2nd last click?

This appears to be a timing issue. Passage navigation seems to be starting before the click is logged, so when the passage renders $clickLog hasn’t been updated yet. If you replace the code in passage3 with

<<done>>
	<<replace "#log">>
		$clickLog[0].label
		$clickLog[1].label
		$clickLog[2].label
	<</replace>>
<</done>>
<span id="log"></span>

then everything works properly.

Thank you, that certainly addresses the issue with the lag - but not with identifying the last clicked link unless I hardcode in the value i.e. $clickLog[2].label. Incidentally that bit of code has just helped me with another problem I was trying to solve!

Yeah, for more complicated expressions like that you can’t use the Naked Variable markup, you hae to use one of the print macros: <<print $clickLog[$clickLog.length-1]>> or similarly with <<=>> or <<->>.

Ah, yes, that does make sense I think. So the following seems to do the trick (outputs from both scripts - both a little different in terms of the code, but returns the same output):

:: passage3
<<done>>
	<<replace "#log">>
		<<print $clickLog[$clickLog.length-1].label>>
                <<print $linkHistory[$linkHistory.length-1]>>
	<</replace>>
<</done>>
<span id="log"></span>

Thanks both for your patience and help, much appreciated!