Autor Zpráva
xxxObiWan
Profil
Ahoj,
snažím se o jednoduchou věc.
1) Pomocí jQuery.ajax() načíst nějakou stránku (ze stejného serveru samozřejmě).
2) Z vráceného HTML vybrat nějaký element a zobrazit jeho kód.

Vůbec se mi to ale nedaří, vždy se mi zobrazí jen `null`. Myslím, že problém bude v příkazu `jQuery('selector', data)`, který daný prvek prostě neumí vybrat.

Živá ukázka: http://jquery.jslab.net/zkousecka/#28d09161325a5d03c9bf261afb3d3626

Děkuji moc za rady.
_es
Profil
xxxObiWan:
Z vráceného HTML vybrat nějaký element a zobrazit jeho kód.
To už z princípu nie je dobrý nápad. Prečo nespravíš taký serverový skript, ktorý vráti len to, čo je treba?
xxxObiWan
Profil
_es: Normálně používám Nette, který toto umí.

Teď jsem ale potřeboval do školy udělat ukázku čistě JavaScriptového AJAX přístupu. A ouha, jQuery zklamalo. Nějaké nápady, proč to nefunguje, jak má?
Chamurappi
Profil
Reaguji na xxxObiWana:
V data je řetězec, ne? Nikoliv kus DOMu. Proč by to mělo nějak fungovat?
Stejně je to špatný nápad. Pokud chceš předávat JavaScriptu strukturované informace, předej je jako JS strukturu a ne jako HTML.
_es
Profil
xxxObiWan:
Asi by si mal najprv naštudovať základy JS a dokumentáciu jQuery - keď si sa rozhodol túto knižnicu používať.

Myslím, že problém bude v příkazu `jQuery('selector', data)`
Čo si čakal, že ten výraz vráti? Vrátené dáta máš v premennej data. Čo funkcia jQuery robí, či nerobí, si môžeš zistiť v dokumentácii: http://api.jquery.com/jQuery/

Objekt XMLHttpRequest, a teda aj jQuery obal toho objektu, spracúva odpoveď zo serveru ako text, alebo ako neveľmi používaný objekt - XML strom. Ak server vráti HTML, tak ho buď spracuješ ako textový reťazec, alebo nejako pridáš do nejakého HTML dokumentu a potom môžeš použiť metódy DOM.
xxxObiWan
Profil
_es:
Asi by si mal najprv naštudovať základy JS a dokumentáciu jQuery

Jak myslíš, cituji z dokumentace: "Internally, selector context is implemented with the .find() method, so $('span', this) is equivalent to $(this).find('span')."

Takže jQuery('<html><body><div></div></html>').find('div') by mělo fungovat, protože (opět cituji z dokumentace):
"jQuery( html [, ownerDocument] )
html: A string of HTML to create on the fly.
"

Chamurappi:
Proč by to mělo nějak fungovat?
Protože třeba tady to funguje ;-) http://jquery.jslab.net/zkousecka/#170f4012928cb9f11f1cb77eaf07aa00
A taky proto, že podle dokumentace by to "nějak" fungovat mělo, viz výše.
_es
Profil
xxxObiWan:
cituji z dokumentace: "Internally, selector context is implemented with the .find() method, so $('span', this) is equivalent to $(this).find('span')."
Ale this v tom ukážkovom kóde nie je textový reťazec.

Protože třeba tady to funguje
No ale z toho, že ti nejaký pochybný kód, bez opory v dokumentácii skriptu, nejako funguje, nevyplýva, že by mal fungovať bezchybne. Overil si si vôbec, či ten výsledok pochádza z dát zo servera a nie z dokumentu? Lebo tam sa taký element tiež nachádza.
xxxObiWan
Profil
Pak tedy využiju jQuery, aby naparsoval získaná data (viz dokumentace) a v nich pak budu vyhledávat.
Výsledek: http://jquery.jslab.net/zkousecka/#32c5ec39e456c90bc1b8060fe68d5c01

Přesto pořád vrací NULL. V čem je tedy chyba?

EDIT: Ještě trochu jinak napsáno - víc "podle dokumentace" to snad už ani být nemůže.
_es
Profil
xxxObiWan:
V čem je tedy chyba?
V tom, že musí ísť o objekt DOM elementu v nejakom dokumente. Objekt v premennej $parsed nie je začlenený v nijakom dokumente. Mimochodom, premenné nemusia mať prvý znak dolár - to sa ti asi pletie odinakiaľ.

ukázku čistě JavaScriptového AJAX přístupu
„AJAX prístup“ predsa nevyžaduje analýzu HTML kódu vráteného zo servera, lepšie asi bude postupovať podľa rady v [#4].
xxxObiWan
Profil
Mimochodom, premenné nemusia mať prvý znak dolár - to sa ti asi pletie odinakiaľ.
Vím, ale bývá taková konvence, že proměnné, obsahující jQuery object, začínají dolarem. Čistě pro přehlednost. (zdroj: Yablkův tutoriál)

musí ísť o objekt DOM elementu v nejakom dokumente
O tom v dokumentaci nic nevidím. A to, že prohledávaná struktura nemusí být součástí dokumentu, dokazuje i tento příklad v dokumentaci (stačí, že struktura je uložena v nějaké proměnné).

„AJAX prístup“ predsa nevyžaduje analýzu HTML kódu vráteného zo servera
Pokud nechci upravovat serverovou část (učit jí, aby vracela např. JSON), pak vyžaduje.
_es
Profil
xxxObiWan:
A to, že prohledávaná struktura nemusí být součástí dokumentu, dokazuje i tento příklad v dokumentaci (stačí, že struktura je uložena v nějaké proměnné).
To som písal už v [#5], že server môže vrátiť XML, xml.responseXML nie je textový reťazec.
xxxObiWan
Profil
Takže, vážení, po dlouhé diskuzi nabízím konečně funkční řešení problému ;-)

1) jQuery při použití metody find() nevyhledává kořenové elementy, protože vytvořený jQuery object představuje právě tento kořenový element. A tak se vyhledává v něm (zdroj). Místo
$parsed = jQuery(data);
$frame = $data.find('#frame');  // #frame" je přímo v <body>, takže není nalezen

je potřeba napsat toto, aby bylo vyhledávání možné i v nejvyšších elementech
$parsed = jQuery('<div/>').append(data);
$frame = $data.find('#frame');  // #frame už není nejvyšší element, takže vše funguje

Viz funkční příklad.

2) Bohužel, jQuery má ve funkci append() problém přidávat do dokumentu tagy <script>. Z tohoto důvodu nám kód nebude fungovat třeba i na české jQuery zkoušečce (můžete vyzkoušet). Musíme tedy tyto tagy vyfiltrovat. Konečný (a snad už všude fungující) kód tak bude vypadat nějak takto:
$parsed = jQuery('<div/>').append( jQuery(data).not('script') );
$frame = $data.find('#frame');

Viz funkční příklad.

Děkuji všem za snahu.
_es
Profil
xxxObiWan:
konečně funkční řešení problému
No - to je asi tak funkčné, že pri takomto pochybnom „riešení“ môžeš očakávať ďalšie problémy - napríklad s definovaním kódovania textu prijatých dát, ten kód asi nevytvorí rovnocennú štruktúru s celým dokumentom - ako by vo vnútri <div>u mohol byť napríklad <head> či <html>? Teda je aj veľká pravdepodobnosť, že to bude v rôznych prehliadačoch, v závislosti od vrátených dát, „fungovať“ rôzne.

„AJAX prístup“ predsa nevyžaduje analýzu HTML kódu vráteného zo servera
Pokud nechci upravovat serverovou část (učit jí, aby vracela např. JSON), pak vyžaduje.
„AJAX prístup“ vyžaduje rozumnú spoluprácu klienta a servera a nie aby robil prehliadač klienta hentaké ohavnosti, server odosielal a prehliadač prijímal zbytočné dáta, zbytočné zaťažovanie prehliadača - efektívnosť toho JS kódu bude veľmi slabá...
xxxObiWan
Profil
"„AJAX prístup“ vyžaduje rozumnú spoluprácu klienta a servera"
To nemusí být pravda. A pokud nevěříš mě, tak věř třeba Davidu Grudlovi. Můžou se stát situace, že přebíráš web po nějakém škaredém programátorovi, v jeho hnusném PHP/Java/Whatever kódu se vůbec nevyznáš, ale klient po tobě chce AJAXové chování. Anebo používáš redakční systém třetí strany a máš možnost měnit jen šablony.
Jasně, tenhle způsob implementace AJAXového chování není ideální. Ale nezatracujme ho.
_es
Profil
xxxObiWan:
tenhle způsob implementace AJAXového chování není ideální
Je už v základe vadný a chybný. Napríklad, čo myslíš - prečo je HTML kód zobrazený v alerte v tom „funkčnom príklade“ odlišný od kódu súboru, ktorý je sťahovaný? Plus všetky ďalšie možné problémy. No ale, kto chce kam...
xxxObiWan
Profil
_es: A jak bys to řešil ty, v případě že bys neměl možnost upravovat chování serveru?

Btw, myslím že alert() nedokáže správně zobrazit například znak "\t", tak proto. Kódování je v pořádku (zkoušel jsem si získané HTML vypsat do textarey a zobrazilo se bez problému).
_es
Profil
xxxObiWan:
myslím že alert() nedokáže správně zobrazit například znak "\t", tak proto.
Treba si pozorne všímať rozdiely, treba vyskúšať rôzne prehliadače. A nemôžeš vedieť, nakoľko bude sťahovaný kód „divoký“ a ako ho tie jQuery metódy, nevhodné na tento účel, spracujú.

Kódování je v pořádku
Čo nemusí platiť pre iný, takýmto spôsobom sťahovaný obsah - skús napríklad použiť iné ako UTF-8 kódovanie a definovať ho len v meta značke.

jak bys to řešil ty, v případě že bys neměl možnost upravovat chování serveru?
Nemusíš chovanie serveru „upravovať“, stačí tú funkčnosť na serveri doplniť, teda spraviť serverový skript, ktorý bude vracať dáta v rozumnej forme. Trebárs môže aj analyzovať HTML kód a dávať z toho nejaký výstup. Síce to bude tiež pochybné riešenie, no menej ako to predtým.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: