简体   繁体   中英

How to properly clear and update a textarea element?

I'm having difficulties clearing and then 'redrawing' a textarea element. I have a HTML doc setup like this:

The problem seems to be occurring in the updateLog function. The numbers 0-4 are printed as they should be, but once '5' is added and the array is shifted, the textarea doesn't seem to change anymore (it should display "12345" then "23456" etc.). I have so far tested and found that the function is being called every second, the array is being properly shifted and that the textarea's value is cleared before the for loop which 'draws' to the textarea. I'm completely stumped here.

 var logWidth = 60 var logHeight = 5 document.getElementById('log').setAttribute("rows", logHeight) document.getElementById('log').setAttribute("cols", logWidth) var canLogPrint = true var txt = document.getElementById('log') var x = 0 var logContents = [] setInterval(function() { if (canLogPrint) { updateLog(x.toString()) x += 1 } }, 1000) function updateLog(message) { logContents.push(message) if (logContents.length > logHeight) { logContents.shift() } txt.value = '' for (s in logContents) { txt.value += s + '\n' } } function pauseLog() { canLogPrint = !canLogPrint }
 #log { /*resize: none;*/ overflow: hidden; margin-bottom: 5px; }
 <textarea id='log' rows=25 cols=60 autofocus readonly></textarea> <br> <button onclick="pauseLog()">PAUSE</button>

This was a funny one to solve.

The problem is that you're using for in loop, wich iterates in the object properties , in that case it is a list, so the object is like {0:'3', 1: '4', 2:'5'... } and you're always printing the key instead of the value.

To fix that you can just use logContents[s] in your for in loop, or use for of loop.

Here's your code working.

 var logWidth = 60 var logHeight = 5 document.getElementById('log').setAttribute("rows", logHeight) document.getElementById('log').setAttribute("cols", logWidth) var canLogPrint = true var txt = document.getElementById('log') var x = 0 var logContents = [] setInterval(function() { if (canLogPrint) { updateLog(x.toString()) x += 1 } }, 1000) function updateLog(message) { logContents.push(message) if (logContents.length > logHeight) { logContents.shift() } txt.value = '' for (s of logContents) { txt.value += s + '\n' } } function pauseLog() { canLogPrint = !canLogPrint }
 #log { /*resize: none;*/ overflow: hidden; margin-bottom: 5px; }
 <textarea id='log' rows=25 cols=60 autofocus readonly></textarea> <br> <button onclick="pauseLog()">PAUSE</button>

 var logWidth = 60 var logHeight = 5 document.getElementById('log').setAttribute("rows", logHeight) document.getElementById('log').setAttribute("cols", logWidth) var canLogPrint = true var txt = document.getElementById('log') var x = 0 var logContents = [] setInterval(function() { if (canLogPrint) { updateLog(x.toString()) x += 1 } }, 1000) function updateLog(message) { logContents.push(message) if (logContents.length > logHeight) { logContents.shift(); txt.value = logContents.join('\n'); } txt.value = '' txt.value = logContents.join('\n'); } function pauseLog() { canLogPrint = !canLogPrint }
 #log { /*resize: none;*/ overflow: hidden; margin-bottom: 5px; }
 <textarea id='log' rows=25 cols=60 autofocus readonly></textarea> <br> <button onclick="pauseLog()">PAUSE</button>

The problem is with your for.. in . for.. in is used to iterate the keys of an object. As arrays are also Objects it will iterate the keys what means

   key value
    0    5
    1    6
    2    7
    3    8
    4    9

Now when the values changes the keys will be the same, that is the reason why your output still will be 0 1 2 3 4.

You can use forEach here as in the example below.

 <html> <head> <style> #log { /*resize: none;*/ overflow: hidden; margin-bottom: 5px; } </style> </head> <body> <textarea id='log' rows=25 cols=60 autofocus readonly></textarea> <br> <button onclick="pauseLog()">PAUSE</button> <script> var logWidth = 60 var logHeight = 5 document.getElementById('log').setAttribute("rows", logHeight) document.getElementById('log').setAttribute("cols", logWidth) var canLogPrint = true var txt = document.getElementById('log') var x = 0 var logContents = [] setInterval(function(){ if (canLogPrint) { updateLog(x.toString()) x += 1 } },1000) function updateLog(message) { logContents.push(message) if (logContents.length > logHeight) { logContents.shift(); } txt.value = '' logContents.forEach((x) => { txt.value += x + '\n' }) } function pauseLog() { canLogPrint = !canLogPrint } </script> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM