Mirakurun Mirakurun - 4 months ago 30
HTML Question

Maintain scroll position in list

I have a select list, which is populated with my logfile. Every second javascript sends GET request to the server which reads the log file and populates the list. But after every GET request, the list scrolls back to top. What I want to do is to make the requests don't affect the scroll so I can freely scroll through the list.

<select id = "list" name=servers size=38 style=width:1028px>

<script type="text/javascript">
window.onload = function () {

if (bytes === undefined) {
var bytes=0;
}
var url = "/test/log.php?q=";
function httpGet(url)
{
var xhttp = new XMLHttpRequest();
xhttp.open("GET", url, true);
xhttp.onload = function (e) {
if (xhttp.readyState === 4) {
if (xhttp.status === 200) {
var list = "";
console.log(xhttp.responseText);
obj = JSON.parse(xhttp.responseText);
for(var key in obj) {
list += obj[key];
if (sessionStorage.logfile == null) {
sessionStorage.logfile == "Log";
}

}
bytes = parseInt(list);
document.getElementById("list").innerHTML = sessionStorage.logfile + list;
sessionStorage.logfile += list;
}
};
xhttp.onerror = function (e) {
console.error(xhttp.statusText);
}
};


xhttp.send();
}

var updateInterval = 1000;
function update() {

httpGet(url + bytes);
setTimeout(update, updateInterval);
}

update();
}
</script>

Answer

Maybe you should use SSE,check this: http://www.w3schools.com/html/html5_serversentevents.asp, but if you just need to make the code works, here is how:

<select id = "list" name=servers size=38 style=width:1028px>

<script type="text/javascript">

//here, a new global var to keep the index;
var old_index=-1;


window.onload = function () {
 //every change on select list, we register in this function..
 document.getElementById("list").onchange = keepValue;



  if (bytes === undefined) {
      var bytes=0;
  }
var url = "/test/log.php?q=";
function httpGet(url)
{
  var xhttp = new XMLHttpRequest();
  xhttp.open("GET", url, true);
  xhttp.onload = function (e) {
      if (xhttp.readyState === 4) {
          if (xhttp.status === 200) {
              var list = "";
              console.log(xhttp.responseText);
              obj = JSON.parse(xhttp.responseText);
              for(var key in obj) {
              list += obj[key];
              if (sessionStorage.logfile == null) {
                  sessionStorage.logfile == "Log";
              }

          }
            bytes = parseInt(list);
            document.getElementById("list").innerHTML = sessionStorage.logfile + list;
            sessionStorage.logfile += list;
            //here, back it to the old selected index
            //when old_index=-1, means first execution
            if (old_index==-1)
            {old_index = document.getElementById("list").length-1;}
            document.getElementById("list").selectedIndex = old_index;
          }
      };
      xhttp.onerror = function (e) {
      console.error(xhttp.statusText);
    }
  };


xhttp.send();
}

var updateInterval = 1000; 
function update() {
  httpGet(url + bytes);
  //i will not change your logic here, but you can write it using setInterval instead.
  setTimeout(update, updateInterval);
}

update();
}

//here, the function to register the list index
function keepValue(evt)
{

old_index = evt.target.selectedIndex;
//or document.getElementById('list').selectedIndex;

}

</script>

EDIT:

ResponseText is in JSON format.

{"key":"2186 <option>   18:42:19.716 7963       [DEBUG main() cnet.cpp:167]  Using public ip: 192.168.0.107 </option>
<option>   18:42:19.716 7963       [DEBUG main() cnet.cpp:168]  Using local ip: 192.168.0.107 </option>
<option>   18:42:19.717 7963       [DEBUG init() redis.cpp:75]  Initializing redis client application </option>"}
Comments