Autor | Zpráva | ||
---|---|---|---|
Fisir Profil |
Ahoj,
vytvářím skript, který zjistí titulek všech stránek na mém webu (projede odkazy na stránce a ignoruje ty, co v sobě mají http:// ). Cyklem se dotazuje mého serveru, který mu titulek v prostém textu vrátí. Když však JavaScriptový kód spustím, vyhodí to: TypeError: Cannot read property '7' of undefined
function getTitles(){ var tag = "a"; var pole = document.getElementsByTagName(tag); for(i = 0; i < pole.length; i++) { if(pole[i].href.search(/http:\/\//) == -1 && pole[i].href.search(/javascript:/) == -1){ if(pole[i].title == "" || !pole[i].title){ var xmlhttp,titulek; if (window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); } else { xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); }; xmlhttp.onreadystatechange=function(){ if(xmlhttp.readyState==4 && xmlhttp.status==200){ titulek = xmlhttp.responseText; pole[i].title = titulek; }; }; xmlhttp.open("GET",".href,true]http://www.j-jaburek.tk/etc/title.php?url=".pole[i].href,true); xmlhttp.send(); }; }; }; }; |
||
Darker Profil |
#2 · Zasláno: 7. 7. 2012, 23:01:16 · Upravil/a: Darker
xmlhttp.open("GET",".href,true]http://www.j-jaburek.tk/etc/title.php?url=".pole[i].href,true); Proč to hledáš cyklem? Proč radši z titulek.php nenačteš titulky všech HTML dokumentů? Nebo, alespoň, proč si nejdřív nenačteš všechny HTML odkazy a pak nezjistíš všechny titulky najednou? Tohle je fakt trochu prasárna... var tag = "a"; //Mám za to, že tohle je zbytečnost. var pole = document.getElementsByTagName(tag); |
||
Fisir Profil |
#3 · Zasláno: 8. 7. 2012, 09:02:14
Reaguji na Darkera [#2]:
„Tady tenhle řádek vypadá dost divně.” První označený úsek zmršila diskuse. To druhé, to je jasně špatně, takhle se spojují řetězce v PHP. „Proč radši z titulek.php nenačteš titulky všech HTML dokumentů?” To by nebylo ohleduplné vůči množství odkazů na jedné stránce. Domů se dostanu až za týden, takže to vyzkouším později (jsem bez notebooku na táboře). |
||
Darker Profil |
#4 · Zasláno: 8. 7. 2012, 17:52:18
Fisir:
„To by nebylo ohleduplné vůči množství odkazů na jedné stránce.“ A stahovat je postupně je ohleduplnějčí čím? Jde mi o to, abys nevytvářel tolik požadavků a titulky stáhl v jedné dávce. |
||
Časová prodleva: 6 dní
|
|||
Fisir Profil |
Nyní mám tento kód:
function getTitles(){ var pole = document.getElementById("pageContent").getElementsByTagName("a"); var links = ""; for(i = 0; i < pole.length; i++) { if( pole[i].href.search(/j-jaburek.tk/) != -1 && pole[i].href.search(/javascript:/) == -1 && pole[i].href.search(/mailto:/) == -1 ){ if(pole[i].title == "" || !pole[i].title){ var xmlhttp,titulek; if (window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); } else { xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); }; xmlhttp.onreadystatechange=function(){ if(xmlhttp.readyState==4 && xmlhttp.status==200){ if(xmlhttp.responseText != "" || xmlhttp.responseText != "Externí weby nejsou podporovány!"){ pole[i].title = xmlhttp.responseText; }; }; }; xmlhttp.open("GET",".href,true]http://www.j-jaburek.tk/etc/title.php?url="+pole[i].href,true); xmlhttp.send(); }; }; }; }; Nechápu ovšem, proč nefunguje: Uncaught TypeError: Cannot set property 'title' of undefined (řádek 20). První označený úsek je problémový řádek, druhý je chyba diskuse.
|
||
Keeehi Profil |
#6 · Zasláno: 14. 7. 2012, 14:26:18
Protože je to v anonymní funkci. Pokud 2. řádek vyhodíš vně funkce getTitles(), měla by být proměnná pole viditelná globálně a pak i v té anonymní funkci.
|
||
Fisir Profil |
Reaguji na Keeehiho [#6]:
Hodil jsem řádek var pole = document.getElementById("pageContent").getElementsByTagName("a"); před function getTitles(){ . Ukazuje to více chyb:
Uncaught TypeError: Cannot call method 'getElementsByTagName' of null ja.js:40 Uncaught TypeError: Cannot read property 'length' of undefined ja.js:43 |
||
Keeehi Profil |
#8 · Zasláno: 14. 7. 2012, 14:40:44
1. chyba souvisí s tím, že v době volání
getElementById("pageContent") ještě element s id="pageContent" neexistuje. Tento javascript přesuňte až za ten element. Jistota je těsně před </body>
2. chyba souvisí s tou první a až tu první vyřešíte, 2. zmizne sama. |
||
Fisir Profil |
#9 · Zasláno: 14. 7. 2012, 14:58:14
|
||
Keeehi Profil |
#10 · Zasláno: 14. 7. 2012, 15:05:10
Prosím o odkaz na živou ukázku.
|
||
Fisir Profil |
#11 · Zasláno: 14. 7. 2012, 15:08:47
|
||
Keeehi Profil |
Fisir:
„Je stále stejný“ Omlouvám se, to jsem přehlédl. Zapomněl jsem, že také i není vidět v té anonymní funkci. Tím se to trochu komplikuje. Ajaxový požadavek musí vypadat takto: xmlhttp.open("GET","ht tp://ww w.j-jaburek.tk/etc/tit le.php?url="+pol e[i].href+"&i="+i);
A odpověď takto: {"i":"5","title":"titulek"} - to číslo za i je jen zkopírované to, co se posílá v tom požadavku.
if(xmlhttp.responseText != "" || xmlhttp.responseText != "Externí weby nejsou podporovány!"){ var odpoved = JSON.parse( xmlhttp.responseText ); pole[odpoved.i].title =odpoved.title; }; |
||
Fisir Profil |
Reaguji na Keeehiho [#12]:
Vypadá to, že to stále nefunguje. A vůbec, jakto, že tam není vidět, když je deklarována (stejně jako pole ) před tímto cyklem?
var odpoved = JSON.parse( xmlhttpt.responseText ); |
||
Keeehi Profil |
i není vidět, protože je deklarovaná ve funkci, takže platí jen uvnitř té funkce. Kdyby jsi ji stejně jak pole, vystrčil před funkci, už by vidět byla, ovšem její hodnota by byla rovna pole.length jelikož ajax je asynchronní a cyklus by nejspíše skončil dřív, než by se prováděla ta anonymní funkce.
Nefunguje to, protože není ošetřená adresa, která se vytváří: xmlhttp.open("GET","http://www.j-jaburek.tk/etc/title.php?url="+encodeURIComponent(pole[i].href)+"&i="+i); Na vytváření té odpovědí existuje v php funkce echo json_encode(array("i"=>$_GET["i"], "title" => $zjstenyTitulek)); |
||
Fisir Profil |
#15 · Zasláno: 14. 7. 2012, 17:02:02
Reaguji na Keeehiho [#14]:
„existuje v php funkce“ Já vím. V PHP skriptu je použita. Děkuji ti, ale má to stále mouchy. Titulek se zjistí pouze pro poslední odkaz na stránce. (Přesněji: Dotazy se pošlou na server všechny, ale title se přidá pouze k poslednímu odkazu.)
|
||
Chamurappi Profil |
#16 · Zasláno: 14. 7. 2012, 17:08:41
Reaguji na Keeehiho:
„Ajaxový požadavek musí vypadat takto“ Nemusí. Stačí, když si někde udrží hodnotu proměnné i , posílat si ji tam a zpátky přes server je divné.
Reaguji na Fisira: Za koncem if ů a funkcí děláš zbytečně středníky.
|
||
Keeehi Profil |
#17 · Zasláno: 14. 7. 2012, 17:16:37
Fisir:
Já vidím titulky všude, kde mají být. Chamurappi: V rámci kódu v [#12] ta vypadat musí. To že by se to dalo udělat celé nebo jen část jinak, to nepopírám. |
||
Fisir Profil |
Reaguji na Chamurappiho [#10]:
„Za koncem if ů a funkcí děláš zbytečně středníky.“
Já vím. Ale jsem zvyklý je tam dělat. Reaguji na Keeehiho [#11]: „Já vidím titulky všude, kde mají být.“ Tak se zkus podívat třeba na www.j-jaburek.tk/clanky/novy-web. Titulek je pouze na odkazu „článek o vývoji“. |
||
Chamurappi Profil |
Reaguji na Keeehiho:
V kódu [#12] jsi zapomněl zmínit, že JSON.parse nefunguje ve všech prohlížečích.
Pokud se takovýhle cyklus: for(var i = 0; i < něco; i++) { … } for(var i = 0; i < něco; i++) (function(i) { … })(i); i pamatovat hodnotu nezávisle na vnějším i .
|
||
Keeehi Profil |
Tak jsem celé překopal:
function getTitles(){ for(i = 0; i < poleii.length; i++) { if( poleii[i].href.search(/j-jaburek.tk/) != -1 && poleii[i].href.search(/javascript:/) == -1 && poleii[i].href.search(/mailto:/) == -1 ){ if(poleii[i].title == "" || !poleii[i].title){ ajax(i); } } } } function ajax(i) { var xmlhttp; if (window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); } else { xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("GET",".href),true].href),true].href),true]http://www.j-jaburek.tk/etc/title.php?url="+encodeURIComponent(poleii[i].href),true); xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { var odpoved = JSON.parse(xmlhttp.responseText); poleii[i].title = odpoved.url; } } xmlhttp.send(null); } Už tam není potřeba posílat to i, takže není ani třrba využívat JSONu, ale klidně tam může zůstat. S eval by to mělo fungovat i ve starších prohlížečích var odpoved = JSON.parse(xmlhttp.responseText) || eval("("+xmlhttp.responseText+")"); |
||
Časová prodleva: 12 let
|
0