Hace un par de días recibí una tarea de prueba de la compañía para la vacante Front-end dev. Por supuesto, la tarea consistió en varios puntos. Pero ahora nos centraremos solo en uno de ellos: la organización de la búsqueda en la página. Es decir búsqueda banal por el texto ingresado en el campo (análogo de Ctrl + F en el navegador). La peculiaridad de la asignación fue que el uso de cualquier framework o biblioteca JS está prohibido.
Todos escriben en JavaScript nativo nativo .
(Para mayor claridad, continuaré acompañando el artículo completo con capturas de pantalla y código, para que usted y yo entendamos de qué estamos hablando en un momento particular)Encontrar una solución
Primer pensamiento: alguien ya ha escrito exactamente esto, necesita google y copiar y pegar. Entonces lo hice. En una hora, encontré dos buenos guiones que esencialmente funcionaban de la misma manera, pero que estaban escritos de manera diferente. Elegí aquel cuyo código entendí mejor y lo inserté en la página de mi viejo.
Si alguien está interesado, tomé el código aquí .El guión funcionó de inmediato. Pensé que el problema estaba resuelto, pero resultó que, sin ofender al autor del guión, había una gran falla. El script buscó todo el contenido de la etiqueta
...
y, como probablemente ya haya adivinado, al buscar cualquier combinación de caracteres que se asemeje a una etiqueta o sus atributos, se rompe toda la página HTML.
¿Por qué el script no funcionó correctamente?
Todo es simple El guión funciona de la siguiente manera. Primero, escribimos todo el contenido de la etiqueta del
cuerpo en una variable, luego buscamos coincidencias con la expresión regular (el usuario la establece al ingresar en el campo de texto) y luego reemplazamos todas las coincidencias con el siguiente código:
<span style="background-color: yellow;">... ...</span>
Y luego reemplazamos la etiqueta del
cuerpo actual con la nueva recibida. El marcado se actualiza, los estilos cambian y todos los resultados encontrados se resaltan en amarillo en la pantalla.
Probablemente ya haya entendido cuál es el problema, pero sin embargo lo explicaré con más detalle. Imagine ingresar la palabra
"div" en el cuadro de búsqueda. Como comprenderá, dentro del
cuerpo hay muchas otras etiquetas, incluida
div . Y si todos aplicamos los estilos mencionados anteriormente al
"div" , entonces esto no será un bloque, pero no está claro qué, ya que el diseño se rompe. Como resultado, después de sobrescribir el marcado, obtenemos una página web completamente rota. Se ve así.
Fue antes de la búsqueda:
Completamente desvanecerseSe convirtió después de la búsqueda:
Completamente desvanecerseComo puede ver, la página se rompe por completo. En resumen, el guión resultó no funcionar, y decidí escribir el mío desde cero, de eso trata este artículo.
Entonces escribimos un guión desde cero
Cómo me parece todo.

Ahora estamos interesados en el formulario de búsqueda. La rodeó con una línea roja.
Miremos un poco. Implementé esto de la siguiente manera (hasta ahora HTML puro). Un formulario con tres etiquetas.
El primero es para ingresar texto;
El segundo : para cancelar la búsqueda (deseleccionar);
El tercero es para buscar (resaltar los resultados encontrados).
<form> <input type="text" value="" placeholder="Search" autofocus> <input type="button" value=" " title=" "> <input type="submit" value=" " title=" "> </form>
Entonces, tenemos un campo de entrada y 2 botones. Escribiré JavaScript en el js.js. Supongamos que ya lo ha creado y conectado.
Lo primero que haremos: registrar las llamadas de función cuando haga clic en el botón de búsqueda y el botón de cancelar. Se verá así:
<form> <input class="place_for_search" type="text" id="text-to-find" value="" placeholder="Search" autofocus> <input class="button_for_turn_back" type="button" onclick="javascript: FindOnPage('text-to-find',false); return false;" value=" " title=" "> <input class="button_for_search" type="submit" onclick="javascript: FindOnPage('text-to-find',true); return false;" value=" " title=" "> </form>
Vamos a explicar un poco lo que hay aquí y por qué.
Le damos al campo de texto
id = "text-to-find" (
este id se referirá al elemento de js ).
Le damos al
botón cancelar
los siguientes atributos:
type = "button" onclick = "javascript: FindOnPage ('text-to-find', false); devuelve falso ";-
Tipo: botón-
Cuando se presiona, se llama a la función FindOnPage ('text-to-find', falso); y pasa la identificación del campo con el texto falsoLe damos al
botón de búsqueda
los siguientes atributos:
type = "button" onclick = "javascript: FindOnPage ('text-to-find', true); devuelve falso ";-
Tipo: enviar (no es un botón porque aquí puede usar Enter después de ingresar al campo, o también puede usar el botón)-
Cuando se presiona, se llama a la función FindOnPage ('text-to-find', verdadero); y pasa la identificación del campo con el texto, verdaderoProbablemente hayas notado un atributo más:
verdadero / falso . Lo usaremos para determinar qué botón se presionó (cancelar la búsqueda o comenzar la búsqueda). Si hacemos clic en cancelar, pasa
falso . Si hacemos clic en la búsqueda, entonces pasa
verdadero .
OK, sigue adelante. Ir a JavaScript
Suponemos que ya ha creado y conectado el archivo js al DOM.
Antes de comenzar a escribir código, tomemos un descanso y primero analicemos cómo debería funcionar todo. Es decir en esencia, escribiremos un plan de acción. Por lo tanto, necesitamos que al ingresar texto en el campo, se realice una búsqueda en la página, pero las etiquetas y los atributos no deberían verse afectados. Es decir solo objetos de texto. Cómo lograr esto: estoy seguro de que hay muchas maneras. Pero ahora usaremos expresiones regulares.
Entonces, la siguiente expresión regular solo buscará el rastro de texto. escriba: "> ... texto ... <". Es decir solo se buscarán objetos de texto, mientras que las etiquetas y los atributos permanecerán intactos.
/>(.*?)</g
Por lo tanto, encontraremos las partes necesarias del código que analizaremos y buscaremos coincidencias con el texto que ingresó el usuario. Luego agregaremos estilos a los objetos encontrados y luego reemplazaremos el código html por uno nuevo.
Empecemos Primero, las variables que necesitamos.
var input,search,pr,result,result_arr, locale_HTML, result_store;
E inmediatamente determine el valor locale_HTML , independientemente de si estamos buscando algo o no. Esto es necesario para guardar inmediatamente la página original y tener la capacidad de restablecer los estilos.
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
Ok, ahora vale la pena crear una función que se llame desde el DOM . Inmediatamente calcule que dentro deberíamos tener 2 funciones, cada una de las cuales funciona dependiendo del botón presionado. Después de todo, realizamos una búsqueda o la ponemos a cero. Y esto lo controla el atributo verdadero / falso , como recordará. También debe comprender que cuando vuelva a buscar, los estilos antiguos deben restablecerse. Así obtenemos lo siguiente:
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
Ok, parte de la lógica está implementada, sigue adelante. Es necesario verificar la palabra recibida para el número de caracteres. Después de todo, ¿por qué necesitamos buscar 1 letra / símbolo? En general, decidí limitar esto a más de 3 caracteres.
Entonces, primero tomamos el valor que ingresó el usuario y, dependiendo de su longitud, realizamos la función de búsqueda principal o la función de advertencia y puesta a cero. Se verá así:
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
Ahora explicaré esta sección del código. Lo único que no puede quedar claro es esta línea:
función FindOnPageBack () {document.body.innerHTML = locale_HTML; }
Aquí todo es simple: el método innerHTML devuelve el código html del objeto. En este caso, simplemente reemplazamos el cuerpo actual con el original que guardamos al cargar toda la página.
Seguimos adelante. Damos valores a las principales variables.
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
Entonces, en esta etapa, ya tenemos las principales variables y valores. Ahora necesitamos dar las partes necesarias de los estilos de código con un fondo resaltado. Es decir verificar el texto seleccionado para una expresión regular (de hecho, el texto seleccionado por la expresión regular es analizado nuevamente por la expresión regular). Para hacer esto, debe hacer una expresión regular a partir del texto ingresado (hecho), y luego ejecutar el método pasado como un tacto. Aquí el método eval () nos ayudará.
En general, después de reemplazar el texto y obtener el resultado con estilos, debemos reemplazar el html actual con el recibido. Lo hacemos
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
En esencia, todo está listo y el script ya está funcionando. Pero agregue un par de detalles más para la belleza.
1) Recorte los espacios en el texto que ingresa el usuario. Inserta este código:
input = numer.replace(/^\s+/g,''); input = numer.replace(/[ ]{1,}/g,' ');
Después de esta línea:
input = document.getElementById(name).value;
2) Comprobaremos las coincidencias (si no se encuentran coincidencias, informaremos al respecto). Este código se inserta en la función FindOnPageGo () después de las variables.
var warning = true; for(var i=0;i<result.length;i++) { if(result[i].match(eval(search))!=null) { warning = false; } } if(warning == true) { alert(' '); }
Puedes ver la fuente aquí .
Puedes descargar la fuente aquí .
Ahora todos. Por supuesto, puede agregar un desplazamiento al primer resultado encontrado, una búsqueda en vivo de ajax, y de hecho puede mejorar infinitamente. Ahora esta es una búsqueda bastante primitiva en el sitio. El propósito del artículo era ayudar a los principiantes si surge la misma pregunta que la mía. Después de todo, no encontré una solución simple ya hecha.
PD: para un funcionamiento correcto, es necesario eliminar la separación silábica del texto en el documento html en aquellos lugares donde hay texto sin formato entre las etiquetas.
Por ejemplo, en lugar de
<p> </p>
Debe
<p> </p>
Esto no es importante, puede deshacerse de estas transferencias automáticamente en el servicio, pero puede decirme al mismo tiempo cómo solucionarlo, si lo entiende antes que yo.
Además, si alguien escribió esto, pero con una búsqueda en vivo, comparta la fuente, será interesante analizarlo.
Estaré encantado de escuchar críticas constructivas, opiniones, tal vez recomendaciones.
Recientemente agregué un pequeño código, hice una búsqueda en vivo en la página. Para que se aclare la pregunta. El código HTML no ha cambiado. JS puede mirar aquí .
La búsqueda se realiza utilizando etiquetas con la clase "place_for_live_search". Entonces, para que el algoritmo analice el contenido deseado, agregue la clase y listo.