javascript - negrita - Resalte una palabra con jQuery
title html (13)
Básicamente necesito resaltar una palabra en particular en un bloque de texto. Por ejemplo, pretendo que quería resaltar la palabra "dolor" en este texto:
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
</p>
<p>
Quisque bibendum sem ut lacus. Integer dolor ullamcorper libero.
Aliquam rhoncus eros at augue. Suspendisse vitae mauris.
</p>
¿Cómo convierto lo anterior a algo como esto?
<p>
Lorem ipsum <span class="myClass">dolor</span> sit amet, consectetuer adipiscing elit.
</p>
<p>
Quisque bibendum sem ut lacus. Integer <span class="myClass">dolor</span> ullamcorper
libero. Aliquam rhoncus eros at augue. Suspendisse vitae mauris.
</p>
¿Es esto posible con jQuery?
Editar : Como Sebastian señaló , esto es bastante posible sin jQuery, pero esperaba que hubiera un método especial de jQuery que te permitiera hacer selectores en el texto mismo. Ya estoy usando mucho jQuery en este sitio, por lo que mantener todo incluido en jQuery haría las cosas un poco más ordenadas.
¿Por qué usar una función de resaltado selfmade es una mala idea?
La razón por la que probablemente sea una mala idea comenzar a construir su propia función de resaltado desde el principio es porque seguramente encontrará problemas que otros ya han resuelto. Desafíos:
- Tendría que eliminar los nodos de texto con elementos HTML para resaltar las coincidencias sin destruir los eventos DOM y desencadenar la regeneración de DOM una y otra vez (como sería el caso con
innerHTML
) - Si desea eliminar los elementos resaltados, deberá eliminar los elementos HTML con su contenido y también deberá combinar los nodos de texto divididos para realizar más búsquedas. Esto es necesario porque cada complemento de resaltado busca coincidencias entre los nodos de texto y si sus palabras clave se dividirán en varios nodos de texto, no se encontrarán.
- También necesitaría crear pruebas para asegurarse de que su complemento funcione en situaciones en las que no haya pensado. ¡Y estoy hablando de pruebas de navegador cruzado!
¿Suena complicado? Si desea algunas características como ignorar algunos elementos de resaltado, mapeo diacrítico, mapeo de sinónimos, búsqueda dentro de iframes, búsqueda de palabras separadas, etc. esto se vuelve cada vez más complicado.
Use un plugin existente
Al utilizar un complemento existente y bien implementado, no tiene que preocuparse por las cosas mencionadas anteriormente. Los complementos de jQuery text highlighter del artículo 10 en Sitepoint comparan los complementos populares de resaltado. Esto incluye complementos de respuestas de esta pregunta.
Eche un vistazo a mark.js
mark.js es un plugin que está escrito en JavaScript puro, pero también está disponible como plugin jQuery. Fue desarrollado para ofrecer más oportunidades que los otros complementos con opciones para:
- buscar palabras clave por separado en lugar del término completo
- diacríticos del mapa (por ejemplo, si "justo" también debe coincidir con "justò")
- ignorar coincidencias dentro de elementos personalizados
- usar elemento de resaltado personalizado
- usar clase de resaltado personalizada
- mapa de sinónimos personalizados
- buscar también dentro de iframes
- recibir términos no encontrados
Alternativamente, puedes ver este violín .
Ejemplo de uso :
// Highlight "keyword" in the specified context
$(".context").mark("keyword");
// Highlight the custom regular expression in the specified context
$(".context").markRegExp(/Lorem/gmi);
Es un código abierto libre y desarrollado en GitHub ( referencia del proyecto ).
¿Es posible obtener este ejemplo de arriba?
jQuery.fn.highlight = function (str, className)
{
var regex = new RegExp(str, "g");
return this.each(function ()
{
this.innerHTML = this.innerHTML.replace(
regex,
"<span class=/"" + className + "/">" + str + "</span>"
);
});
};
no reemplazar texto dentro de etiquetas html como, de lo contrario se rompe la página.
Aquí hay una variación que ignora y preserva el caso:
jQuery.fn.highlight = function (str, className) {
var regex = new RegExp("//b"+str+"//b", "gi");
return this.each(function () {
this.innerHTML = this.innerHTML.replace(regex, function(matched) {return "<span class=/"" + className + "/">" + matched + "</span>";});
});
};
Escribí una función muy simple que usa jQuery para iterar los elementos que envuelven cada palabra clave con una clase .highlight.
function highlight_words(word, element) {
if(word) {
var textNodes;
word = word.replace(//W/g, '''');
var str = word.split(" ");
$(str).each(function() {
var term = this;
var textNodes = $(element).contents().filter(function() { return this.nodeType === 3 });
textNodes.each(function() {
var content = $(this).text();
var regex = new RegExp(term, "gi");
content = content.replace(regex, ''<span class="highlight">'' + term + ''</span>'');
$(this).replaceWith(content);
});
});
}
}
Más información:
Intente resaltar: texto de JavaScript que resalta el complemento de jQuery .
/*
highlight v4
Highlights arbitrary terms.
<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>
MIT license.
Johann Burkard
<http://johannburkard.de>
<mailto:[email protected]>
*/
jQuery.fn.highlight = function(pat) {
function innerHighlight(node, pat) {
var skip = 0;
if (node.nodeType == 3) {
var pos = node.data.toUpperCase().indexOf(pat);
if (pos >= 0) {
var spannode = document.createElement(''span'');
spannode.className = ''highlight'';
var middlebit = node.splitText(pos);
var endbit = middlebit.splitText(pat.length);
var middleclone = middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode, middlebit);
skip = 1;
}
}
else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
for (var i = 0; i < node.childNodes.length; ++i) {
i += innerHighlight(node.childNodes[i], pat);
}
}
return skip;
}
return this.length && pat && pat.length ? this.each(function() {
innerHighlight(this, pat.toUpperCase());
}) : this;
};
jQuery.fn.removeHighlight = function() {
return this.find("span.highlight").each(function() {
this.parentNode.firstChild.nodeName;
with (this.parentNode) {
replaceChild(this.firstChild, this);
normalize();
}
}).end();
};
Pruebe también la versión "actualizada" del script original .
/*
* jQuery Highlight plugin
*
* Based on highlight v3 by Johann Burkard
* http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
*
* Code a little bit refactored and cleaned (in my humble opinion).
* Most important changes:
* - has an option to highlight only entire words (wordsOnly - false by default),
* - has an option to be case sensitive (caseSensitive - false by default)
* - highlight element tag and class names can be specified in options
*
* Usage:
* // wrap every occurrance of text ''lorem'' in content
* // with <span class=''highlight''> (default options)
* $(''#content'').highlight(''lorem'');
*
* // search for and highlight more terms at once
* // so you can save some time on traversing DOM
* $(''#content'').highlight([''lorem'', ''ipsum'']);
* $(''#content'').highlight(''lorem ipsum'');
*
* // search only for entire word ''lorem''
* $(''#content'').highlight(''lorem'', { wordsOnly: true });
*
* // don''t ignore case during search of term ''lorem''
* $(''#content'').highlight(''lorem'', { caseSensitive: true });
*
* // wrap every occurrance of term ''ipsum'' in content
* // with <em class=''important''>
* $(''#content'').highlight(''ipsum'', { element: ''em'', className: ''important'' });
*
* // remove default highlight
* $(''#content'').unhighlight();
*
* // remove custom highlight
* $(''#content'').unhighlight({ element: ''em'', className: ''important'' });
*
*
* Copyright (c) 2009 Bartek Szopka
*
* Licensed under MIT license.
*
*/
jQuery.extend({
highlight: function (node, re, nodeName, className) {
if (node.nodeType === 3) {
var match = node.data.match(re);
if (match) {
var highlight = document.createElement(nodeName || ''span'');
highlight.className = className || ''highlight'';
var wordNode = node.splitText(match.index);
wordNode.splitText(match[0].length);
var wordClone = wordNode.cloneNode(true);
highlight.appendChild(wordClone);
wordNode.parentNode.replaceChild(highlight, wordNode);
return 1; //skip added node in parent
}
} else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
!/(script|style)/i.test(node.tagName) && // ignore script and style nodes
!(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
for (var i = 0; i < node.childNodes.length; i++) {
i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
}
}
return 0;
}
});
jQuery.fn.unhighlight = function (options) {
var settings = { className: ''highlight'', element: ''span'' };
jQuery.extend(settings, options);
return this.find(settings.element + "." + settings.className).each(function () {
var parent = this.parentNode;
parent.replaceChild(this.firstChild, this);
parent.normalize();
}).end();
};
jQuery.fn.highlight = function (words, options) {
var settings = { className: ''highlight'', element: ''span'', caseSensitive: false, wordsOnly: false };
jQuery.extend(settings, options);
if (words.constructor === String) {
words = [words];
}
words = jQuery.grep(words, function(word, i){
return word != '''';
});
words = jQuery.map(words, function(word, i) {
return word.replace(/[-[/]{}()*+?.,//^$|#/s]/g, "//$&");
});
if (words.length == 0) { return this; };
var flag = settings.caseSensitive ? "" : "i";
var pattern = "(" + words.join("|") + ")";
if (settings.wordsOnly) {
pattern = "//b" + pattern + "//b";
}
var re = new RegExp(pattern, flag);
return this.each(function () {
jQuery.highlight(this, re, settings.element, settings.className);
});
};
Necesita obtener el contenido de la etiqueta p y reemplazar todos los dolors con la versión resaltada.
Ni siquiera necesita tener jQuery para esto. :-)
Puede usar la siguiente función para resaltar cualquier palabra en su texto.
function color_word(text_id, word, color) {
words = $(''#'' + text_id).text().split('' '');
words = words.map(function(item) { return item == word ? "<span style=''color: " + color + "''>" + word + ''</span>'' : item });
new_words = words.join('' '');
$(''#'' + text_id).html(new_words);
}
Simplemente seleccione el elemento que contiene el texto, elija la palabra para colorear y el color de su elección.
Aquí hay un ejemplo :
<div id=''my_words''>
This is some text to show that it is possible to color a specific word inside a body of text. The idea is to convert the text into an array using the split function, then iterate over each word until the word of interest is identified. Once found, the word of interest can be colored by replacing that element with a span around the word. Finally, replacing the text with jQuery''s html() function will produce the desired result.
</div>
Uso ,
color_word(''my_words'', ''possible'', ''hotpink'')
Puede usar mi complemento de resaltado jQuiteLight , que también puede funcionar con expresiones regulares.
Para instalar usando el tipo npm :
npm install jquitelight --save
Para instalar usando el tipo de bower :
bower install jquitelight
Uso:
// for strings
$(".element").mark("query here");
// for RegExp
$(".element").mark(new RegExp(/query h[a-z]+/));
Uso más avanzado here
Si realmente eres un juego, puedes buscar en la fuente de cómo resalta la sintaxis en los bloques de código;)
Básicamente, tendrás que insertar HTML de forma dinámica (los intervalos serían mejores) donde los necesites.
Utiliza .each (), .replace (), .html (). Probado con jQuery 1.11 y 3.2.
En el ejemplo anterior, lee la ''palabra clave'' que se resaltará y agrega la etiqueta span con la clase ''resaltar''. El texto ''palabra clave'' se resalta para todas las clases seleccionadas en .each ().
HTML
<body>
<label name="lblKeyword" id="lblKeyword" class="highlight">keyword</label>
<p class="filename">keyword</p>
<p class="content">keyword</p>
<p class="system"><i>keyword</i></p>
</body>
JS
$(document).ready(function() {
var keyWord = $("#lblKeyword").text();
var replaceD = "<span class=''highlight''>" + keyWord + "</span>";
$(".system, .filename, .content").each(function() {
var text = $(this).text();
text = text.replace(keyWord, replaceD);
$(this).html(text);
});
});
CSS
.highlight {
background-color: yellow;
}
He creado un repository en un concepto similar que cambia los colores de los textos cuyos colores son reconocidos por html5 (no es necesario que usemos los valores #rrggbb reales y podríamos usar los nombres como html5 estandarizados alrededor de 140 de ellos)
$( document ).ready(function() {
function hiliter(word, element) {
var rgxp = new RegExp("//b" + word + "//b" , ''gi''); // g modifier for global and i for case insensitive
var repl = ''<span class="myClass">'' + word + ''</span>'';
element.innerHTML = element.innerHTML.replace(rgxp, repl);
};
hiliter(''dolor'', document.getElementById(''dolor''));
});
.myClass{
background-color:red;
}
<!DOCTYPE html>
<html>
<head>
<title>highlight</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<link href="main.css" type="text/css" rel="stylesheet"/>
</head>
<body id=''dolor''>
<p >
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
</p>
<p>
Quisque bibendum sem ut lacus. Integer dolor ullamcorper libero.
Aliquam rhoncus eros at augue. Suspendisse vitae mauris.
</p>
<script type="text/javascript" src="main.js" charset="utf-8"></script>
</body>
</html>
$(function () {
$("#txtSearch").keyup(function (event) {
var txt = $("#txtSearch").val()
if (txt.length > 3) {
$("span.hilightable").each(function (i, v) {
v.innerHTML = v.innerText.replace(txt, "<hilight>" + txt + "</hilight>");
});
}
});
});
Jfiddle aquí
function hiliter(word, element) {
var rgxp = new RegExp(word, ''g'');
var repl = ''<span class="myClass">'' + word + ''</span>'';
element.innerHTML = element.innerHTML.replace(rgxp, repl);
}
hiliter(''dolor'');