0 votes
by (250 points)

Hi - I'm struggling to get even basic JS to work in Twine 2. Even code copies straight from w3schools doesn't work.

eg.

var x = document.querySelectorAll("h2, div, span");
var i;
for (i = 0; i < x.length; i++) {
  x[i].style.backgroundColor = "red";
}

 

Doesn't do anything.

What I've found is that I can use this to change the 'body' of the document but nothing else. What I'm actually trying to do is add an animation delay to every instance of a particular class, with the animation delay going up for each one. eg.

var nodes = document.querySelectorAll(".bubble");
var i
for(var i = 0; i<nodes.length; i++){

  nodes[i].style.animationDelay = (i*3)+"s";

}

 

1 Answer

0 votes
by (68.6k points)

Preface.  Most code examples for DOM manipulation you find on random websites are probably not going to work as-is in story formats or, at least, not within the Story JavaScript section.  The reason for this is that most such examples assume a static, or mostly so, web page.  In contrast, story formats are web applications that do quite a lot of dynamic creation and manipulation of DOM content, so assumptions based on normal web pages are not always correct.

Where are you placing this code and the HTML elements you're attempting to modify?  If it's in the Story JavaScript section, then that's never going to work unless you're also injecting your elements from there, as code placed there is run only once during startup and, very likely, the elements you're attempting to target aren't yet on the page.

Assuming you're placing HTML markup within your passage(s) and that you're attempting to modify the styles of those elements, then what you should be doing is something like the following.

 

For A Single Passage

If you only need this post-processing on a single passage, then you could simply add your code within a <script> tag at the end of the passage.  For example:

<div class="bubble">A</div>
<div class="bubble">B</div>
<div class="bubble">C</div>
<script>
var nodes = document.querySelectorAll(".bubble");
for (var i = 0; i < nodes.length; ++i) {
	nodes[i].style.animationDelay = (i * 3) + "s";
}
</script>

 

For Multiple Passages

If you'll need this post-processing on multiple passages, then you could add your <script> tag wrapped code to a separate passage with the special tag footer, so it will run for every passage—which is better than copying the same script to many passages.  For example:

  1. Create a new passage and give it a descriptive name—e.g. .bubble animationDelay.
  2. Tag the new passage with: footer.
  3. Add the <script> tag and code to the new passage:
    <script>
    var nodes = document.querySelectorAll(".bubble");
    for (var i = 0; i < nodes.length; ++i) {
    	nodes[i].style.animationDelay = (i * 3) + "s";
    }
    </script>

     

...