[Snowman] JS script doesn't run in page order

This is a simplified version of my problem. I have two passages, and the second is rendered within the first.

:: one
<div class="test">
This is passage one
</div>
<%= story.render( "two" ) %>

:: two
<script>
$('.test').addClass('red')
</script>

<div class="test">
This is passage two.
</div>

Add to this a CSS declaration .red {color:red}.

My intended result is:

<div class="red test">
This is passage one.
</div>
<div class="test">
This is passage two.
</div>

But the actual result is:

<div class="red test">
This is passage one.
</div>
<div class="red test">
This is passage two.
</div>

See what Iā€™m trying to do? Iā€™m expecting the script tag to be run in the place where itā€™s written, before the second ā€œ.testā€ div is added to the DOM, so it can only select the first ā€œ.testā€. However, the script runs some time later, selecting both ā€œ.testā€ divs.

Is there anything Iā€™m doing wrong? I need a systematic solution for this: Iā€™m not doing this by hand in a few passages, itā€™s the way that the whole game works: rendering a passage within the current passage, then changing the previous text. (Itā€™s of course a lot more complex than this example.)

Thanks!

The issue is that <script> elements are always executed after the contents of the ā€˜currentā€™ Passage have been processed, so as current written the 2nd .test classed will always exist.

There are a number of methods you can use to achieve the result you want, like using a more precise CSS Selectorā€¦

1: Use a pseudo class like :first-of-type to target the first instance of the .test class.

<script>
$('.test:first-of-type').addClass('red')
</script>

2: Combine :not( selector ) with :last-of-type to target every instance of the .test class except the last one.

<script>
$('.test:not(:last-of-type)').addClass('red')
</script>
1 Like
  1. I hate Javascript.

  2. Great idea @Greyelf! Thanks. I had to adapt it because my real divs arenā€™t siblings, but I could do it using .first() instead of :first-of-type.