1
$(function() {
    let testOne = 'test one.';
    let testTwo = 'test two';

    let messageBox = $('messagebox');

    let a = ['test:', testOne,'test2:', testTwo];
    let i = 1

    setInterval(cool, 1000)

    function cool() {
        messageBox.text(a[1])
    }
});

Hi there,

I am new to JS. I am looking to have testOne and testTwo (going to add a few more) display in timers across my screen. I was given help to get this far. I am trying to, for example, have a word and its English definition appear on the screen in a time loop, rotating the words in a loop. (kind of like a live screen-saver)

What am I missing?

Thank you for your time, help, and effort.

showdev
  • 25,529
  • 35
  • 47
  • 67
John Smith
  • 13
  • 4
  • "display in timers" what do you mean? – zfrisch Nov 08 '18 at 22:42
  • *"What am I missing?"* The rest of your code required for a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – Herohtar Nov 08 '18 at 22:43
  • Hi Z, I am trying to, for example, have a word and its english definition appear on the screen in a time loop, rotating the words in a loop. (kind of like a live screen-saver) – John Smith Nov 08 '18 at 22:44
  • Hi Herohtar, The rest of my code is not necessary. This is from scratch, I did not add CSS yet and my HTML doesnt contain any content yet. – John Smith Nov 08 '18 at 22:45
  • `$('messagebox');` is also an invalid selector – Taplar Nov 08 '18 at 22:46
  • Taplar, I edited the title. – John Smith Nov 08 '18 at 22:47
  • Taplar, what would make messagebox invalid? – John Smith Nov 08 '18 at 22:48
  • 2
    `messagebox` is going to try to find an element like ``, but that's not a valid tag. If you want to find an element by class you have to use `.messagebox`, or if you want to find an element by id you have to use `#messagebox`. It all depends on your html. Selectors in javascript and pretty much one for one with CSS selectors. If you know how to do CSS Selectors, you'll have some insight into what your javascript selectors should be. – Taplar Nov 08 '18 at 22:49
  • There is no html element `messagebox` so you need either to add `#` or `.` before it, depending. That's why everyone said "show your html" – digijay Nov 08 '18 at 22:52
  • 1
    You can have `` if you want. It's a custom html element. As long as you're registering and using it as a proper web component. Everything is ok. React and Angular do this all the time and it's still 100% valid HTML. https://stackoverflow.com/questions/5682943/how-to-create-custom-tags-for-html – mwilson Nov 08 '18 at 23:09
  • This does not seem like a duplicate of "javascript interval" to me. The OP's `setInterval()` syntax is correct. – showdev Nov 09 '18 at 07:39

2 Answers2

0

You can easily swap out the messages in your array and update an html element using your code. Instead of passing a hardcoded index in, just increment a number until it reaches the length of the array (n < array.length) and reset it to 0.

I personally would recommend making your messagebox element a div or something out of the box just for readability sake (so nobody comes in and gets confused where messagebox is coming from). However, if you have a specific use case for a custom html element, make sure you're doing it correctly.

https://jsfiddle.net/mswilson4040/oxbn8t14/2/

<messagebox>Initial Value...</messagebox> // custom HTML element called messagebox


$(function() {
    let testOne = 'test one.';
    let testTwo = 'test two';
        let interval = -1;
    let messageBox = $('messagebox');

    let a = ['test:', testOne,'test2:', testTwo];
    // let i = 1 <-- this isn't doing anything

    setInterval(cool, 1000)

    function cool() {
            interval = interval < a.length ? interval += 1 : 0;
        messageBox.text(a[interval])
    }
});
mwilson
  • 10,186
  • 5
  • 41
  • 72
0

You've got a good start.

  1. As others have mentioned, unless you're using a custom HTML element (i.e. <messagebox>), use # at the beginning of your selector to indicate that "messagebox" is an ID. See jQuery's ID Selector.

    $('#messagebox')
    

    Alternatively, use a class and the class selector.

    $('.messagebox')
    
  2. The index of the array element to display is currently hard-coded to 1. We want to increment it upon each iteration so the text will change. But we only want to count up to the number of array elements and then go back to the first one and start over.

    Below, I'm using JavaScript's increment and remainder operators to increment i while limiting it to the number of elements in a. Note that the "postfix" method "returns the value before incrementing", so i starts at zero.

    a[i++ % a.length]
    

Working example:

$(function() {

  let $messageBox = $('#messagebox');
  let testOne = 'test one.';
  let testTwo = 'test two.';
  let a = ['test:', testOne, 'test2:', testTwo];
  let i = 0;

  function cool() {
    $messageBox.text(a[i++ % a.length])
  }

  setInterval(cool, 1000);

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="messagebox"></div>

EDIT

I don't like letting i count up indefinitely. The math might get wonky after about 9 quadrillion loop iterations, which is how high JavaScript can safely count.

Safe in this context refers to the ability to represent integers exactly and to correctly compare them. For example, Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 will evaluate to true, which is mathematically incorrect. -- developer.mozilla.org

console.log(Number.MAX_SAFE_INTEGER);
console.log(Number.MAX_SAFE_INTEGER + 1);
console.log(Number.MAX_SAFE_INTEGER + 2);
console.log(Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2);

So, here's what happens after about three million centuries:

$(function() {

  let $messageBox = $('#messagebox');
  let testOne = 'test one.';
  let testTwo = 'test two.';
  let a = ['test:', testOne, 'test2:', testTwo];
  let i = 9007199254740990;

  function cool() {
    console.log(i);
    $messageBox.text(a[i++ % a.length])
  }

  setInterval(cool, 1000);

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="messagebox"></div>

That's not good enough.
We need this thing running well past the end of time.
Let's keep it safe:

$(function() {

  let $messageBox = $('#messagebox');
  let testOne = 'test one.';
  let testTwo = 'test two.';
  let a = ['test:', testOne, 'test2:', testTwo];
  let i = 0;

  function cycleText() {
    console.log(i);
    $messageBox.text(a[i]);
    i = ++i % a.length;
    setTimeout(cycleText, 1000);
  }

  cycleText();

});
body {
  font-size: 2em;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="messagebox"></div>
showdev
  • 25,529
  • 35
  • 47
  • 67
  • 1
    Using an `id` selector or `class` selector isn't needed. If the OP wants to have an html element called `messagebox` it's perfectly fine and they can use it as a selector. – mwilson Nov 08 '18 at 23:16
  • @mwilson Agreed. The HTML structure is unclear from the OP, so I mentioned both options. – showdev Nov 08 '18 at 23:18
  • Thank you, Showdev. I was overwhelmed with all the fixes I had to make earlier. I did a poor job demonstrating what I needed to figure out. My issue extended all the way into forgetting to use increment counters. Earlier when I tried them, I would have not done the syntax proper, so thank you for supplying me the proper way. Anyway, thank you. – John Smith Nov 09 '18 at 00:50
  • $textBox.text(a[i++ % a.length]) - so, without " % a.length])" the function will not keep running the array over and over again. Where can I learn more about that codes purpose? to be more specific: where can I learn more about: " % " – John Smith Nov 09 '18 at 01:05
  • Without using `%`, the value would just get larger and larger and soon be larger than the size of your array. (Note that there are other ways to handle it, e.g. by setting `i` back to zero when it reaches `a.length`.) For reference, see [Remainder Operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Remainder_()) and [Modulo Operation](https://en.wikipedia.org/wiki/Modulo_operation). Also see [What does % do in JavaScript?](https://stackoverflow.com/questions/8900652/what-does-do-in-javascript) – showdev Nov 09 '18 at 01:52
  • When I took out % and .length, my code runs one loop of it, and then stops. When I take out just the %, it breaks. Thank you for posting those resources. – John Smith Nov 09 '18 at 02:18
  • That makes sense. When `i` gets above `a.length`, it no longer references values in the array; the numbers are too high. That's why you need to either set `i` back to zero or use a modulus; both methods result in [circular counting](https://study.com/academy/lesson/modulus-in-math-definition-examples.html). – showdev Nov 09 '18 at 06:46
  • That makes sense in those scenarios, thank you. In the function function cool() { $textBox.text(a[++i % a.length]) } What purpose does the first 'a' serve? – John Smith Nov 10 '18 at 02:45
  • In that example, we're referencing the array `a` and accessing the value for the key defined inside the `[]`. For example, `a[3]` is "test two" in your array. – showdev Nov 11 '18 at 05:19
  • HI, (a[i++ a.length]) , what role does this serve in the code? – John Smith Nov 25 '18 at 19:39