0 votes
by (140 points)
retagged by
I'm working on a piece that requires a number of HTML forms. I want them to have autofocus, since that's expected practice for forms in general.

The autofocus initially works as intended. However, the field loses focus after a short amount of time. Any typing is interrupted, and the user has to manually click the field again, which is quite jarring. This happens with both autofocus in the HTML tag and with manually applying focus with JavaScript.

I've timed it and this happens after approximately 0.8 seconds, which is the amount of time Harlowe's default transitions last, so my suspicion is that something in the passage loading is grabbing focus away from the page element. However, I have no idea how to go about interrupting/fixing this. Is there a way around this besides just not using autofocus (not ideal, but...)?

Thanks in advance.

1 Answer

0 votes
by (159k points)

An example of the contents of your Passage and how you are implementing your input related functionality would help us know exactly what your Passage is doing.

The visual effect portion of Harlowe's passage transition process includes the following two steps:

1. Wrapping the new passage's HTML elements within a tw-transition-container element which is then added to the DOM of the current page. (Start of passage transition visual effect.)

2. Removing the tw-transition-container element from the DOM of the current page and then re-adding it's child elements directly to the DOM. (End of passage transition visual effect.)

The removal and then re-adding of your input related elements may be causing the side effect you are seeing.

by (140 points)

Basically, what I have is a "fake" form, meant to mimic a login screen with username and password. It's contained within a custom class, in order to disable Harlowe's fading in text (the effect looks bad on fixed interface elements). Removing this div does not fix the autofocus issue.

<div id="interface" class="nofade">

The username field is first, and has autofocus:

<input id="username" type="text" maxlength="20" oninput=" populatePassword()" onKeyPress="return checkSubmit(event,link)"/ autofocus>

Additional functions here: 

populatePassword adds asterisks to the password field immediately below once the user starts entering a username. (The "password" box is entirely for cosmetic effect; I don't want to confuse the player into thinking it's a puzzle they don't know the answer to.) It doesn't cause the autofocus issue -- removing it makes no difference, the field still loses focus.

checkSubmit "submits" the form (i.e., advances to the next passage) if the user has pressed Enter on the field. event is standard, link is custom. Removing this also does not affect the autofocus issue in any way.

var link = document.querySelector('tw-link[passage-name="Hub"]');

I'm currently using a workaround as follows. It's not ideal -- there's a split-second blip between when the autofocus is lost and when it's re-applied, which is visible if you're looking for it -- but does allow the user to continuously type without noticeable interruption:

// hack to prevent harlowe's transitions from jacking focus
var timeoutoverride = 808; // ~0.8 seconds
var focustimer = setTimeout(function() {
    document.getElementById("username").focus();
}, timeoutoverride);

(There's a corresponding clearTimeout anywhere the user can advance to the next passage, in case they manage to do it in less than 0.8 seconds.)

by (159k points)

WARNING: If you are using JavaScript to modify the contents of the undocumented State.variables object and if that contents is a collection object of some kind (Array, Map, etc) then it is likely that you are corrupting History, which can effect the outcome of the Undo feature if more than a single passage traversal has occurred since the last TwineScript modification of the same collection.

by (140 points)
I've disabled Undo already. This is not the sort of piece where it makes sense. Besides, this appears on the very first passage.
...