Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Показания датчика обновлять периодически (https://javascript.ru/forum/events/72664-pokazaniya-datchika-obnovlyat-periodicheski.html)

sim31 16.02.2018 01:11

Показания датчика обновлять периодически
 
Нужен небольшой совет.

Написал программу что берет показания датчика температуры (влажности, давления и т.п.) и выводит в тестовый файл одной строчкой, так проще всего. Например
Writeln('35.5');

Ну и к сути, лежит у нас 2 файла в одном каталоге на который смотрит Apache, Index.html статический и temperatura.txt.
Последний обновляется каждые 5 секунд, например.

Хотелось бы понять, как написать скрипт, что будет в теле Index.html периодически вставлять данные из temperatura.txt.

Пока использую костыль:
Код:

meta http-equiv="refresh" content="10"
но тут обновляется вся страница, и своей программой приходится перезаписывать Index.html и внутри обновлять одну строку, очень громоздкая конструкция, а кроме того при обновлении картинка дергается.

Разбирался со скриптом, таймер да, просто
setTimeout("alert('Прошла 1 секунда')", 10000);


Вывод параметров на экран тоже просто
function showMessage() {
  document.writeln(x);}


Но после однократного вывода доступа к телу документа нет. Функция вызывается, но данные выведены статически, раз и навсегда. Почитал про BOM, DOM, что-то сложно всё, нет удобного примера или шаблона.

Кто может подсказать как собрать все команды в одну конструкцию? В идеале чтобы данные из temperatura.txt попадали в ячейку таблицы. Первый столбец описание
"текущая температура", второй столбец содержимое файла "temperatura.txt"

Aetae 16.02.2018 02:02

document.write - пишет в тело документа прямо по мере загрузки, т.е. докачался первый кусок - сразу обработан, и результат document.write вкинут прямо на живую в поток обработки поступающего текста.
Потому для динамического обновления его использовать уже нельзя, ибо когда страница загружена - исходный текст выгружается из памяти за не надобностью, остаётся лишь результат разбора в виде сложного объекта - DOM.

Со справкой покончили, теперь код:) :
function updateInfo(file, target, interval){
  if(typeof target !== 'object')
    target = document.querySelector(target);
  
  function stop(){
    clearTimeout(timer);
    xmlhttp.abort();
  }
  function update(){
    xmlhttp.open('GET', file + '?' + Math.random(), true);
    xmlhttp.send();
  }
  
  var xmlhttp = new XMLHttpRequest(), timer;
  xmlhttp.onreadystatechange = function(){
    if(xmlhttp.readyState !== 4) 
      return;
    
    if(xmlhttp.status !== 200) 
      console.log('updateInfo: ' + xmlhttp.statusText);
    else 
      target.innerHTML = xmlhttp.responseText;
    
    timer = setTimeout(update, interval);   
  }
  
  update();
  
  return {
    start: update,
    stop: stop
  } 
};

updateInfo('./temperatura.txt', 'table td:nth-child(2)', 1000);

sim31 16.02.2018 03:04

Одновременно я свою версию делал, работает только наполовину. Таймер работает, считает и выводит цифру в положение textPlace1. Файл не считался, но скорее всего там что-то не так :)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>

<script language="JavaScript" type="text/javascript">

function OnLoad() 
{
httpRequest = new XMLHttpRequest();
httpRequest.open("GET", "/test.txt", true);
httpRequest.onreadystatechange = OnRequestStateChange;
httpRequest.send(null);
}

function OnRequestStateChange()
{
if (httpRequest.readyState != 4)
  return;
if (httpRequest.status != 200)
  return;
document.getElementById("textPlace2").innerHTML = httpRequest.responseText;
}

// вот тут и ниже работает, то что сверху нет
var x=100;

function showMessage() {
//  document.writeln(x);
  x++; 
  document.getElementById("textPlace1").innerHTML = x;
}

setInterval(function() {showMessage()}, 500);

</script>

<div id="textPlace1"></div>
<div id="textPlace2"></div>

</body>
</html>

sim31 16.02.2018 03:27

Цитата:

Сообщение от Aetae
теперь код

Код красивый, но что-то данных нет, возможно неправильно запускаю, в консоли одно сообщение - ошибка

TypeError: target is null
zzz2.html:33:7
updateInfo/xmlhttp.onreadystatechange


Запускал так, еще непонятно как DOM таблицы указать, чтобы данные туда отправлялись:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

</head>

<body>

<script language="JavaScript" type="text/javascript">

function updateInfo(file, target, interval){
  if(typeof target !== 'object')
    target = document.querySelector(target);
  
  function stop(){
    clearTimeout(timer);
    xmlhttp.abort();
  }
  function update(){
    xmlhttp.open('GET', file + '?' + Math.random(), true); // защита от кеширования, тут понятно
    xmlhttp.send();
  }
  
  var xmlhttp = new XMLHttpRequest(), timer;
  xmlhttp.onreadystatechange = function(){
    if(xmlhttp.readyState !== 4) 
      return;
    
    if(xmlhttp.status !== 200) 
      console.log('updateInfo: ' + xmlhttp.statusText);
    else 
      target.innerHTML = xmlhttp.responseText;
    
    timer = setTimeout(update, interval);   
  }
  
  update();
  
  return {
    start: update,
    stop: stop
  } 
};

updateInfo('./temperatura.txt', 'table td:nth-child(2)', 1000);
// и куда update пойдет? ))

</script>

<table width="246" border="1">
  <tr>
    <td width="105">parametr1</td>
    <td width="125">&nbsp;</td> 
  </tr>
  <tr>
    <td>parametr1</td>
    <td>&nbsp;</td>
  </tr>
</table>


</body>
</html>

sim31 16.02.2018 03:45

Вот так заработало, не нашел как отправить данные в таблицу, взял из предыдущего примера работу с блоком текста. В консоле ничего, но из файла данные обновляются.

Условно рабочий пример этот тут можно запустить
http://89.223.27.27/zzz3.html

<body>

<script language="JavaScript" type="text/javascript">

function updateInfo(file, interval){
  if(typeof target !== 'object') // ? наверное что-то должно быть 

// Тут выдает ошибку, убрал и пока непонятно как через функцию передавать "пункт назначения"
//    target = document.getElementById("textPlace1").innerHTML;
	
  
  function stop(){
    clearTimeout(timer);
    xmlhttp.abort();
  }
  function update(){
    xmlhttp.open('GET', file + '?' + Math.random(), true);
    xmlhttp.send();
  }
  
  var xmlhttp = new XMLHttpRequest(), timer;
  xmlhttp.onreadystatechange = function(){
    if(xmlhttp.readyState !== 4) 
      return;
    
    if(xmlhttp.status !== 200) 
      console.log('updateInfo: ' + xmlhttp.statusText);
    else 
      document.getElementById("textPlace1").innerHTML = xmlhttp.responseText;
      // некарасиво как-то на пока непонятно как лучше сделать
    
    timer = setTimeout(update, interval);   
  }
  
  update();
  
  return {
    start: update,
    stop: stop
  } 
};

updateInfo('./temperatura.txt', 1000);

</script>

<div id="textPlace1"></div>
<div >*** *** ***</div>

</body>
</html>

sim31 16.02.2018 04:22

Получилось направить данные в таблицу, надо было указать по аналогии метку

<tr>
    <td id="textPlace2"></td>
    <td></td>
  </tr>


Остались вопросы по программе, как передавать эту метку или какой-то аналог при вызове функции, на случай если параметров будет несколько.

Aetae 17.02.2018 00:20

Проблема была в том, что функцию вы вызываете до того, как на странице появляются элементы. Если бы вы внимательно читали информационную справку о потоке - могли бы сами понять) :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
</head>
 
<body>
 
<script language="JavaScript" type="text/javascript">
 
function updateInfo(file, target, interval){
  if(typeof target !== 'object')
    target = document.querySelector(target);
   
  function stop(){
    clearTimeout(timer);
    xmlhttp.abort();
  }
  function update(){
    xmlhttp.open('GET', file + '?' + Math.random(), true); // защита от кеширования, тут понятно
    xmlhttp.send();
  }
   
  var xmlhttp = new XMLHttpRequest(), timer;
  xmlhttp.onreadystatechange = function(){
    if(xmlhttp.readyState !== 4)
      return;
     
    if(xmlhttp.status !== 200)
      console.log('updateInfo: ' + xmlhttp.statusText);
    else
      target.innerHTML = xmlhttp.responseText;
     
    timer = setTimeout(update, interval);  
  }
   
  update();
   
  return {
    start: update,
    stop: stop
  }
};
 
//тут ещё нет никакого table, оно ещё летит по сети, а код уже работает. Естесно нифига не найдено.
updateInfo('./temperatura.txt', 'table td:nth-child(2)', 1000); //запрос по (css) селектору: первая таблица, второй по порядку td, тут предполагалось, что вы сами укажете что надо)
 
</script>
 
<table width="246" border="1">
  <tr>
    <td width="105">parametr1</td>
    <td width="125">&nbsp;</td>
  </tr>
  <tr>
    <td>parametr1</td>
    <td>&nbsp;</td>
  </tr>
</table>
 
 
</body>
</html>

Должно быть примерно так:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script>
function updateInfo(file, target, interval){
  //тут проверяется что target - объект, если да то считаем, что это сам элемент куда надо выводить и оставляем как есть, иначе считаем что передан (css) селектор и запрашиваем элемент по оному
  if(typeof target !== 'object') 
    target = document.querySelector(target);
   
  function stop(){
    clearTimeout(timer);
    xmlhttp.abort();
  }
  function update(){
    xmlhttp.open('GET', file + '?' + Math.random(), true); 
    xmlhttp.send();
  }
   
  var xmlhttp = new XMLHttpRequest(), timer;
  xmlhttp.onreadystatechange = function(){
    if(xmlhttp.readyState !== 4)
      return;
     
    if(xmlhttp.status !== 200)
      console.log('updateInfo: ' + xmlhttp.statusText);
    else
      target.innerHTML = xmlhttp.responseText;
     
    timer = setTimeout(update, interval);  
  }
   
  update();
   
  return {
    start: update,
    stop: stop
  }
};

window.onload = function(){
  updateInfo('./temperatura.txt', '#textPlace2', 1000);
  //или
  updateInfo('./temperatura.txt', document.getElementById('textPlace2'), 1000);
}

</script>
</head>
 
<body>
 

<table width="246" border="1">
  <tr>
    <td width="105">parametr1</td>
    <td width="125">&nbsp;</td>
  </tr>
  <tr>
    <td>parametr1</td>
    <td >&nbsp;</td>
  </tr>
</table>

<!-- или просто добавить в конец, так:
<script>
updateInfo('./temperatura.txt', '#textPlace2', 1000);
</script>
-->
</body>
</html>

И да, js - регистрозависимый, потому ваш OnLoad не работает.)


Часовой пояс GMT +3, время: 12:57.