rss

Univerzální funkce pro AJAX

14. 3. 2007

ajax

AKTUALIZOVÁNO - díky komentujícím a hlavně Adamovi Hořčicovi.

Jak AJAX funguje jsem už popsal, nyní bych vám chtěl ukázat jak ho používám já. Napsal jsem si jednoduchou univerzální funkci, kterou pak lze kdykoliv použít. Jinak upozorňuji, že tento článek je opět pro začátečníky.

Takže tohle je ono - jsou ty dvě funkce jako minule, ale trochu vylepšené:

function ajax(stranka, kam)
{

    var httpRequest;
    
    if(typeof window.ActiveXObject != 'undefined')
    {
        httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else
    {  
        httpRequest = new XMLHttpRequest();
    }
    httpRequest.open("GET", stranka, true);
    httpRequest.onreadystatechange= function () 
    {
        processRequest(httpRequest, kam) 
    };
    httpRequest.send(null);
}


function processRequest(httpRequest, kam) 
{
    if (httpRequest.readyState == 4)
    {
        if(httpRequest.status == 200)
        {
            if (typeof kam == 'string') 
            {
                document.getElementById(kam).innerHTML = httpRequest.responseText;
            }
            if (typeof kam == 'function') 
            {
                kam(httpRequest.responseText);
            }
        }
        else
        {
            alert("Chyba pri nacitani stanky " + httpRequest.status +" : "+ httpRequest.statusText);
        }
    }
    else
    {
        if (typeof kam == 'string' && kam != '') 
        {
            document.getElementById(kam).innerHTML = '?ekejte...';
        }
    }
       
} 

Funkce ajax zavolá soubor zadaný ve formě URL v parametru stranka. Výstup tohoto souboru pak můžeme zpracovat dvěma způsoby:

  • Použít ho jako obsah do elementu v HTML tak, že vyplníme ID tohoto elementu do parametru kam.
  • Použít ho jako parametr zvolené funkce, kterou jsme si někde napsali (čili existuje) a jejíž název napíšeme opět do parametru kam. Zadává se jen název funkce bez závorek a nepíše se to do apostrofů. Funkce bude potom zavolána jako když má jeden parametr - výstup souboru. Tedy zadáme-li jako parametr kam například mojefunkce, bude nakonec zavolána funkce mojefunkce('nejaky vystup')

Příklad

Všechno si můžete samozřejmě vyzkoušet na příkladu.

Vytvořil jsem si tam tedy nějakou svoji funkci mojefunkce, která je pak zavolána a vložen do ní výstup AJAXu:

function mojefunkce(parametr)
{
    alert(parametr);
}

Jenom pro informaci, soubor ajax-obsah.php, který se v příkladu zpracovává vypadá takto:

<?php

sleep(1);

if ($_GET['vystupdofunkce'])
{
    echo "Ahoj, toto je parametr funkce";
}
else
{
    echo "Toto je vystup volaneho souboru";
}

?>

Ještě detail

Někdo bystrý si možná všiml, že oproti příkladu v minulém článku obsahuje ještě první funkce něco navíc. Je to deklarace proměnné: var httpRequest;. Zjistil jsem totiž, že pokud tam tohle nemáte a na nějaké stránce zavoláte několik funkcí ajax najednou, vykonají se asi jenom dvě, ostatní "uvíznou". Tímto se správně nadeklaruje každý objekt XMLHttpRequest(), který se "děje" paralelně se všemi ostatními a vše funguje správně, můžete se například podívat na zjišťování volných domén, kde jsem to použil.


Komentáře

lukyn.v

Jen pro informaci, kdyby náhodou. ;) Opera 9.10 s výše uvedeným skriptem a se zjiťováním volných domén na Blueboardu má trochu problémy. Funguje to tak nějak napůl. Vypíše náhodně jen některé možné domény. Nejsem odborník, tak nevím, má-li Opera problémy s AJAXem celkově nebo jen s tímto skriptem. FF 2 a IE 7 jsou OK.

Jakub Vrána

Ve funkci ajax() by se mělo testovat, jestli se objekt podařilo vytvořit.

Proč se v metodě open() prefixuje stranka "./"?

V ukázce kódu asi vypadlo zpětné lomítko - '('' není syntakticky správně.

Používání eval() není zrovna nejšťastnější. Co kdyby vrácený text obsahoval třeba apostrof? Proč se předaná funkce zkrátka nezavolá?

Co když by funkce chtěla raději pracovat s responseXML? Proč se jednoduše nepředá celý objekt httpRequest?

Viz můj článek na stejné téma.

Medhi

Jakub Vrána [2]: Díky za připomínky,

./ jsem odstranil, opravdu zbytečné.

Bohužel nevím jak funkci rovnou zavolat, budu rád, když poradíš.

Zpětná lomítka jsem doplnil.

K ostatnímu, i tvému článku bych asi jen řekl, že to není moc pro začátečníky, i když samozřejmě na profesionální úrovni, já jsem v tomto amatér.

Vojtěch Semecký

Ahoj, když máš jméno funkce v proměnné, tak tu funkci zavoláš prostě tak, že za proměnnou přidáš závorky a případné parametry. Např.:

$f = "MojeFunkce";
$f();

Ten druhý řádek zavolá funkci MojeFunkce(). V helpu PHP je to popsáno v kapitole Variable functions.

Medhi

Vojtěch Semecký [4]: Ale tady se nejedná o PHP, nýbrž JavaScript.

Ivo Toman

Hezké, konečně někdo na weblogy píše zajímavé informace .

Mordae

Pouzije se jen jeden argument -- kam a bude se testovat, pomoci typeof zda-li jde o 'function', kdy potom budeme volat proste kam(vystup), nebo zda-li jde o 'object', kdy odstranime vsechny jeho pod-uzly a vytvorime nove z odpovedi (vyhnete se innerHTML, nefunguje v XML modu FF) a konecne stejne provedeme i pokud jde o 'string', pouze objekt nejprve ziskame pomoci getElementByID(kam).

Kdysi jsem to psal a zase ztratil. Moc pekne to vymyslel take Chose, ten ovsem posila z PHP primo skript, ktery vola definovany receptor na strance. Libilo se mi to daleko vic, nez AJAX, ale to jen tak na okraj… :] http://www.chos...pres-javascript/

Jakub

Pro začátečníka s AJAXem jako jsem já je to VELMI přínosné !
Děkuji.

Radek Hulán

Pro AJAX používám XHConn objekt, převzatý. Nicméně, doporučuji se podívat třeba sem, jak se pracuje s AJAXem a DOM (vyšší dívčí) ;-)

http://hulan.cz/styles/radekhulan.cz/script/script-item.js

Jakub Vrána

Medhi [5]: V JavaScriptu se to používá identicky.

Medhi

Jakub Vrána [10]: Zkoušel jsem to ale nepodařilo se mi.. nevíš o nějaké ukázce? Jak to může používat identicky, když JS nepoužívá znak $?

Díky moc. Hned jak řešení zjistím do příkladu ho doplním.

ah01

S tou univerzálností bych to moc nepřeháněl, ale pro jednoduché úkoly to může stačit. Řekl bych, že hlavně pro začátečníky to může být přínosné.

Nicméně si neodpustím zmínit, že toto použití eval je prostě ohavnost! Jsem rád, že se u nás konečně začíná více psát o modernám JavaScriptu, ale takovéto konstrukce by se prostě používat neměly.

Pokud si s tím, jak tohle odstranit (ideální by byla metoda, kterou popisuje v reakci Mordae [7]: ), nevíš rady, klidně mi napiš (mail, icq ? viz web). Rád ti pomůžu.

tom

ahoj zaujal me test tech domen, nemas kousek kodu jak se dotazujes do centralniho registru na ty domeny ?

podle se musis na kzdy typ domeny ptat jineho serveru … nebo se pletu ?

jinak AJAX je super …

tom

ahoj zaujal me test tech domen, nemas kousek kodu jak se dotazujes do centralniho registru na ty domeny ?

podle se musis na kzdy typ domeny ptat jineho serveru … nebo se pletu ?

jinak AJAX je super …

berkof

Zkoušel jsem rozchodit tento příklad, ale nějak mi to moc nefunguje:

  • do tagu jsem vložil Vaší univerzální funkci
  • pak jsem ji v souboru aja.html v tagu span> zavolal s parametrama:

span onclick="ajax('ht tp://localhost/pokus/ajax/zdroj.html','raz');" style="cursor: hand; cursor: pointer"> tlacitko 1 /span>
div id="raz"> tady 1 /div>
hr>

  • v souboru zdroj.html je několik divů a jeden z nich má id="raz"

chápu tedy dobře, že na pozadí přenese z tohoto divu v souboru zdroj.html
obsah a vloží ho do souboru aja.html?

chyby:

  1. vloží mě tam všechny divy ze souboru zdroj.html
  2. pokud chci na jiném místě aktualizovat jinej div s jiným id tak mě pořad aktualizuje jen ten první div a to navíc tak že k němu obsah přičítá

poradíte mi v čem je chyba? moc prosím

p.s. odstranil jsem některé lomené závorky aby se to zobrazilo

gindar

Mám jen drobnou připomínku. Vytvoření objektu XMLHttpRequest je trochu složitější. MS používá dva ruzné ActiveX objekty, nevím který prohlízeč používá který. Osobně řeším pomocí try a catch (méně IFů)

var ajaxreq;

if (window.XMLHttpRequest) {
ajaxreq = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
ajaxreq = new ActiveXObject('Microsoft.XMLHTTP');
} catch(e) {
ajaxreq = new ActiveXObject('Msxml2.XMLHTTP');
}
} else {
… něco co nahlásí že ajax není podporován apod. …
}

joell

Ahoj, ví někdo co se stane když server z nějakého důvodu nedokončí požadavek (poslaný metodou post), tím myslím že readyState se zastaví třeba na 3, nikdy nedostane 4. Stává se mi občas, že na jedné stránce kde používám XMLHttpRequest, zatuhnou všechny linky, prostě se pak z té stránky nehnu ani ručně zadanou adresu to nebere.
Říká Vám to někomu něco?

Antonín Daněk

Děkuji autorovi článku a taky gindarovi ;)

Konstantin Maltsev

Ahoj lidi, celkem zajimavy clanek, ale mam jednu otazku.

Kdyz volam nejaky soubor pomoci AJAX, tak jak muzu tomu souboru predat promenne POST ?

Treba mam formular a mam tam $_POST[nazor1], $_POST[nazor2]

A chci tyto promenne predat souboru pracuj.php pomoci POST, ten zjisti co z promennyma ma delat, a pak vrati odpoved ?

gindar

Konstantin Maltsev [19]: Nějak tak:
httpRequest.open("POST", url, true);
httpRequest.send('a=2&b=1&c=5');
httpRequest.setRequestHeader("Method", "POST " + uri + " HTTP/1.1"); //hlavička není povinná

Jirka

Zdravím, použil jsem tuto metodu na svých stránkách, nebo spíš se snažím toto použít, jen nevím, jak to ošetřit, aby to fungovalo při zaklázaném javascriptu…
Jsem tak trochu lama, tak prosím, pokud se najde někdo, kdo by mi chtěl pomoct, trochu míň složitě a odborně.

Jirka

Zdravím, použil jsem tuto metodu na svých stránkách, nebo spíš se snažím toto použít, jen nevím, jak to ošetřit, aby to fungovalo při zaklázaném javascriptu…
Jsem tak trochu lama, tak prosím, pokud se najde někdo, kdo by mi chtěl pomoct, trochu míň složitě a odborně.

Thomas123

Návod je super a po pár úpravách mi postačí k mému účelu.

Jan Wohlgemuth

Moc děkuju za univerzální fuknci. Dnes jsem se s prvopočátky AJAXu dost natrápil a první funkční prototyp jsem vytvořil až díky vaší funkci. Díky!

Matouš M.

Opět mi tyto stránky posloužily. Dík za jednoduchý a názorný úvod do problematiky!

honza

Jakub Vrána [2]: Mám pocit že ten Váš článek na Root.cz je spíše pro ty co už všechno ví. Nic proti, ale pár vysvětlivek, nebo popisků navíc by Vás nezabilo, a hodně lidem pomohlo. Myslím že to vede k tomu, že lidi bezmyšlenkovidě kopírují (protože do toho nevidí) a pak se diví že to ne a ne fungovat?

Michal008

Ahoj, zajímalo by mě jestli by šel vytvořit httprequest (ne ve funkci) a poté po něm jen přenášet, aby se pokaždé nemusel navazovat. Je mi jasné, že by to asi nešlo při přenášení několika souborů najendou, ale pokud by se přes tu proměnnou httprequest pokaždé načátala jen jendna stránka fungovalo by to?

Jedná se mi o to, že v aplikaci (myslím třeba C++) není problém vytvořit httprequest a poté po spojení načítat v tomto proudu soubory(stránky).

Myslím že by to tu hodně potěšilo uživatele, kteří načítají pomocí této varianty několikrát za sebou. (vycházím z toho, že funkce pokaždé naváže nový request)

JH

Díky za článek, nedaří se mi poslat php skriptu pomocí AJAX pole čísel pro uložení do databáze, řeží se to zde http://diskuse.jakpsatweb.cz/??

Kdyby s tím měl někdo zkušenost, budu vděčný za radu. Díky!


Archiv