Re: XMLHttp autorefresh v dive

Webdesign, HTML, CSS, Flash, PHP, ASP, .NET, JavaScript. Kritika www stránek na Smetišti.

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod 5ulo 14. 4. 2008 20:19

Zdravim, taham na svoju stranku cez xmlhttprequest do divu html subor a potrebujem, aby sa ten div autorefreshoval napr. kazdych 30s. Aby to nebolo malo, taketo divy budu na stranke dva a kazdy bude mat iny cielovy dokument. Autorefresh by kludne mohol byt rovnaky pre oba divy. Kazdopadne, dostal som sa po tialto.

Kód: Vybrat vše
<script type="text/javascript">
var rootdomain="http://"+window.location.hostname

function ajaxinclude(url) {
var page_request = false
if (window.XMLHttpRequest) // if Mozilla, Safari etc
page_request = new XMLHttpRequest()
else if (window.ActiveXObject){ // if IE
try {
page_request = new ActiveXObject("Msxml2.XMLHTTP")
}
catch (e){
try{
page_request = new ActiveXObject("Microsoft.XMLHTTP")
}
catch (e){}
}
}
else
return false
page_request.open('GET', url, false) //get page synchronously
page_request.send(null)
writecontent(page_request)
}

function writecontent(page_request){
if (window.location.href.indexOf("http")==-1 || page_request.status==200)
document.write(page_request.responseText)
}
</script>


a do stranky vkladam takto
Kód: Vybrat vše
<script type="text/javascript">
ajaxinclude(rootdomain+"stranka.html")
</script>


Sice to krasne funguje, ale za toho onieho neviem dorobit ten autorefresh. Neviete niekto pomoct, prosim? :)
Som "kazisvět šestý" :)))
5ulo
Kolemjdoucí

Odeslat příspěvekod gofry 16. 4. 2008 03:22

setInterval()

Inak prečo odosielaš tú požiadavku synchrónne?
gofry
Junior
Uživatelský avatar

Odeslat příspěvekod 5ulo 16. 4. 2008 08:23

Asi preto, ze som amater a bol som rad, ze som nasiel aspon ten tutorial na to, co som pastol vyssie. Mas nejaky lepsi napad? Rad sa priucim ;)
Som "kazisvět šestý" :)))
5ulo
Kolemjdoucí

Odeslat příspěvekod gofry 16. 4. 2008 09:46

Tak na ten tutoriál čo najskôr zabudni. Sila Ajaxu je práve v tom, že sa robí asynchrónne.

Kód: Vybrat vše
<script type="text/javascript">

var xmlHTTP;

function createXMLHTTP() {
  var xmlHttp = null;
  try {
    // Firefox, Opera 8.0+, Safari
    xmlHttp = new XMLHttpRequest();
  } catch (e) {
    // Internet Explorer
    try {
      xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
  }

  return xmlHttp;
}

function getDataForDIV() {
  var xmlHTTP = createXMLHTTP();
  if(!xmlHTTP) alert('sorry, no ajax for you');

  var url = 'nejaka_adresa';
 
  xmlHTTP.onreadystatechange=refreshDIV;
  xmlHTTP.open("GET", url, true);
  xmlHTTP.send(null);
}

function refreshDIV() {
  if (xmlHTTP.readyState==4) {
  document.getElementById("tvoj_div").innerHTML = xmlHTTP.responseText;
  }
}

function init() {
  getDataForDIV();
  setInterval('getDataForDIV()', 30000);
}

<script>


...
<body onload="init()">
...



Kód som netestoval, tak snáď bude fungovať.
Naposledy upravil gofry dne 16. 4. 2008 11:20, celkově upraveno 1
gofry
Junior
Uživatelský avatar

Odeslat příspěvekod 5ulo 16. 4. 2008 10:34

vdaka za priklad aj objasnenie.. aj ked ten tvoj kod nefacha :) nenaplni mi ten div :( aspon viem, ze v asynchronnosti je sila :D

stroskota to na chybe
Kód: Vybrat vše
xmlHTTP is not defined
[Break on this error] if (xmlHTTP.readyState==4) {

error on line 32
Som "kazisvět šestý" :)))
5ulo
Kolemjdoucí

Odeslat příspěvekod gofry 16. 4. 2008 11:19

Pred funkciu createXMLHTTP() dopíš
Kód: Vybrat vše
var xmlHTTP;
tj. začiatok bude vyzerať takto:
Kód: Vybrat vše
<script type="text/javascript">

var xmlHTTP;

function createXMLHTTP() {
  var xmlHttp = null;
  try {
...

Doplnil som to aj do pôvodného kódu.

Osobne by som ti ale doporučil použiť nejaký JS framework (napríklad YUI), práca je potom ďaleko jednoduchšia a xmlHTTP request "zavoláš" na jednom riadku.
gofry
Junior
Uživatelský avatar

Odeslat příspěvekod 5ulo 17. 4. 2008 17:08

tak som sa dnes k tomu opat dostal. Dopisal som tam to "var xmlHTTP;" (bey uvodzoviek samorejme :)) a dospel som k niecomu takemuto

Kód: Vybrat vše
xmlHTTP has no properties
if (xmlHTTP.readyState==4) {
Som "kazisvět šestý" :)))
5ulo
Kolemjdoucí

Odeslat příspěvekod gofry 17. 4. 2008 17:54

Jejda, pekne zákerná chyba. Vo funkcii getDataForDIV() je hneď na prvom riadku inicializovaná lokálna premenná xmlHTTP, ktorá prekryje tú globálnu.

Takže fcia by mala vyzerať takto
Kód: Vybrat vše
function getDataForDIV() {
  xmlHTTP = createXMLHTTP();
  ...
}


Taktiež tam nemám dobre ukončený tag <script> - chýba mu lomítko.

Opravil by som to aj v pôvodnom kóde, ale nejak sa mi neozbrazuje tlačítko na editovanie príspevku.
gofry
Junior
Uživatelský avatar

Odeslat příspěvekod 5ulo 17. 4. 2008 18:13

Vyborne.. uz to funguje.. vdaka :) co sa tyka toho uzatvoreneho <script> tak neva.. ja to aj tak hukal do externeho .js :)
Este mi prosim ta porad, ako mozem mat na stranke dva divy s rozdielnym ID a kazdy div ma brat inu stranku... to cez tento skript asi nedokazem.. Ten moj prvy povodny synchronny to zvladal, ale chybal mu autorefresh :(
Tam bolo to kuzlo v tom, ze na stranku som vlozil dokument prave za pomoci
Kód: Vybrat vše
<script type="text/javascript">
ajaxinclude(rootdomain+"stranka.html")
</script>
Som "kazisvět šestý" :)))
5ulo
Kolemjdoucí

Odeslat příspěvekod gofry 17. 4. 2008 19:29

Môžeš pre každý div vytvoriť samostatné xmlHTTP1, getDataForDiv1(), refreshDiv1() a xmlHTTP2, getDataForDiv2(), refreshDiv2(). To je vhodný postup, keby každý div robil s prijatými datami niečo odlišné.

Keď ale iba chceš vypísať vrátené data do divu, tak
Kód: Vybrat vše
function createXMLHTTP() {
  ...
}

function getDataForDIV(url, divID) {
  var xmlHTTP = createXMLHTTP();

  if(!xmlHTTP) {
    alert('sorry, no ajax for you');
    return false;
  }

  xmlHTTP.onreadystatechange = function() {
    if (xmlHTTP.readyState == 4) {
      document.getElementById(divID).innerHTML = xmlHTTP.responseText;
    }
  };

  xmlHTTP.open('GET', url, true);
  xmlHTTP.send(null);
}

function init() {
  getDataForDIV('ajax1.php', 'div1');
  getDataForDIV('ajax2.php', 'div2');
  setInterval("getDataForDIV('ajax1.php', 'div1'); getDataForDIV('ajax2.php', 'div2');", 3000);
}
Je to trochu odlišné od toho predchádzajúceho, napríklad nie je nutné používať to globálne xmlHTTP, stačí lokálne.

Teoreticky by fcia init() mohla vyzerať aj
Kód: Vybrat vše
function init() {
  getDataForDIV('ajax1.php', 'div1');
  getDataForDIV('ajax2.php', 'div2');
  setInterval("getDataForDIV('ajax1.php', 'div1')", 1000);
  setInterval("getDataForDIV('ajax2.php', 'div2')", 4000);
}
aby si mohol nastaviť rôzne intervaly pre rôzne divy, ale vo FF sa to chovalo veľmi divne, ak bol jeden interval deliteľom druhého. Netuším prečo.
Naposledy upravil gofry dne 17. 4. 2008 23:20, celkově upraveno 1
gofry
Junior
Uživatelský avatar

Odeslat příspěvekod 5ulo 17. 4. 2008 23:08

Gofry, ja byt zena, tak ta fcul radostou pomilujem :)))))) Velky dik...v tej tvojej poslednej verzii mas drobnu "chybu"...
Kód: Vybrat vše
      document.getElementById(divID).innerHTML += xmlHTTP.responseText;

som opravil na
Kód: Vybrat vše
      document.getElementById(divID).innerHTML = xmlHTTP.responseText;

pretoze s tym pluskom sa to len a len pripisovalo do nekonecna.. takze pre ostatnych, kto sem zabludi, pastnem cely kod tak, ako funguje :)

Kód: Vybrat vše
<script type="text/javascript">

function createXMLHTTP() {
  var xmlHttp = null;
  try {
    // Firefox, Opera 8.0+, Safari
    xmlHttp = new XMLHttpRequest();
  } catch (e) {
    // Internet Explorer
    try {
      xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
  }

  return xmlHttp;
}

function getDataForDIV(url, divID) {
  var xmlHTTP = createXMLHTTP();

  if(!xmlHTTP) {
    alert('sorry, no ajax for you');
    return false;
  }

  xmlHTTP.onreadystatechange = function() {
    if (xmlHTTP.readyState == 4) {
      document.getElementById(divID).innerHTML = xmlHTTP.responseText;
    }
  };

  xmlHTTP.open('GET', url, true);
  xmlHTTP.send(null);
}

function init() {
  getDataForDIV('site1.php', 'div1');
  getDataForDIV('site2.php', 'div2');
  setInterval("getDataForDIV('site1.php', 'div1')", 3000);
  setInterval("getDataForDIV('site2.php', 'div2')", 3000);
}

</script>

...
<body onload="init()">
...
Naposledy upravil 5ulo dne 17. 4. 2008 23:38, celkově upraveno 1
Som "kazisvět šestý" :)))
5ulo
Kolemjdoucí

Odeslat příspěvekod gofry 17. 4. 2008 23:22

Pravda, zmenil som to aj v pôvodnom kóde. Inak v tom tvojom nemusíš mať na úplnom začiatku "var xmlHTTP;", pretože sa to beztak nikde nepoužije.

Fakt škoda, že nie si žena :D Pomilovanie sa vždy hodí :twisted:
gofry
Junior
Uživatelský avatar

Odeslat příspěvekod 5ulo 17. 4. 2008 23:39

okeee.. zeditoval som to .. sedi jak rit na serbli :D
Som "kazisvět šestý" :)))
5ulo
Kolemjdoucí

Odeslat příspěvekod 5ulo 17. 4. 2008 23:52

Ono este som prisiel na jednu vec...
Ak su v js definovane napr. tie dva divy s dvoma roznymi obsahmi a na nejakej inej podstranke jeden z divov vynecham, prejavi sa chba, pretoze js nevie "nahmatat" ten chybajuci div...
Kód: Vybrat vše
document.getElementById(divID) has no properties
document.getElementById(divID).innerHTML = xmlHTTP.responseText;

Inak to nema na funkcnost ziaden vplyv... iba sa dole vo FF pocitaju chyby :/
Som "kazisvět šestý" :)))
5ulo
Kolemjdoucí

Odeslat příspěvekod gofry 18. 4. 2008 00:39

Neošetrovať chyby je veľmi zlá praktika. Vypomstí sa ti to, je to iba otázka času.

V tomto prípade to môžeš ošéfovať tým, že to dáš do bloku try { } catch(e) {}, kde časť catch je prázdna (ale je to Obrázek a zbytočne posielaš requesty na server)

Kód: Vybrat vše
...
try {
  document.getElementById(divID).innerHTML = xmlHTTP.responseText;
} catch(e) {}//prázdne telo, nevadí, že element neexistuje
...


alebo si vytvoríš druhú fciu init2() v ktorej budeš volať iba refresh jedného divu a túto init2() budeš volať miesto init() pri onload stránky, ktorá má iba jeden div,

alebo si upravíš samotnú fciu init(), to je jedno z tých lepších riešení
Kód: Vybrat vše
function init() {

  if(document.getElementById('div1') != null) {
    getDataForDIV('site1.php', 'div1');
    setInterval("getDataForDIV('site1.php', 'div1')", 3000);
  }

  if(document.getElementById('div2') != null) {
    getDataForDIV('site2.php', 'div2');
    setInterval("getDataForDIV('site2.php', 'div2')", 3000);
  }
}
gofry
Junior
Uživatelský avatar

Další stránka

Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků