Estrutura de índice em buscadores que processam no cliente
Se a pesquisa interna é baseada em um índice de palavra que não seja Muito extenso, é possível enviar o índice para o cliente e esse é o navegador que executa o processo de pesquisa usando JavaScript e Dom Management. Uma solução consiste em criar um arquivo de texto plano com o índice de palavra-chave, algo como o que vimos no tópico anterior:
...table 86tbody 86,12...
para que o ponto de chave números de documentos onde eles estão localizados. Por sua vez, podemos ter outro arquivo de índice com os URLs:
...12 /ijk/lmn.html86 /abc/def/ghi.html...
Isso pode ser enviado para o cliente usando variáveis de tipo de string dentro de um arquivo .js, para Exemplo:
var indice = "...;table=86;tbody=86,12;...";var claves = "...;12=/ijk/lmn.html;...;86=/abc/def/ghi.html;...";
Então, no navegador, poderíamos aplicar a função para converter essas cadeias nas matrizes correspondentes e trabalhe neles.
Mas quando eu fiz o meu mecanismo de pesquisa com JavaScript, não usei este conceito de índice de chave, mas eu construí o índice exclusivamente usando os cabeçalhos identificados. Este é um exemplo do HTML do índice localizado 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 é enviado dentro do documento, como elementos HTML, localizado no recipiente com id="indiceContenidos"
que inicialmente tem as propriedades do estilo overflow: hidden; height: 0;
com o que não ser mostrado na tela, mas seu conteúdo está presente. Em seguida, cada página é incluída em um recipiente como id="cabecera"
, onde o identificador é o nome do documento sem a extensão. Portanto, este contêiner terá todos os links para os cabeçalhos do documento cabecera.html
. Cada link <a>
também está contido em outro <div>
para fornecê-lo com elegante recuado.
em essência é sobre Carregue uma variável global com uma coleção de elementos do índice, ação que é feita com a carga da página. Em seguida, o usuário ao se procurar por essa coleção, removendo o texto interno do elemento e verificando a correspondência com a string de pesquisa. A vantagem de enviar o índice para o cliente como elementos HTML é que ele pode ser usado diretamente como um índice de conteúdo, ou melhor, um índice, para o qual com o JavaScript, alteramos as propriedades do estilo do contêiner com id="indiceContenidos"
conten.style.overflow = "visible";conten.style.height = "auto";
A grande vantagem desses mecanismos de pesquisa com o JavaScript é que eles não consomem recursos do servidor ao processar as pesquisas. Tudo é feito no navegador. Mas o tamanho é uma limitação que condiciona esses mecanismos de pesquisa, portanto, para um volume maior de cabeçalhos, não seria mais eficiente enviá-lo para o navegador do cliente. Essa pesquisa inclui 862 links para todos os cabeçalhos dos 16 documentos que compõem o glossário XHTML + CSS. A pesquisa é então composta de:
- documento pesquisado.html de 152kb com os links para os cabeçalhos.
- javascript busca.js de 7kb para lidar com o processo de pesquisa.
- estilo externo em parte do arquivo XHTMLCSS-Style.css. Isso ocupa 5kb, mas sobre o mecanismo de pesquisa é uma quantia menor.
no que se segue é exposto à medida que este mecanismo de pesquisa funciona. Mas começamos do fato de que já construímos o índice de acordo com a estrutura indicada e que repetimos esquematicamente novamente:
<div> ... <div> ... <div><a>...</a></div> <div><a>...</a></div> ... </div> ... <div> ... <div><a>...</a></div> <div><a>...</a></div> ... </div> ... </div>
para construir este índice automaticamente pode Consulte a ferramenta de um tópico seguinte que fala sobre os índices de construção. É um utilitário que permitirá que você fabrique este índice com base nos documentos HTML selecionados, salvando o HTML gerado em um arquivo de texto. Nessa página, é explicado como usar essa ferramenta.
Estrutura HTML-CSS do mecanismo de pesquisa com JavaScript
Visualmente, nosso mecanismo de pesquisa tem essa aparência:
Esta é uma caixa de texto para a cadeia de pesquisa, um botão para iniciar a pesquisa, outra para abrir as opções inferiores e um botão para mostrar índice. As opções de pesquisa permitem que você pesquise por ingressos que contenham todas as palavras ou apenas uma palavra. Além disso, apenas palavras completas também podem ser procuradas e maiúsculas maiúsculas.
Não é conveniente mostrar o padrão de pesquisa se este mecanismo de pesquisa será destinado a um site de uso geral. Mas, como aqui, o objetivo é mostrar todos os detalhes possíveis, esse padrão de pesquisa está incluído. Então, até mesmo o usuário interessado pode tentar outros padrões.Do ponto de vista, devemos lembrar que este mecanismo de pesquisa funciona no navegador do usuário, de modo que os erros de padrões indevidos só afetarão o navegador e não o servidor.
Finalmente, há um limitador para o número máximo de Resultados, porque para determinadas pesquisas como letras, por exemplo, o número de resultados pode ser muito alto. Mas de qualquer maneira a melhor maneira de entender tudo isso é colocá-lo na execução.
A estrutura geral por blocos é 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>
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 contêiner com id="resultados"
é em princípio conteúdo vazio, porque Existem dinamicamente os resultados de cada pesquisa. O recipiente com class="vinculos"
tem essa 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 da cadeia de texto inclui um evento onblur
De tal maneira que, quando deixando esse item, o padrão de pesquisa é atualizado com as funções patronear()
, incluídas nas pesquisas do módulo. js. O botão para iniciar as chamadas de pesquisa a função buscar()
. As outras funções são opciones()
e Mostrando a caixa de opções e o índice de conteúdo total, uma vez que ambos os recipientes são inicialmente ocultos, como foi declarado no CSS. O índice de conteúdo total com id="indiceContenidos"
está oculto com height:0
Precisamos ter carregado na página porque vamos fazer a pesquisa iterano Pelos elementos <a>
, portanto, mesmo se eles não são exibidos, eles estão presentes. Vamos ver agora a estrutura da caixa de opções:
<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 contêiner de resultados (com id="resultados"
) vácuo Inicialmente e o recipiente de índice (com id="indiceContenidos"
) sua estrutura já estava exposta na seção anterior.
O JavaScript para operar o mecanismo de pesquisa interno
A estrutura das variáveis globais e funções deste módulo JavaScript é a seguinte:
- Variáveis globais
- : uma referência para o elemento
<input type="text">
para armazenar o padrão. -
inputOpcionesFlags
Uma referência ao elemento<input type="text">
que armazena as opções ou bandeiras do padrão. -
vinculos
: uma variável que conterá a coleção de elementos do índice. -
hasta
: um inteiro que inicialmente contém o número de elementos desse índice. -
particulas
: uma variável de tipo de cadeia que contém uma lista de partículas (preposições, advérbios, etc.) que serão excluídas da cadeia de pesquisa. - funções
-
window.onload = function()
: inicialize o Finder com a carga da página. - : Prepare o padrão de pesquisa.
- : Pesquise esse padrão.
-
function opciones()
: show ou opções de caixa. -
function indiceContenidos()
: Mostrar ou ocultar o índice de conteúdo.
Eu não vou expor o código completo deste javascript. Com navegadores como o Firefox, você pode baixar este código facilmente e consultar-o. A função de inicialização com a carga da página é simplesmente responsável por referenciar as variáveis globais e preencher a coleta de matriz ou link. As funções que mostram ou ocultam os recipientes de opções ou índice não têm nenhuma complexidade. Vamos ver apenas as funções para preparar o padrão e pesquisar.
Quando sairmos da caixa de string de pesquisa executar o evento onblur
que chama a função patronear()
, que é responsável por preparar o padrão.
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 padrão que preparamos tem dois campos, um com o Expressão regular que será salva no <input type="text">
e que tínhamos referenciado na variável global inputPatron
e, por outro lado, e, por outro lado, bandeiras ou modificadores da expressão regular que armazenamos no <input type="text">
e que também referência na variável global . Essas variáveis serão então consultadas na função buscar()
.
O padrão é construído escapando os caracteres reservados de expressões regulares e, em seguida, eliminando as partículas usadas com frequência. É a variável global particulas
contendo uma lista separada pela barra vertical de preposições, advérbios, artigos e outras palavras de freqüência usada na linguagem e que eles não contribuem para a pesquisa .Eliminamos espaços no início ou no final da string de busca e convertemos vários espaços em um. Se no final a corrente contiver algo mais do que um espaço, construímos o padrão.
Neste momento, teremos uma string de pesquisa com palavras separadas pelo espaço. Se o <input type="checkbox" />
é desactivado é que vamos procurar algumas dessas palavras. Construímos o padrão que separam as alternativas com a barra vertical (um dilema). Em outro caso, estamos procurando todas as palavras e é construído separando-os com .*?
equivalente a uma conjuntiva. Em seguida, incorporamos os delimitadores para a palavra completa. Na caixa de bandeiras, adicionamos a opção Se a pesquisa é insensível em maiúsculas-minúsculas, ou seja, ela não diferirá em maiúsculas minúsculas.
ao sair do Já temos na caixa <input type="text">
o padrão e no padrão <input type="text">
os sinalizadores Quando o botão correspondente é pressionado, eu executo 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 variável maxBusca
Limita o número máximo de iterações na coleção de links. A variável maxResulta
Controla o número de resultados a serem retornados. Em seguida, declaramos a expressão regular com new RegExp(cadBusca, opciones)
. Nesse caso, usamos uma string em cadBusca
, o padrão construído antes com a função patronear()
, adicionando os sinalizadores. O processo de pesquisa consiste em iterar pela coleta de links, extraindo o texto interno desses elementos <a>
. Fazemos isso com a função getInnerText()
do módulo geral.js com funções que unificam o comportamento dos navegadores ao extrair o texto interno de um elemento. Para isso, é necessário vincular esse módulo no cabeçalho das pesquisas:
<script type="text/javascript" src="alguna_carpeta/general.js" charset="ISO-8859-1"></script>
Se você não quiser incorporar esse módulo geral.js, você pode localizar A função getInnerText()
diretamente no módulo pesquisado.js. Nesse texto interno do elemento <a>
Aplicamos o padrão de pesquisa, obtendo uma matriz de coincidências na variável resultado
. Nós controlamos que o número de resultados é menor que os declarados para apresentar (variável maxResulta
), caso em que estamos acumulando com innerHTML
dinamicamente construir elementos de link. Se você exceder maxResulta
Perguntamos ao usuário se continuarmos iterando dando-lhe a opção de quebrar o loop.
Muitas melhorias são possíveis, mas essencialmente eu mostrei um maneira de fazer um mecanismo de pesquisa interno com JavaScript. Sua grande vantagem é que ele é executado no navegador do usuário, onde o retorno de retorno é mais rápido e também não consome recursos do servidor. Desvantagens são principalmente a necessidade de o usuário ter ativado o JavaScript e o tamanho do arquivo de índice que deve ser transferido do servidor. Este aspecto pode ser melhorado se, em vez de fazer um índice HTML, fizemos isso apenas com texto, mas esse mecanismo de pesquisa será sempre limitado por um tamanho máximo desse arquivo de índice. Ele não parece certo enviar o cliente um documento, incluindo o arquivo de índice com o tamanho que excede o 150kb muito.
Neste momento eu implementei neste site outro mecanismo de pesquisa com base em índices armazenados como matrizes serializadas em arquivos de texto e em execução no servidor que é exposto no próximo tópico. Mas ainda mantenho este mecanismo de busca com Javascript porque, independentemente da sua qualidade, é um bom exercício para aprender aspectos de javascript como gerenciamento Dom ou expressões regulares.