My Code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Real Time Texteditor</title> <style> @import url('https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap'); body{ background-color: white; margin: 25px; } h1{ margin-bottom: 0px; color: black; align-content: center; font-family: 'Roboto Mono', monospace; } #ErrorParag{ margin-top: 0px; font-family: 'Roboto Mono', monospace; } #textarea{ width: 100%; height: 90vh; color: black; font-size:20px; border: 5px solid; border-radius: 5px; } </style> <script> const params = new Proxy(new URLSearchParams(window.location.search), { get: (searchParams, prop) => searchParams.get(prop), }) const ID = params.id const NAME = params.name //console.log(String(ID)+" "+String(NAME)) const xhr = new XMLHttpRequest(); last_input = "" window.onload = function(){ xhr.open('POST', '/api/retrieve', false); xhr.setRequestHeader("Content-Type", "application/json"); xhr.send(JSON.stringify({"id":ID, "name":NAME})); response = JSON.parse(xhr.responseText); //console.log(response); if(response.status==="error"){ document.getElementById("ErrorParag").innerHTML = response.error document.getElementById("ErrorParag").style.color = "#ff0000"; } else if(response.status==="success"){ document.getElementById("textarea").innerHTML = response.data } } function compareString(x, y){ //x = originally, y = new => if(x.length>y.length){ //smaller String => char was deleted x>y for(let i = 0; i<x.length; i++){ //console.log(String(x)+" "+String(y[i])+" --- "+String(x.length)+" "+String(i)) //kleiner Bug bei der Darstellung wird der gesamte Text angezeigt if(x[i]!==y[i]){ return {"pos":String(i),"change":String(-1),"char":String(x[i])} } else if(i===x.length-1){ return {"pos":String(i+1),"change":String(-1),"char":String(x[x.length])} } } } else if(x.length<y.length){ //bigger String => char was added x<y for(let i = 0; i<y.length; i++){ //console.log(String(x[i])+" "+String(y[i])+" --- "+String(y.length)+" "+String(i)) if(x[i]!==y[i]){ return {"pos":String(i),"change":String(1),"char":String(y[i])} } else if(i===y.length-1){ return {"pos":String(i+1),"change":String(1),"char":String(y[y.length])} } } } return {"Error":"Something went completely wrong"} } function onTextUpdate(e){ let results = compareString(last_input, e.value) //console.log(results) globalThis.last_input = e.value; send_data = JSON.stringify({"update":results, "id":ID, "name":NAME}) // {"update":{"pos": ..., "change": ..., "char": ...}, "id": ... , "name": ... } //console.log("Data which is gonna be send:") console.log(send_data) //post the results to back end xhr.open('POST', '/api/update', false); xhr.setRequestHeader("Content-Type", "application/json"); xhr.send(send_data); response = JSON.parse(xhr.responseText); console.log(response); if(response.status==="failure"){ document.getElementById("ErrorParag").innerHTML = response.error document.getElementById("ErrorParag").style.color = "#ff0000"; } else if(response.status==="success"){ document.getElementById("ErrorParag").innerHTML = "success" document.getElementById("ErrorParag").style.color = "#00ff00"; } } const loadData = function(){ console.log("get data from server") xhr.open('POST', '/api/retrieve', false); xhr.setRequestHeader("Content-Type", "application/json"); xhr.send(JSON.stringify({"id":ID, "name":NAME})); response = JSON.parse(xhr.responseText); console.log(response.data); if(response.status==="error"){ document.getElementById("ErrorParag").innerHTML = response.error document.getElementById("ErrorParag").style.color = "#ff0000"; } else if(response.status==="success"){ console.log("success!") document.getElementById("textarea").innerHTML = response.data } } const load_data = setInterval(loadData, 1000) </script> </head> <body> <h1>Real Time Texteditor</h1> <p id="ErrorParag"></p> <textarea id="textarea" placeholder="Just write ..." oninput="onTextUpdate(this)"></textarea> </body> </html>
As you probably read, the code is for a Real-Time Texteditor Project I’m working on with a friend. But I don’t understand why everything works well until I click on the text field and wanna write something. The server gets everything and the other instance also. The only problem is, that the second instance doesn’t overwrite the innerHTML of the text field. If I reload the second instance everything appears in the text field. I’m confused. Does anyone know why this is happening?
Advertisement
Answer
First of all, you shouldn’t set an Interval to load data every second, as in a normal text editor, you load data every time the textarea’s value is changed. When setting an Interval to load data every second you’re essentially spamming the user and the server for no reason.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Real Time Texteditor</title> <style> @import url('https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap'); body{ background-color: white; margin: 25px; } h1{ margin-bottom: 0px; color: black; align-content: center; font-family: 'Roboto Mono', monospace; } #ErrorParag{ margin-top: 0px; font-family: 'Roboto Mono', monospace; } #textarea{ width: 100%; height: 90vh; color: black; font-size:20px; border: 5px solid; border-radius: 5px; } </style> <script> const params = new Proxy(new URLSearchParams(window.location.search), { get: (searchParams, prop) => searchParams.get(prop), }) const ID = params.id const NAME = params.name //console.log(String(ID)+" "+String(NAME)) const xhr = new XMLHttpRequest(); last_input = "" window.onload = function(){ xhr.open('POST', '/api/retrieve', false); xhr.setRequestHeader("Content-Type", "application/json"); xhr.send(JSON.stringify({"id":ID, "name":NAME})); response = JSON.parse(xhr.responseText); //console.log(response); if(response.status==="error"){ document.getElementById("ErrorParag").innerHTML = response.error document.getElementById("ErrorParag").style.color = "#ff0000"; } else if(response.status==="success"){ document.getElementById("textarea").innerHTML = response.data } } function compareString(x, y){ //x = originally, y = new => if(x.length>y.length){ //smaller String => char was deleted x>y for(let i = 0; i<x.length; i++){ //console.log(String(x)+" "+String(y[i])+" --- "+String(x.length)+" "+String(i)) //kleiner Bug bei der Darstellung wird der gesamte Text angezeigt if(x[i]!==y[i]){ return {"pos":String(i),"change":String(-1),"char":String(x[i])} } else if(i===x.length-1){ return {"pos":String(i+1),"change":String(-1),"char":String(x[x.length])} } } } else if(x.length<y.length){ //bigger String => char was added x<y for(let i = 0; i<y.length; i++){ //console.log(String(x[i])+" "+String(y[i])+" --- "+String(y.length)+" "+String(i)) if(x[i]!==y[i]){ return {"pos":String(i),"change":String(1),"char":String(y[i])} } else if(i===y.length-1){ return {"pos":String(i+1),"change":String(1),"char":String(y[y.length])} } } } return {"Error":"Something went completely wrong"} } function onTextUpdate(e){ let results = compareString(last_input, e.value) //console.log(results) globalThis.last_input = e.value; send_data = JSON.stringify({"update":results, "id":ID, "name":NAME}) // {"update":{"pos": ..., "change": ..., "char": ...}, "id": ... , "name": ... } //console.log("Data which is gonna be send:") console.log(send_data) //post the results to back end xhr.open('POST', '/api/update', false); xhr.setRequestHeader("Content-Type", "application/json"); xhr.send(send_data); response = JSON.parse(xhr.responseText); console.log(response); if(response.status==="failure"){ document.getElementById("ErrorParag").innerHTML = response.error document.getElementById("ErrorParag").style.color = "#ff0000"; } else if(response.status==="success"){ document.getElementById("ErrorParag").innerHTML = "success" document.getElementById("ErrorParag").style.color = "#00ff00"; } console.log("get data from server") xhr.open('POST', '/api/retrieve', false); xhr.setRequestHeader("Content-Type", "application/json"); xhr.send(JSON.stringify({"id":ID, "name":NAME})); response = JSON.parse(xhr.responseText); console.log(response.data); if(response.status==="error"){ document.getElementById("ErrorParag").innerHTML = response.error document.getElementById("ErrorParag").style.color = "#ff0000"; } else if(response.status==="success"){ console.log("success!") document.getElementById("textarea").value = response.data } } </script> </head> <body> <h1>Real Time Texteditor</h1> <p id="ErrorParag"></p> <textarea id="textarea" placeholder="Just write ..." oninput="onTextUpdate(this)"></textarea> </body> </html>
All I changed was combining the load_data
function with the onTextUpdate
function, and changing document.getElementById("textarea").innerHTML = response.data
to
document.getElementById("textarea").value = response.data
, since as Teemu explained well in the comments: textarea
can’t contain HTML, it contains plain text only. Use value
instead of innerHTML
.