2

After pressing button I want to display in input in order & every two seconds the full list text li

A -- B -- C -- D -- E

I tried this but it's not working

 <button>show li in order every 2 seconds</button>

 <input type=text id="show" />

$("button").on("click",function(){
   $(".menu li").each(function(){
    setTimeout(function() { $("show").($(this).text()); }, 2000);
  });
 });
input{
width:40px;
height:40px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<button>show li in order every 2 seconds</button>

<input type=text id="show" />
<ul class="menu">

<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
</ul>
Anurag Srivastava
  • 14,077
  • 4
  • 33
  • 43
max
  • 105
  • 7
  • Were any of the below answers helpful to you? If so, please select a "correct" answer *(by clicking the checkmark beside an answer)* to close the question, or else provide your own answer and choose that as the correct answer. ***Please review the answers closely before deciding - future readers will be influenced by your decision.*** Otherwise, please add comments below one of the answers or edit your original question to add more detail so that additional answers can be provided. *Thanks!* – cssyphus Jul 14 '20 at 01:33

3 Answers3

2

You need to use setInterval and set text from .menu li incrementally

$("button").on("click", function() {
  var items = $(".menu li"), idx = 0;

  var timer = setInterval(function() {
    var currText = items.eq(idx).text()
    if (idx < items.length - 1) idx++;
    // else idx = 0;
    else clearInterval(timer); // Use this for clearing the timer
    
    $("#show").val(currText);
    if(idx > 0) items.eq(idx - 1).hide(); // Hide previous <li>
  }, 2000);
});
input {
  width: 40px;
  height: 40px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<button>show li in order every 2 seconds</button>

<input type=text id="show" />
<ul class="menu">

  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
  <li>E</li>
</ul>
Anurag Srivastava
  • 14,077
  • 4
  • 33
  • 43
  • pretty good answer. thank you. A question, please the code continues executing itself after reaching to the last row `E` or does it stop? – max Jan 19 '20 at 16:00
  • It continues, if you wish it to stop, use the `clearInterval` method I added as a comment, instead of `else idx = 0` – Anurag Srivastava Jan 19 '20 at 16:05
  • I understand. pretty awesome. A last question please. What if I want to hide the prior `li` content once its in the new row...for example once in row `C`, then is hided row `B` – max Jan 19 '20 at 16:14
  • Use `.hide()` with the correct index, see edit in answer – Anurag Srivastava Jan 19 '20 at 16:16
  • I see. but in this case its not hiding the last one `E` – max Jan 19 '20 at 16:21
  • another bug would be that in case you set the time interval to `20` seconds, for example...the page waits 20 seconds to start running the code...after the button press. how to fix this? – max Jan 19 '20 at 16:53
  • Then you call the code inside the timer once before initializing it. For the last `E` you can run a code before `clearInterval` inside the `else` block – Anurag Srivastava Jan 20 '20 at 15:27
0
$("button").on("click",function(){
    var dispIntrvl = $(this).attr("dispIntrvl");
    if(dispIntrvl) {
         clearInterval(dispIntrvl);
    }
    var indx = -1;
    var arr = [];
    $(".menu li").each(function(){
        arr.push($(this).text());
    });
    if(arr.length == 0)return;
    var shw = $("show");
    dispIntrvl = setInterval(function() {
        shw.val(arr[++indx]);
        if(indx == arr.length)indx = -1;
    }, 2000);
    $(this).attr("dispIntrvl", dispIntrvl);
});
shashank joshi
  • 140
  • 1
  • 4
0

You can use a nested setTimout (also called a Chained Timeout) to accomplish this, otherwise the results will display all-at-once at the very end (giving the appearance that only the final one worked).

The pop() method gets/removes the last array element, so we want to first reverse the array so that the characters are popped-off in their original order, per your question specs. Using pop() gives us a quick way to run the array once only.

I prefer to use nested setTimeout() to using setInterval() because the setTimeout will call itself again as soon as it has finished, whereas setInterval re-runs itself on a timer. Therefore, if there is any delay completing the function the next setInterval will still run as scheduled, meaning that multiple instances of the function could stack up.

let arr = [];

$("button").click(function() {
   $('.menu li').each(function(){
      arr.push( $(this).text() );
   });
   arr = arr.reverse();
   showChars(arr);
});

function showChars(arr){
   if (arr.length === 0) return false;
   let chr = arr.pop();
   setTimeout(function(){
      $('#show').val(chr);
      showChars(arr);
   },1000);
}
input {
  width: 40px;
  height: 40px;
  text-align:center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>

<input type=text id="show" />
<button>show li in order every 2 seconds</button>

<ul class="menu">
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
  <li>E</li>
</ul>

Chained-Timeout gives a guaranteed slot of free time to the browser; Interval tries to ensure the function it is running executes as close as possible to its scheduled times, at the expense of browser UI availability.

setTimeout or setInterval?

cssyphus
  • 37,875
  • 18
  • 96
  • 111