Estrutura WEXTENSIBLE

de índice nos buscadores que procesan no cliente

Se a busca interna está baseada nun índice de palabras que non é Moi extenso, é posible enviar o índice ao cliente e que é o navegador que realiza o proceso de busca usando JavaScript e Dom Management. Unha solución consiste en crear un ficheiro de texto plano co índice de palabras clave, algo así como o que vimos no tema anterior:

...table 86tbody 86,12...

para que as palabras clave Números de documentos onde se atopan. Pola súa banda, podemos ter outro ficheiro de índice cos URL:

...12 /ijk/lmn.html86 /abc/def/ghi.html...

Isto pódese enviar ao cliente usando variables de tipo de cadea dentro dun ficheiro .js, para Exemplo:

var indice = "...;table=86;tbody=86,12;...";var claves = "...;12=/ijk/lmn.html;...;86=/abc/def/ghi.html;...";

Entón no navegador poderiamos aplicar a función split() para converter esas cadeas nas matrices correspondentes e traballar con eles.

pero cando eu fixen o meu buscador con JavaScript non uso ese concepto de índice de clave, pero eu constrúe o índice utilizando exclusivamente as cabeceiras identificados. Este é un exemplo do HTML do índice situado no <body> do documento:

<div></div><div> ... <div class="item"> ... <div style="text-indent:3em"> <a href="/temas/xhtml-css/cabecera.html#h0" class="h0"> Elementos XHTML de cabecera </a> </div> ... </div> ...</div>

o índice envíase dentro do documento, como elementos HTML, situados no recipiente con id="indiceContenidos" que inicialmente ten as propiedades de estilo overflow: hidden; height: 0; co que non o fará móstrase na pantalla pero o seu contido está presente. A continuación, cada páxina está incluída nun recipiente como id="cabecera", onde o identificador é o nome do documento sen a extensión. Polo tanto, este contedor terá todas as ligazóns aos encabezados do documento cabecera.html. Cada ligazón tamén está contida noutro <div> para proporcionar-lo con elegante sangrado.

En esencia é sobre Cargue unha variable global cunha colección de elementos

do índice, a acción que se realiza coa carga da páxina. A continuación, o usuario ao buscarse por esa colección eliminando o texto interior do elemento e comprobando a coincidencia coa cadea de busca. A vantaxe de enviar o índice ao cliente como elementos HTML é que pode usarse directamente como índice de contido, ou mellor devandito, unha táboa de contidos, para a que con JavaScript cambiamos as propiedades do estilo do recipiente con

:

conten.style.overflow = "visible";conten.style.height = "auto";

A gran vantaxe destes motores de busca con JavaScript é que non consumen recursos de servidor ao procesar as procuras. Todo está feito no navegador. Pero o tamaño é unha limitación que condiciona estes motores de busca, polo que por un maior volume de encabezados non sería máis eficiente enviarlo ao navegador do cliente. Esta busca inclúe 862 enlaces a todos os títulos dos 16 documentos que compoñen o glosario XHTML + CSS. A busca entón está composta por:

  • documento buscado. HTML de 152kb coas ligazóns aos encabezados.
  • Javascript Buscas.js de 7kb para xestionar o proceso de busca.
  • Estilo externo en parte do ficheiro XHTMLCSS-style.CSS. Isto ocupa 5kb pero sobre o motor de busca é unha cantidade menor.

No que segue está exposto a medida que funciona este motor de busca. Pero comezamos a partir do feito de que xa construímos o índice de acordo coa estrutura indicada e que repetimos esquemáticamente de novo:

<div> ... <div> ... <div><a>...</a></div> <div><a>...</a></div> ... </div> ... <div> ... <div><a>...</a></div> <div><a>...</a></div> ... </div> ... </div>

para construír este índice pode automaticamente Consulte a ferramenta dun seguinte tema que fala sobre os índices de construción. É unha utilidade que lle permitirá fabricar este índice en función dos documentos HTML seleccionados, gardando o HTML xerado nun ficheiro de texto. Nesa páxina explícase como usar esa ferramenta.

Estrutura HTML-CSS do motor de busca con JavaScript

Visualmente o noso buscador ten esta aparencia:

Buscas

Esta é unha caixa de texto para a cadea de busca, un botón para iniciar a busca, outro para abrir as opcións máis baixas e un botón para mostrar o Índice. As opcións de busca permítenlle buscar billetes que conteñan todas as palabras ou só unha palabra. Ademais, só se poden buscar palabras completas e maiúsculas en maiúsculas.

Non é conveniente mostrar o patrón de busca se este motor de busca estará destinado a un sitio de uso xeral. Pero como aquí o obxectivo é mostrar todos os detalles posibles, que se inclúe o patrón de busca. Polo tanto, mesmo o usuario interesado pode probar outros patróns.Desde o punto de vista debemos lembrar que este motor de busca funciona no navegador do usuario, polo que os erros por patróns indebidos só afectarán ao navegador e non ao servidor

Finalmente hai un limitador para o número máximo de resultados, porque para certas procuras como letras, por exemplo, o número de resultados pode ser moi alto. Pero de todos os xeitos, a mellor forma de entender todo isto é poñelo en execución.

A estrutura xeral por bloques é a seguinte:

<div class="vinculos"> ...Aquí van la cadena de búsqueda y botones...</div> <div > <div>OTRAS OPCIONES DE BÚSQUEDA:<br /> ...Aquí van las opciones... </div> <div> ...Aquí se ponen los resultados de la búsqueda... </div> <div> ...Aquí va el índice de vínculos... </div> </div>

O estilo CSS específico para este documento é:

div#indiceContenidos { overflow: hidden; height: 0; }div#indiceContenidos a { text-decoration: none; }div#vinculosIndice { display: none; }div#resultados { border: rgb(49, 99, 98) solid 1px; }div#resultados a { text-decoration: none; color: navy; }div#opcionesBusca { border: rgb(49, 99, 98) solid 1px; overflow: hidden; height: 0; }

O contenedor con id="resultados" está en principio contido baleiro, porque Hai dinámicamente os resultados de cada busca. O recipiente con ten esta estrutura:

<div class="vinculos"> Cadena: <input type="text" value="" size="40" onblur="patronear()" /> <input type="button" value="Buscar" onclick="buscar()" /> Encontrados: <em>0</em> <input type="button" value="Opciones" onclick="opciones()" /> <input type="button" value="Índice" onclick="indiceContenidos()" /> <div>...</div></div>

A caixa de texto para a cadea de busca inclúe un evento onblur de tal xeito que ao saír do elemento, o patrón de busca actualízase coas funcións patronear(), funcións que están incluídas nas buscas do módulo. js. O botón para comezar a busca chama a función buscar(). As outras funcións son opciones() E mostrando as opcións de caixa eo índice de contido total de, xa que ambos os envases son inicialmente oculto, como foi declarado no CSS. O índice de contido total con id="indiceContenidos" está oculto con Necesitamos ter cargado na páxina porque imos facer a busca iterano polos elementos , polo que aínda que non se amosan están presentes. Vexamos agora a estrutura da caixa de opcións:

<div> Conjuntivas:<input type="checkbox" /> Palabra completa:<input type="checkbox" /> Diferencia mayúsculas/minúsculas:<input type="checkbox" /> Patrón:<span class="monospace">/</span> <input type="text" value="" size="40" class="monospace" /> <span class="monospace">/</span> <input type="text" size="5" value="" class="monospace" /> <input type="button" value="Actualizar patrón" onclick="patronear()" /> Resultados máximos:<input type="text" value="100" size="5" />, número de búsquedas máximas:<input type="text" value="0" size="5" /> de un total de <span>0</span><br /> </div> 

Finalmente, o contedor de resultados (con id="resultados") inicialmente eo contenedor de índice (con id="indiceContenidos"), a súa estrutura xa estaba exposta na sección anterior.

O JavaScript para operar o motor de busca interna

p> A estrutura das variables e funcións globais deste módulo de JavaScript é a seguinte:

  • variables globais
    • inputPatron: unha referencia ao elemento <input type="text"> para almacenar o patrón.
    • inputOpcionesFlags: unha referencia ao elemento <input type="text"> que almacena as opcións ou bandeiras do patrón.
    • vinculos: unha variable que contén a colección de elementos <a> do índice.
    • hasta: un número enteiro que inicialmente contén o número de elementos dese índice.
    • particulas: unha variable de tipo de cadea que contén unha lista de partículas (preposicións, adverbios, etc.) que se eliminarán da cadea de busca.
  • Functions
    • window.onload = function(): inicializar o buscador coa carga da páxina.
    • : Prepare o patrón de busca.
    • function buscar(): busca ese patrón.
    • function opciones(): amosar ou ocultar as opcións da caixa.
    • function indiceContenidos(): amosar ou ocultar o índice de contido.

Non vou expoñer o código completo deste JavaScript. Con navegadores como Firefox pode descargar este código con facilidade e consultarlo. A función de inicialización coa carga da páxina é simplemente responsable de facer referencia ás variables globais e encher a colección de matriz ou ligazón. As funcións que mostran ou ocultan os recipientes de opcións ou índice non teñen ningunha complejidad. Só veremos as funcións para preparar o patrón e buscar.

Cando saímos da caixa de cadea de busca execútase o evento onblur que chama a función patronear(), que é responsable de preparar o patrón.

function patronear() { document.getElementById("encontrados").innerHTML = 0; inputPatron.value = ""; var cadenaBusca = document.getElementById("cadBusca").value; var palabraCompleta = document.getElementById("palabraCompleta").checked; if (cadenaBusca != "") { //escapa caracteres reservados de expresiones regulares cadenaBusca = cadenaBusca.replace(/(\?\\\/\^\{\}\|])/g, "\\$1"); //elimina espacios al inicio o final cadenaBusca = cadenaBusca.replace(/^\s+|\s+$/g, ""); //suprime las preposiciones, artículos y otras palabras intermedias, es //decir rodeadas de un espacio por ambos lados. var patron = new RegExp("\\b(?:" + particulas + ")\\b", "gi"); cadenaBusca = cadenaBusca.replace(patron, " "); //Convierte más de un espacio en uno cadenaBusca = cadenaBusca.replace(/\s+/g, " "); //Quita los espacios iniciales y finales por haber partículas ahí cadenaBusca = cadenaBusca.replace(/^\s+|\s+$/g, ""); if ((cadenaBusca == "") || (cadenaBusca == " ")){ inputPatron.value = ""; } else { //reemplaza los espacios intermedios por la alternativa | o conjuntiva .*? //pero diferenciando si buscamos en palabra completa o no var conj = "\|" if (document.getElementById("conjuntiva").checked) { conj = ".*?"; } if (palabraCompleta){ cadenaBusca = cadenaBusca.replace(/\s+/g, "\\b" + conj + "\\b"); cadenaBusca = "\(?:\\b" + cadenaBusca + "\\b\)"; } else { cadenaBusca = cadenaBusca.replace(/\s+/g, conj); cadenaBusca = "\(?:" + cadenaBusca + "\)"; } inputPatron.value = cadenaBusca; var opciones = ""; var difMayusMinus = document.getElementById("caseMM").checked; if (!difMayusMinus) { opciones = opciones + "i"; } inputOpcionesFlags.value = opciones; } } }

O patrón que preparamos ten dous campos, un co Expresión regular que se gardará no <input type="text"> e que nos referimos na variable global inputPatron e, por outra banda, bandeiras ou modificadores da expresión regular que almacenamos no <input type="text"> e que tamén nos referimos á variable global inputOpcionesFlags. Estas variables serán consultadas na función buscar().

O patrón está construído escapando os caracteres reservados das expresións regulares e despois eliminando as partículas frecuentes. É a variable global particulas que contén unha lista separada pola barra vertical de preposicións, adverbios, artigos e outras palabras de uso frecuente no idioma e que non aportan nada á busca ..Eliminamos espazos ao comezo ou ao final da cadea de busca e converte varios espazos nun só. Se ao final a cadea contén algo máis que un espazo, entón construímos o patrón.

Neste momento teremos unha cadea de busca con palabras separadas por espazo. Se o <input type="checkbox" /> está desactivado é que imos buscar algunhas destas palabras. Construímos o patrón que separa as alternativas coa barra vertical (un dilema). Noutro caso estamos a buscar todas as palabras e está construído separándoos con .*? equivalente a unha conjuntiva. Entón incorporamos os delimitadores \b para a palabra completa. Na caixa de bandeiras, engadimos a opción se a busca é minúscula en maiúsculas insensibles, é dicir, non difire en maiúsculas en minúsculas.

ao saír do Xa temos na caixa <input type="text"> o patrón e no <input type="text"> as bandeiras Cando se preme o botón correspondente, executamos o buscar():

function buscar() { document.getElementById("encontrados").innerHTML = 0; var divResultados = document.getElementById("resultados"); divResultados.innerHTML = ""; var cadBusca = inputPatron.value; var opciones = inputOpcionesFlags.value; var maxBusca = 1 * document.getElementById("maxBusca").value; var maxResulta = 1 * document.getElementById("maxResulta").value; var maxResultaBase = maxResulta; var item = 0; if (cadBusca != "") { var patron = new RegExp(cadBusca, opciones); document.getElementById("iterTotal").innerHTML = hasta; if (maxBusca < hasta) { hasta = maxBusca; } for (var i=0; i<hasta; i++) { var cadena = getInnerText(vinculos); var resultado = cadena.match(patron) ; if (resultado != null) { item++; if (item <= maxResulta) { divResultados.innerHTML += ' <a href="' + vinculos.href + '">' + vinculos.innerHTML + '</a><br />'; } else { var men = ""; if (maxResulta == maxResultaBase) { men = " primeros "; } else { men = " siguientes "; } document.getElementById("encontrados").innerHTML = item; var mensaje = window.confirm("Se muestran los" + men + maxResultaBase + " resultados. ¿Continuar buscando?"); if (mensaje) { maxResulta += maxResultaBase; } else { break; } } } } } document.getElementById("encontrados").innerHTML = item;} 

a variable maxBusca limita o número máximo de iteracións na colección de ligazóns. A variable maxResulta controla o número de resultados a devolver. Entón declaramos a expresión regular con new RegExp(cadBusca, opciones). Neste caso, usamos unha cadea en cadBusca, o patrón construído antes coa función patronear(), engadindo as bandeiras. O proceso de busca consiste en iterar a colección de ligazóns extraendo o texto interno destes elementos . Facémolo coa función getInnerText() do módulo xeral. Con funcións que unifican o comportamento dos navegadores ao extraer o texto interno dun elemento. Para iso, é necesario vincular ese módulo no encabezado das procuras:

Se non queres incorporar esa módulo xeral. Podes localizar A función getInnerText() directamente no módulo buscado. Neste texto interior do elemento aplicamos o patrón de busca, obtendo unha variedade de coincidencias na variable . Controlamos que o número de resultados é menor que os declarados para presentar (variable maxResulta), caso en que estamos acumulando con innerHTML dinámicamente Construír elementos de ligazón. Se superas maxResulta Pedimos ao usuario se seguimos iterando dándolle a opción de romper o lazo.

Moitas melloras son posibles, pero esencialmente mostrei a xeito de facer un buscador interno con JavaScript. A súa gran vantaxe é que se executa no navegador do usuario, onde o regreso de regreso é máis rápido e tampouco consome recursos de servidor. As desvantaxes son principalmente a necesidade de que o usuario teña activado JavaScript e o tamaño do ficheiro de índice que debe ser transferido desde o servidor. Este aspecto pode ser mellorado se no canto de facer un índice HTML fixémolo con só texto, pero aínda este motor de busca estará limitado por un tamaño máximo dese ficheiro de índice. Non parece correcto enviar ao cliente un documento que inclúa o ficheiro de índice con tamaño que supera os 150kb demasiado.

Neste momento implementou neste sitio outro motor de busca baseado en índices almacenados como matrices serializadas En ficheiros de texto e executándose no servidor que está exposto no seguinte tema. Pero aínda teño este motor de busca con JavaScript porque, independentemente da súa calidade, é un bo exercicio para aprender aspectos de JavaScript como xestión de DOM ou expresións regulares.

Deixa unha resposta

O teu enderezo electrónico non se publicará Os campos obrigatorios están marcados con *