Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Ajaxilla tiedon haku

Sivun loppuun

Macro [17.08.2009 12:40:07]

#

Olen koittanut saada Ajaxsilla haettua 2 sivua sekunnin välein, mutta minusta ei ole järkevää laittaa 30 rivistä koodia moneen kertaan, jos haluaa vain hakea eri sivuilta tietoa ja asettaa johonkin diviin/tableen tms.
Kysymys: Miten saisin haettua helpoiten monta sivua, ja laitettua ne erikseen eri id:llä varustettuihin elementteihin?

Teuro [17.08.2009 12:54:28]

#

Millä tavalla olet tehnyt tuon, koska ohjelmoinnissa ei pitäisi koskaan joutua tilanteeseen, jossa samaa koodia kirjoitetaan moneen kertaan? Yksi tapa tulee mieleen heti, jossa saat koodin määrää monikäyttöisemmäksi. Teet siis xmlHttpRequest olion globaaliksi, jolloin jokainen koodin osa voi käyttää samaa oliota riippumatta sivusta.

Tällä tavalla saadaan koodia fiksummaksi. Lisäksi jokainen sivu vastaa samalla tavalla responseText / responceXml. Eli oikeastaan tarvitsee ainoastaan specialisoida tulostusfunktiot, joille annetaan jokin tulosjoukko parametrinä.

EDIT Sekoilua poistettu koodista

var vastaus1 = "Tervetuloa teuro";
var vastaus2 = "Säätila tänään helsingissä on +18 *C";

function paivitaElementti(elementti, vastaus){
    document.getElementById(elementti).nodeValue = vastaus;
}

Tuota siis käytetään ihan millä tahansa elementillä, joka vain on määritelty sivulla. Jos tarvetta tulee voi tuosta kirjoitella vielä speciaalisemman version, jos ei siis haluta päivittää koko elementin sisältöä.

Macro [17.08.2009 13:29:51]

#

Löysin linkin tästä vanhasta keskustelusta, jota olen koittanut soveltaa. Tälläistä koitin:

<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8" />
<title>Ajax-haku</title>
<script type="text/javascript">
function paivitaElementti(elementti, vastaus){
    document.getElementById(elementti).nodeValue = vastaus;
}
</script>
</head>
<body>
<a href="javascript:paivitaElementti('testi', 'uusi sisältö');">Päivitä</a><br />
<div id="testi"></div>
</body>
</html>

Joka ei tuottanut tulosta. Olikohan tuo linkitykseni oikein?

Edit. Katos kummaa, kun muutin nodeValuen innerHtml:ksi, niin alkoi pelittämään :)

Teuro [17.08.2009 13:45:03]

#

Jooh mun moka tuo pitäisi laittaa appendChild() metodin avulla tuo tekstisolmu paikalleen, niin pitäisi alkaa toimimaan. nodeValue taisi olla tosiaan readonly tyyppinen tieto.

Macro [17.08.2009 13:51:37]

#

Koitin tehdä tälläistä viritelmää, tuon kasetti.infon koodivinkin perusteella:

<?php
// Date in the past
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

// always modified
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");

// HTTP/1.1
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);

// HTTP/1.0
header("Pragma: no-cache");
?>
<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8" />
<title>Ajax-haku</title>
<script type="text/javascript">
function aseta(elementti, sivu) {
var xmlHttp

function refresh_text(){
    //suoritetaan dataa hakeva funktio
    showText();
    setTimeout("refresh_text()", 2000)
}

function showText(){
    xmlHttp = GetXmlHttpObject();
    if (xmlHttp == null){
        alert ("Selaimesi ei tue AJAXia!");
        return;
    }

    //tässä on sivu josta dataa haetaan
      var url = sivu;

    xmlHttp.onreadystatechange=stateChanged;
    xmlHttp.open("GET",url,true);
    xmlHttp.send(null);
}

function stateChanged() {
    if (xmlHttp.readyState==4){
        document.getElementById(elementti).innerHTML=xmlHttp.responseText;
    }
}

function GetXmlHttpObject(){
    var xmlHttp=null;
    try{
          xmlHttp=new XMLHttpRequest();
      }
    catch (e){
          try
            {
            xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
            }
          catch (e)
            {
            xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
      }
    return xmlHttp;
}
}
</script>
</head>
<body onload="aseta('teksti', 'haettava_sivu.php')">
<div id="teksti"></div>
</body>
</html>

Tämä ei kyllä näyttänyt toimivan. Tuossa kun on funktion sisällä funktioita, niin johtuuko tämä siitä, että elemennti ja sivu muuttujat eivät saa arvoa (?) muissa funktioissa, jolloin se ei voi suorittaa tätä oikein?

Apua kaivataan.

tsuriga [17.08.2009 16:07:06]

#

Et kutsu refresh_text-funkkaria ollenkaan. Monissa esimerkeissä näkyy käytettävän lainausmerkkejä kutsuttaessa setTimeoutissa funktiota, mutta Fx:n Error Consoleen siitä tulostuu erhe, eikä funktio rullaa. Lähtee pois kon laittaa setTimeout(refresh_text, 2000);.

Macro [18.08.2009 08:05:51]

#

IE sanoo "Out of memory at line: 29", jolta löytyy tuo setTimeout.
Missä kohtaa tuota kuuluisi kutsua? Muuten tuo toimii hyvin.
Ja välttämättä minun ei tarvitse saada sitä toimimaan, kuin IE:llä, koska kaveriporukka jolle tämä tulee käyttää IE:tä, mutta olisihan se kiva tehdä ihan validia koodia :)

Laitoin näin, ja hakee vain kerran sivun:

function aseta(elementti, sivu) {
	var xmlHttp;
	var elementti = elementti;
	var sivu = sivu;

	function refresh_text(){
		//suoritetaan dataa hakeva funktio
		showText();
		setTimeout("refresh_text()", 100)
	}

	function showText(){
		xmlHttp = GetXmlHttpObject();
		if (xmlHttp == null){
			alert ("Selaimesi ei tue AJAXia!");
			return;
		}

		//tässä on sivu josta dataa haetaan
		  var url = sivu;

		xmlHttp.onreadystatechange=stateChanged;
		xmlHttp.open("GET",url,true);
		xmlHttp.send(null);
	}

	function stateChanged() {
		if (xmlHttp.readyState==4){
			document.getElementById(elementti).innerHTML=xmlHttp.responseText;
		}
	}

	function GetXmlHttpObject(){
		var xmlHttp=null;
		try{
			  xmlHttp=new XMLHttpRequest();
		  }
		catch (e){
			  try
				{
				xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
				}
			  catch (e)
				{
				xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
				}
		  }
		return xmlHttp;
	}
	refresh_text();
}

Edit. Eikö kukaan tiedä, vai eikö ole ehtinyt vastata? :)

Lebe80 [18.08.2009 09:57:45]

#

Eikös tossakin olisi vaan helpompaa käyttää jotain ajax-kirjastoa, niin tuo pelkkä päivitysosio veisi sen pari riviä ja se tukisi moderneja selainversioita.

Macro [19.08.2009 08:24:40]

#

Voisitko antaa esimerkin, että miten tämän voisi toteuttaa? Mielelläni tekisin kyllä tuon aloittamani koodin loppuun, jos joku vain osaa kertoa, miksi koodi suoritetaan vain kerrran.

Lebe80 [19.08.2009 09:45:11]

#

Prototypejs:llä, en jaksa tähän muiden kirjastojen esimerkkejä laitella (esim. jQuery tai Mootools, jotka olisivat hieman kevyempiä tähän tarkoitukseen)

new Ajax.PeriodicalUpdater(elementti, sivu, {
  method: 'get', frequency: 2, decay: 1
});

Macro [19.08.2009 12:39:20]

#

En oikein tajunnut miten tätä käytetään. Voisitko selventää?

Myös, jos joku kertoisi miten saisin tuon "itse tekemäni" koodin toimimaan. Nyt se siis hakee vain sivun latautuessa tiedot, ja jää siihen.

Edit. Googletin Ajax.PeriodicalUpdater, jonka jälkeen sain käsityksen, ettei tämä toimi Internet Explorerilla.

Lebe80 [19.08.2009 13:23:32]

#

Macro: hyvin googletettu, sillä itsellä ainakin toimii IE:llä.

http://games.terolepisto.net/ajax/

Macro [19.08.2009 13:39:02]

#

Katsos kummaa, kyllä se lähtikin toimimaan. Olin tehnyt pienen virheen.
Tosin, tämä ei toimi oikein kunnolla (Omassa tiedostossa): Kun sivulle menee, niin tällä näkyy vanhentunut aika. Kun sivun päivittää, se häviää. Kun vaihtaa sivua (Alt + tab), ja tulee takaisin sen jälkeen, niin tekstiä näkyy sivulla.

Lebe80: Näytät osaavan aika hyvin näitä asioita, niin näytätkö mitä tuohon koodiini pitää tehdä muutoksia, että alkaa toimimaan? :)

Lebe80 [19.08.2009 14:00:57]

#

Teen tässä nyt samalla hommia mistä maksetaan ihan kuukausittain korvaus, joten en siihen oikein kerkiä. Katsoisitko linkistäni esim. html-lähdekoodista mallia tai vierailemalla vaikkapa prototypejs:n kotisivuilla.

Macro [19.08.2009 15:55:38]

#

Katsoin lähdekoodia (Sieltä bongasin prototype.js tiedoston jonka takia tiedostoni ei toiminut aluksi), ja vierailin tuolla Prototypejs:n sivuilla, kun tuota Ajax.PeriodicalUpdateria googletin.

Jos pitäisi nyt katsoa, että tuo prototype.js on ihan hirmuisen pitkä, ja tuo tuossa aikaisemmin postaamani on ~30, niin siinä on suuri ero. Jos pitäisi saada mahdollisimman kevyt, niin tuolla 30 rivin pätkällä sen saisi, kun saisi päivittymään oikein, ettei vain kerran päivittyisi.


Macro

MIB [19.08.2009 18:26:30]

#

Katos kumma, itselläni sama ongelma. :D Valitettavasti en osaa auttaa.

Metabolix [19.08.2009 21:06:54]

#

Prototypen käyttö ei ole alkuunkaan raskasta suhteutettuna siihen, että lataat sivua parin sekunnin välein.

Funktioiden määrittely toisen funktion sisällä tuolla tavalla on vähintäänkin epäilyttävää, jos koodia on tarkoitus käyttää useassa kohti. Mitähän tuon setTimeoutin kuuluisi sen jälkeen kutsua, kun sille kerran annetaan vain teksti, jossa on funktion nimi? Kokeilepa antaa sille itse funktio (ilman sulkuja ja lainausmerkkejä), ja kokeile lisäksi jäsentää koodisi hieman järkevämmin. Esimerkiksi GetXmlHttpObject on aivan turhaan toisen funktion sisällä.

tsuriga [20.08.2009 00:40:03]

#

Ja varsinkin sen kutsuminen uudestaan ja uudestaan joka sadas millisekunti — riittää, kun luot kyseisen olion vain kerran. Myös muuttuja url on turha. Kyseistä lainausmerkit ja sulut pois -ratkaisua tarjosin itsekin tuossa pari päivää sitten, tosin vähän turhan epäsuorasti kun en itse IE:llä kerennyt testaamaan, enkä nimityksistäkään ollut/ole satavarma. Eli setTimeout vaatii parametrikseen merkkijonon sijaan callback-funktion. Tiedä sitten millä selaimella lainausmerkit ovat aikoinaan toimineet kun noita esimerkkejä löytyy pilvin pimein.

Macro [20.08.2009 09:38:42]

#

Jos mielestänne tuon prototypen käyttö on kevyempää, niin voihan sitä koittaa ymmärtää. Onhan siinä suuri ero, että te olette koodanneet vuosia, ja minä vasta hetki sitten aloitin, joten varmaan pitää teitä uskoa.

tsuriga: Ainakaan IE7 ei ole tarvinnut mitään erillisiä funktioita lisäksi, se toimii sellaisenaan kuin kasetti.infossa esitettiin. Jos otan lainausmerkit pois, niin käy niin, että IE ei ymmärrä sitä nähtävästi ja sanoo "Out of memory".

Katsonmitä voin tehdä tuon prototypen kanssa, että saanko toimimaan.

Silti kiinnostaa saada tuo oma juttu valmiiksi, koska ei ole ollut tapana jättää mitään keskeneräiseksi. Siinä samalla oppisi lisää tuota Ajaxia.

Edit. Taas kävi niin, että netti sammui, kun tuli sen 0,1 sekunnin välein alerttia...

Edit. Aiemmin kun tsuriga mainitsi, että pitää ottaa lainausmerkit pois, ja sanoin ettei IE toimi sen kanssa, niin en huomioinut hänen esimerkkiään.
Oli jäänyt ne sulut siihen funktion perään setTimeoutissa. Kiitos siitä tsurigalle :)

Ps. En tiennytkään että JavaScript ja Ajax ovat näin jänniä kieliä.

Teuro [20.08.2009 10:17:24]

#

Mikäli haluat tuon oman koodisi toimimaan helpolla, niin voisit verrata koodiasi tuohon putkassa olevaan ajax-oppaaseen. Siitä selviää nimittäin helpolla merkittävimmät virheet. Suurin osa virheistä täällä onkin jo selvitetty sinulle. Muun muassa funktiot funktion sisällä -> huono asia.

Yleensä valmiiden kirjastojen käyttö on nopeampaa, kuin omat sävellykset. Tuon koodin koko saattaa aiheuttaa sinulle mielikuvan raskaasta ja hitaasta käytöstä - jota se olisikin, jos koodi olisi ns. inline koodia ts. sivun lähdekoodiin kirjoitettua. Nyt kun tuo javascript koodi on eristetty omaan tiedostoonsa voi selain hakea koko koodin omaan muistiinsa, josta funktion kutsuminen on nopeaa.

Lisäksi usein valmiit kirjastot on testattu useimmilla selaimilla toimiviksi, joten rajapinta koodaajalle on samanlainen riippumatta selaimesta.

Macro [20.08.2009 14:52:44]

#

Heh, vahingossa kirjoitin "väärään" paikkaan "väärää" tekstiä, ja alkoi toimimaan :) Kiitos kaikille avusta, teistä oli apua suuresti.

Tässä vielä koodi, ettei kukaan enään törmäisi samaan ongelmaan:

<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Ajax-haku</title>
<script type="text/javascript">
function hae(elementti, sivu) {
	var paivita = 100;
	var xmlHttp;

	function refresh_text(){
		showText();
		setTimeout(refresh_text, paivita);
	}

	function showText(){
		xmlHttp = GetXmlHttpObject();
		if (xmlHttp == null){
			document.write("Selaimesi ei tue Ajaxia!");
			return;
		}

		xmlHttp.onreadystatechange=stateChanged;
		xmlHttp.open("GET",sivu,true);
		xmlHttp.send(null);
	}

	function stateChanged() {
		if (xmlHttp.readyState==4){
			document.getElementById(elementti).innerHTML=xmlHttp.responseText;
		}
	}

	function GetXmlHttpObject(){
		var xmlHttp=null;
		try{
			  xmlHttp=new XMLHttpRequest();
		  }
		catch (e){
			  try
				{
				xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
				}
			  catch (e)
				{
				xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
				}
		  }
		return xmlHttp;
	}
	refresh_text();
}
</script>
</head>
<body onload="hae('teksti', 'haettava.php');">
Sivu 1, haettava.php:<hr>
<div id="teksti"></div> <br>
</body>
</html>

Esimerkki, haettava.php:

<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");

$sanat = array("PHP", "HTML", "XHTML", "CSS", "JavaScript", "Ajax", "Java", "Flash");
shuffle($sanat);

echo "Ohjelmointikieliä: " . $sanat[0];
?>

Koitan vielä poistaa nuo funktiot, tuon toisen sisästä, mutta pääasia että toimii :)

Ps. Miten saisin taulukon maxsimi korkeudeksi esim 100 px (height="100"), niin että tulisi scrollbar jos menee yli korkeuden sen sisältö? Kuin textarea, mutta taulukkona/divinä.

Macro [20.08.2009 19:12:46]

#

Sen verran vielä, että tarkoitus tuolla oli joku chat väsätä. No, toimiihan se ihan kivasti, mutta kun lähettää viestin, niin se vilkahtaa ärsyttävästi. Miten tuollaisen voisi saada pois?

Ja sitten vielä toi äskeinen viestini, että mitenköhän voisi sen scrollbarin saada?

Edit.
Hoksasin tuon scrollbar jutun, mutta se taulu venyy koko ajan jos on liikaa tavaraa putkessa:

<table width="400" style="overflow-y: auto; overflow-x: hidden; border: 1px solid black;">
<tr><td>
MoikkajeemoiMoikkajeemoiMoikkajeemoiMoikkajeemoiMoikkajeemoi
MoikkajeemoiMoikkajeemoiMoikkajeemoiMoikkajeemoiMoikkajeemoi
MoikkajeemoiMoikkajeemoiMoikkajeemoiMoikkajeemoiMoikkajeemoi
MoikkajeemoiMoikkajeemoiMoikkajeemoiMoikkajeemoi
</td></tr></table>

Miten tuon sitten voisi korjata, että ei mene yli taulun leveyden?

MIB [22.08.2009 09:59:44]

#

Macro kirjoitti:

... Tässä vielä koodi, ettei kukaan enään törmäisi samaan ongelmaan ...

Kiitos sinulle, sain omankin ongelman ratkaistua.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta