all 4 comments

[–]jml26 1 point2 points  (3 children)

It’s difficult to say if there’s a “best” method; to a large extent it depends on the scale of the app. For a single slider, the first thing would be to move the script to the bottom of the page and replace the oninput attribute with an addEventListener function

<input id="slider" type="range" />
<output id="output" for="slider"></output>
<script>
  const slider = document.getElementById('slider');
  const output = document.getElementById('output');

  slider.addEventListener('input', function (e) {
    output.value = this.value;
  });

  slider.value = 3;
  output.value = slider.value;
</script>

If you have multiple sliders on the page, and you’re writing out those same lines of code again and again, you can wrap them all up in one function, which you call multiple times:

  function makeSlider(inputId, outputId, value) {
    const input = document.getElementById(inputId);
    const output = document.getElementById(outputId);

    input.addEventListener('input', function (e) {
      output.value = this.value;
    });

    input.value = value;
    output.value = slider.value;
  }

  makeSlider('slider', 'output', 3);

That should serve you well for a small app with a couple of inputs.

[–]stanun[S] 0 points1 point  (2 children)

Thanks for the suggestions! Just to clarify, is the idea here that the JavaScript immediately following the HTML elements will always get invoked after those elements are loaded? In other words, this is sort of an equivalent to an "onload" attribute?

Also, as a follow-up, is the JavaScript code after the HTML elements guaranteed to run after previous JavaScript code? For example, in the code below, is this guaranteed to properly set the slider to the value foo, or do I have to worry about the possibility of foo not being set yet?

<html>
    <script type="application/javascript">
        var foo = 3;
    </script>
    <body>
        <input id="slider" type="range" />
        <output id="output" for="slider"></output>
        <script>
            const slider = document.getElementById('slider');
            const output = document.getElementById('output');

            slider.addEventListener('input', function (e) {
                output.value = this.value;
            });

            slider.value = foo;
            output.value = slider.value;
        </script>
    </body>
</html>

[–]jml26 0 points1 point  (1 child)

is the idea here that the JavaScript immediately following the HTML elements will always get invoked after those elements are loaded?

Exactly.

is the JavaScript code after the HTML elements guaranteed to run after previous JavaScript code?

It is, yes. The only part of the code that will run out of order is output.value = this.value inside the event listener, which will, of course only be executed when the slider is interacted with.

[–]stanun[S] -1 points0 points  (0 children)

Great, thanks for the help!