Why does this JavaScript only work in the start passage?

Hello all SugarCube 2.30.0 users!

I put this code:

document.getElementsByClassName("macro-textbox").spellcheck = "false";

in various places (JavaScript, in <<script>> in PassageHeader, PassageDone, PassageReady, etc.) to disable “spellcheck” on textbox macros, but it only works if the textboxes are in the start passage. Is there anything that would make it work in all the passages?

Thank you people!

The HTML elements generated while process the contents of ‘current’ Passage (and any Passages referenced by it) are first added to a buffer, and the contents of that buffer isn’t added to the web-page’s Document Object Model until late in the Passage Transition process. This means that JavaScript code within the ‘current’ Passage (or those referenced) can’t directly reference any HTML element generated by that Passage, because that element wont exist in the DOM yet.

So that answers one of the reasons why that you code won’t work in PassageHeader, the other reason it won’t work in that special passage is because its contents is processed before that of the ‘current’ Passage, which means that <<script>> macro is executed before any <<texttbox>> macro in the ‘current’ Passage is.

But the main reason your code doesn’t work (as you expect it to) is because the getElementsByClassName() function returns an array-like object, so you are actually doing that property assignment on that collection object and not the elements contained within it. This outcome can be seen by using the following test project…
(switching which code is commented out for each test)

:: Start
<<set $name to "">>
<<textbox "$name" $name>>

:: PassageDone
<<script>> document.getElementsByClassName("macro-textbox").spellcheck = "false"; <</script>>

…and by using code like the following within your web-browser’s Console to look at the Array-like object…

document.getElementsByClassName("macro-textbox")

…when you expand that object within the Console you will see that it has been assigned a “spellcheck” property with a value of “false”.

You could use jQuery code like the following within the PassageDone special passage to loop through each element with the collection…

:: PassageDone
<<script>> $('.macro-textbox').each(function () { this.spellcheck = false; }); <</script>>

(cough) I just found out that it works to wrap it in <span spellcheck="false">. I had just assumed that wouldn’t work because similar solutions had not worked for other things before. What’s embarrassing is that I had already used that solution for a previous game of mine. :upside_down_face:

1 Like

I hate that. :grin:

It’s like reinventing the wheel… because you forgot you already made a wheel still have it stored in your shed.

1 Like

I had thought of checking my previous game, but the problem was I had tried several things with it as well, and had left the most recent failed attempt in the JavaScript section. So that was what I found, and it sent me on a snipe hunt.

When it didn’t work for my current game I assumed it was because I had used textarea macros in the previous game, while my current game uses textbox macros. Just this morning I thought of checking if I had done anything in the html in my previous game, and there was the <span> solution I had actually used.