JavaScript - vyhľadávanie v stránke

Programovacie jazyky, rady, poradňa...
DomCZo
Light Star
Light Star
Používateľov profilový obrázok
Príspevky: 235
Registrovaný: 16 okt 2006, 22:49

JavaScript - vyhľadávanie v stránke

Príspevok od používateľa DomCZo »

Vedel by mi niekto poradiť jednoduché vyhľadávanie cez JavaScript? Lebo si s tým neviem rady.

Na nete som našiel nejaké skripty, ktoré buď neboli so všetkými prehliadačmi kompatibilné, alebo také, ktoré fungujú na princípe, ýe vyhľadá v stránke to DANÉ slovo raz a označí (vysvieti) mi ho...

Ale ja by som rád niečo také, čo mi to DANÉ slovo backgroundne v stránke, a keď sa v stránke vyskytuje viackrát, tak nech backgroundne všetky.

Díki.
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Vyskúšaj searchhi. Je to pôvodne na niečo mierne iné, ale po malej úprave to robí presne to čo potrebuješ. Pridaj tam (do toho js)

Kód: Vybrať všetko

function simpleSearchHighlight() {
	var words = unescape("next item").split(/\s+/);
	for (w=0;w<words.length;w++) {
		highlightWord(document.getElementsByTagName("body")[0],words[w]);
	}
	return;
}
a uprav riadok

Kód: Vybrať všetko

window.onload = simpleSearchHighlight;
DomCZo
Light Star
Light Star
Používateľov profilový obrázok
Príspevky: 235
Registrovaný: 16 okt 2006, 22:49

Príspevok od používateľa DomCZo »

Díki. Funguje to, len sa mi teraz nedarí to dať do formulára :-(

dal som to takto

Kód: Vybrať všetko

  var slovo = document.getElementById('nick');

   var words = unescape(slovo).split(/\s+/);

Kód: Vybrať všetko

<input type="text" id="nick" value="auto">
<input type="button" onclick="simpleSearchHighlight();" value="Hladat">
Ale nejde mi to, neviem prečo.
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Kód: Vybrať všetko

var slovo = document.getElementById('nick');
vráti objekt INPUT. To čo chceš je

Kód: Vybrať všetko

var slovo = document.getElementById('nick').value;
DomCZo
Light Star
Light Star
Používateľov profilový obrázok
Príspevky: 235
Registrovaný: 16 okt 2006, 22:49

Príspevok od používateľa DomCZo »

Teraz tam mam:

Kód: Vybrať všetko

   var slovo = document.getElementByID('nick').value;
   var words = unescape(slovo).split(/\s+/);

Kód: Vybrať všetko

<html>
<head>
<script src="searchhi.js" type="text/javascript"></script>
</head>
<body>

<input type="text" id="nick" value="auto">
<input type="button" onclick="simpleSearchHighlight();" value="Hladat">
<br><br>
fsf fasf as fads oauto saf dsf ds auto f adsfdsf as.

</body>
</html>
A nejde, už som z toho blbý. Zložitá Java.
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Ono to funguje, akurát nič nevidno :) Na zmenu farby musíš použiť css. :wink:

Kód: Vybrať všetko

<html>
<head>

<script src="searchhi.js" type="text/javascript"></script>
<style type="text/css"><!--
span.searchword {
        background-color: yellow;
}
--></style>
</head>
<body>

<input type="text" id="nick" value="auto">
<input type="button" onclick="simpleSearchHighlight();" value="Hladat">
<br><br>
 fsf fasf as fads oauto saf dsf ds auto f adsfdsf as.

</body>
</html>
DomCZo
Light Star
Light Star
Používateľov profilový obrázok
Príspevky: 235
Registrovaný: 16 okt 2006, 22:49

Príspevok od používateľa DomCZo »

Hej hej. Keď som to prerábal asi 10x, tak mi to niekde vypadlo. Ale aj tak mi to nejde. Mám Firefox 2.0. A IE5.0 hlási chybu (žltý výkričník).

Kukám Firefox Chybovú konzolu.
Chyba: document.getElementByID is not a function
DomCZo
Light Star
Light Star
Používateľov profilový obrázok
Príspevky: 235
Registrovaný: 16 okt 2006, 22:49

Príspevok od používateľa DomCZo »

Kód: Vybrať všetko

http://www.codingforums.com/showthread.php?t=35194
"getElementById, not getElementByID. Tis case-sensitive."
Ja umrem :D

...Ako to pri ďalšom zadaní "odbackgroundnem"? Aby mi nezostali stále všetky zadané slová žlté. Prosím.
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Najlepšie by bolo tú stránku načítať znova. Pri tom zvýrazňovaní sa totiž do štruktúry dokumentu povsúvajú <span> tagy, pomocou ktorých sa to zvýrazní. Odstránenie toho zafarbenia je jednoduché, ale tie <span> tagy by tam ostali a to by spôsobovalo problém, pri ďalšom hľadaní (napr. v html máš slovo autobus, dáš hľadať auto a potom to zvýraznenie odstrániš, ale ostane to rozdelené na dve časti, takže potom už autobus nenájdeš). Riešenie by bolo, zlúčiť ten <span> s okolitými tagmi. Ale to môže byť zložité (musel by si si poznačiť, ako si to delil [či je to na začiatku, v strede, alebo na konci pôvodného obsahu]).

Urobil som js funkciu, ktoré zlučuje ten span s okolitým textom (ale zatiaľ je to len taký pokus, treba to vylepšiť a zoptimalizovať). Do html pridaj ďalšie tlačítko:

Kód: Vybrať všetko

<input type="button" onclick="cleanHighlight();" value="Vycistit">
a do súboru s tým javaskriptom pridaj:

Kód: Vybrať všetko

function cleanWord(node)
{

	for (i = node.childNodes.length - 1; i >= 0; i--) {
		tn = node.childNodes[i];
		if (tn.className == "searchword") {
			text = "";

			bn = (i > 1) ? node.childNodes[i-1] : null;
			an = (i < node.childNodes.length - 2) ? node.childNodes[i+1] : null;

			if (bn != null) {
				text += bn.nodeValue;
			}
			text += tn.childNodes[0].nodeValue;
			if (an != null) {
				text += an.nodeValue;
			}

			pn = tn.parentNode;
			pn.insertBefore(document.createTextNode(text), tn);

			if (an != null) pn.removeChild(an);
			pn.removeChild(tn);
			if (bn != null) pn.removeChild(bn);
		}
	}

	// Iterate into this nodes childNodes
	if (node.hasChildNodes) {
		var hi_cn;
		for (hi_cn=0;hi_cn<node.childNodes.length;hi_cn++) {
			cleanWord(node.childNodes[hi_cn]);
		}
	}
}

function cleanHighlight()
{
	cleanWord(document.getElementsByTagName("body")[0]);
}
DomCZo
Light Star
Light Star
Používateľov profilový obrázok
Príspevky: 235
Registrovaný: 16 okt 2006, 22:49

Príspevok od používateľa DomCZo »

Pekne to pracuje.

Trošku som to upravil:

Kód: Vybrať všetko

function simpleSearchHighlight()
{
	var slovo = document.getElementById("nick").value;
	var words = unescape(slovo).split(/\s+/);
	if (slovo.length >= 3)
	{
		for(w=0;w<words.length;w++)
		{
			highlightWord(document.getElementsByTagName("body")[0],words[w]);
		}
	}
	return;
}

Kód: Vybrať všetko

<input type="text" id="nick" onkeyup="cleanHighlight(); simpleSearchHighlight();">
<input type="button" onclick="cleanHighlight();" value="R">
Ešte by som mal poslednú otázku, vedel by si mi poradiť, ako nastaviť, aby sa scrollovalo okno vždy na prvé nájdené slovo? Toto mám zo starého skriptu:

Kód: Vybrať všetko

win.document.body.scrollTop = TRange.offsetTop;
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Do súboru searchhi.js pridaj:

Kód: Vybrať všetko

var	first = true;
(daj to niekam na začiatok).
Funkciu highlightWord uprav:

Kód: Vybrať všetko

			pn.removeChild(node);

				if (first) {
					var top = hiword.offsetTop;
					var parent = hiword;
					while (parent = parent.offsetParent) {
						top += parent.offsetTop;
					}
					document.getElementsByTagName("body")[0].scrollTop = top;
					first = false;
				}
(to pn.removeChild(node); je tam len na to, aby si vedel, kam to vložiť :) )
A nakoniec funkcia simpleSearchHighlight():

Kód: Vybrať všetko

function simpleSearchHighlight() {
	first = true;

	var slovo = document.getElementById('nick').value;
	var words = unescape(slovo).split(/\s+/);
	for (w=0;w<words.length;w++) {
		if (words[w].length < 4) continue;
		highlightWord(document.getElementsByTagName("body")[0],words[w]);
	}

	return;
}
Ak používaš aj funkciu googleSearchHighlight, tak aj tam pridaj:

Kód: Vybrať všetko

first = true;
Dalo by sa to urobiť aj tak, že súbor najskôr iba zvýrazníš. Potom si nájdeš prvý tag span ktorý má class rovné "searchword" a tam posunieš stránku.

// chrono: Elegantnejšie by asi bolo urobiť funkciu, ktorá vráti absolútnu polohu tagu a použiť ju

Kód: Vybrať všetko

function findPos(obj)
{
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}
a potom dať do funkcie highlightWord iba

Kód: Vybrať všetko

if (first) {
	document.getElementsByTagName("body")[0].scrollTop = findPos(hiword)[1];
	first = false;
}
DomCZo
Light Star
Light Star
Používateľov profilový obrázok
Príspevky: 235
Registrovaný: 16 okt 2006, 22:49

Príspevok od používateľa DomCZo »

Ok díkes. Skôr tá prvá možnosť, tá je dobrá.

Lebo tá druhá to vyhľadávala tak, že keď som tam mal napríklad slovo AUTO, tak som začal písať A... U... T a hodilo ma to k slovu AUTO a zostalo vysvietené iba AUT. Akonáhle som dopísal ešte O, scroll sa posunul hore späť k formulári a už sa nepohol.
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

DomCZo napísal:Ok díkes. Skôr tá prvá možnosť, tá je dobrá.

Lebo tá druhá to vyhľadávala tak, že keď som tam mal napríklad slovo AUTO, tak som začal písať A... U... T a hodilo ma to k slovu AUTO a zostalo vysvietené iba AUT. Akonáhle som dopísal ešte O, scroll sa posunul hore späť k formulári a už sa nepohol.
Prvá možnosť čoho? Lebo tá "elegantnejšia" úprava robí presne to isté čo tá "neelegantná".
DomCZo
Light Star
Light Star
Používateľov profilový obrázok
Príspevky: 235
Registrovaný: 16 okt 2006, 22:49

Príspevok od používateľa DomCZo »

Tá neelegantnejšia je lepšia.
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Veď robia presne to isté (len časť je presunutá do samostatnej funkcie). :)
Daj mi príklad, v ktorom tie verzie nefungujú rovnako a pozriem sa na to (lebo mne fungujú rovnako, ale možno som to sem zle skopíroval).
DomCZo
Light Star
Light Star
Používateľov profilový obrázok
Príspevky: 235
Registrovaný: 16 okt 2006, 22:49

Príspevok od používateľa DomCZo »

Kukni si tú prílohu prosím. Máš pravdu, asi to robí to isté. Skús dať vyhľadať že vlakovka. Slovo vlak sa tam nachádza pred slovom vlakovka, preto keď začnem písať V..L..A..K (vlak vysvieti) ..O a už to nevyhľadá nič.

// Asi nie je dobrý nápad tam dávať onkeyup, lebo to cez BUTTON pracuje správne, keď sa nevyhľadáva furt písmenko za písmenkom.
Prílohy
search.zip
(2.55 KiB) 156 stiahnutí
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

V súbore search2.js pridaj do funkcie simpleSearchHighlight (na začiatok)

Kód: Vybrať všetko

first = true;
A vo funkcii cleanWord oprav riadok

Kód: Vybrať všetko

an = (i <= node.childNodes.length - 2) ? node.childNodes[i+1] : null;
(má tym byť <= a nie iba <)
PS: Na postupné hľadanie by bolo efektívnejšie upraviť celý skript (nie je treba všetko vždy vymazať a nájsť znova)
DomCZo
Light Star
Light Star
Používateľov profilový obrázok
Príspevky: 235
Registrovaný: 16 okt 2006, 22:49

Príspevok od používateľa DomCZo »

Hej, teraz to pracuje úplne super.

A chcem sa len opýtať, na začiatku JavaScriptu má byť to var first = true?

Kód: Vybrať všetko

var   first = true;

function highlightWord(node,word)
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

DomCZo napísal:Hej, teraz to pracuje úplne super.

A chcem sa len opýtať, na začiatku JavaScriptu má byť to var first = true?

Kód: Vybrať všetko

var   first = true;

function highlightWord(node,word)
Má to tam byť (aj keď stačilo by aj "var first;"). To nadefinuje globálnu premennú first (vo funkcii simpleSearchHighlight sa nastaví true, a neskôr, keď sa nájde nejaký vyhovujúci text, tak sa to nastaví, vo funkcii highlightWord na false).
PS: Lepšie by bolo, keby si dal ten editbox a tlačítko do divu, s absolútnou polohou 0,0 (tak by pri tom ako sa stránka odskroluje, ostal ten edit hore [a posunul by sa iba zvyšok stránky])
DomCZo
Light Star
Light Star
Používateľov profilový obrázok
Príspevky: 235
Registrovaný: 16 okt 2006, 22:49

Príspevok od používateľa DomCZo »

Áno, aby stránka neskákala hore, dole, hore, dole...
Onkeyup som dal aj tak preč, lebo pri väčšej stránke to dlho vyhľadáva, aspoň na mojom pomalom kompe.

Kód: Vybrať všetko

<form onsubmit="cleanHighlight(); simpleSearchHighlight(); return false;">
<input type="text" id="nick">
<input type="submit" value="Označiť">
</form>
Tak díki za pomoc.
Napísať odpoveď