2008-09-23 9 views
86

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:Resalta una palabra con jQuery

<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 Sebastianpointed out, esto es bastante posible sin jQuery - pero esperaba que podría haber un método especial de jQuery, que le permiten hacer los 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.

+1

En lugar de destacar las palabras con un ' ', es más correcto usar' ', semánticamente hablando. –

+0

Hola, estoy a bordo tarde, pero aquí hay otro fragmento de código que ayuda a resaltar y filtrar el texto según las etiquetas. Con suerte, eso ayudará a alguien [Plugin de jQuery para resaltar texto y Filtrar] (http://jaspreetchahal.org/jquery-text-highlighter-and-filter-plugin/) –

+2

En caso de que necesite una versión indulgente del plugin de jQuery highlight: [http://www.frightanic.com/2011/02/27/lenient-jquery-highlight-plugin-javascript/](http://www.frightanic.com/2011/02/27/lenient-jquery-highlight -plugin-javascript /) –

Respuesta

75

Pruebe highlight: JavaScript text higlighting jQuery plugin.

/* 

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(); 
}; 

También pruebe "updated" version of the original script.

/* 
* 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); 
    }); 
}; 
+0

Hay dos soluciones, y están contenidas en un archivo cada una. Los agregué arriba. Al menos, como en el peor de los casos, siempre estarán disponibles aquí en el historial de edición. –

+0

highlight v4 tiene errores un poco. Hay una solución en la página principal de Burkard: http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html En este caso, no fue una buena idea copiar el código aquí; el enlace apunta a la última versión (ahora :)). –

+0

Por cierto, la etiqueta es probablemente mejor que la etiqueta aquí. – unitario

2

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. :-)

+8

Pero es más fácil con jQuery, ¿no? ;) – Eikern

+6

se puede hacer con Nokia 6310, ni siquiera necesita tener una PC para esto :-) – okliv

-2

Si realmente juego que podría mirar a través de la fuente de Stackoverflow de cómo lo hace resaltar la sintaxis en los bloques de código;)

Esencialmente, usted tendrá que insertar simplemente dinámicamente HTML (palmos le se mejor) donde los necesites.

+0

SO toma el marcado ('carácter) del usuario para adjuntar texto dentro de las etiquetas' '. ¿Qué pasa si uno quiere eliminar lo destacado de los textos? – Madeyedexter

38
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'); 
+2

No desea utilizar innerHTML ya que fue introducido por Microsoft en los años 80, y más tarde cayó por Microsoft nuevamente, como de costumbre.Aunque la mayoría de los navegadores lo admiten, es todo menos el estándar del W3C. – nottinhill

+19

¿Qué debería usar en lugar de innerHTML? – Kebman

+13

@Sir Ben Benji: Creo que estás confundiendo innerHTML con innerText (la alternativa desarrollada por Microsoft a textContent, que de hecho es anatema para la especificación). innerHTML puede haber comenzado como una extensión de Microsoft, pero de ninguna manera se ha "eliminado"; ha sido admitido por todos los navegadores principales desde principios de los 2000, y es parte de HTML5 (ya en 2008): http://www.w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml Todavía está presente en la última revisión en http://www.w3.org/TR/DOM-Parsing/. Consulte también http://www.w3.org/TR/html5/references.html#refsDOMPARSING –

-2

¿Es posible conseguir este ejemplo anterior:

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 las etiquetas HTML como, esto Breakes de lo contrario la página.

11

Aquí es una variación que ignora y preserva 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>";}); 
    }); 
}; 
+6

Esto funciona para texto sin formato, pero no parece excluir etiquetas y atributos. es decir, busque "muchacha" cuando tenga un atributo de clase en un div en su innerHTML. – Jonathan

+0

¿Cómo se invoca esta función? – jiy

+0

'innerHTML' es malo, mira mi respuesta aquí. Además, '\\ b' no funciona para caracteres Unicode. Además, esta función omite casi cualquier cosa, p. buscando dentro de niños anidados. – dude

1

me escribió una función muy simple que utiliza jQuery para recorrer los elementos envolventes cada palabra con una clase DESTACAR.

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:

http://www.hawkee.com/snippet/9854/

+2

Esto no busca elementos anidados, no tiene ninguna función para eliminar los aspectos destacados y no tiene información de licencia. – dude

2

Usted puede usar mi más destacado complemento jQuiteLight, que también puede trabajar con expresiones regulares.

de instalar con npm Tipo:

npm install jquitelight --save 

de instalar con bower Tipo:

bower install jquitelight 

Uso:

// for strings 
$(".element").mark("query here"); 
// for RegExp 
$(".element").mark(new RegExp(/query h[a-z]+/)); 

Más uso avanzado here

+0

Suena como un duplicado de [jquery.mark] (https://github.com/julmot/jquery.mark) – user3631654

+0

@ user3631654 no es un complemento diferente. Mi complemento puede funcionar con RegExp y tiene una función de resaltado inteligente. Si ha incluido el complemento que ha mencionado antes de este complemento, puede obtenerlo usando 'var oldMark = $ .fn.mark.noConflict()' – iamawebgeek

+0

Parece que [jquery.mark] (https://github.com/julmot/ jquery.mark) tiene un método 'markRegExp()' para también resaltar expresiones regulares personalizadas. Entonces esto no debería ser un argumento. – user3631654

23

¿Por qué utilizar una función de resaltado de hecho a sí mismo es una mala idea

La razón por la que es probablemente una mala idea para empezar a construir su propia función resaltado desde cero se debe a que sin duda se ejecutará en problemas que otros ya han resuelto. Desafíos:

  • Usted tendría que quitar nodos de texto con los elementos HTML para destacar sus partidos sin destruir eventos DOM y provocando DOM regeneración una y otra vez (lo que sería el caso con, por ejemplo innerHTML)
  • Si desea para eliminar los elementos resaltados, debe eliminar los elementos HTML con su contenido y también debe 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 funciona en situaciones en las que no ha 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.

utilizar un plugin existente

Cuando se utiliza una, plug-in bien implementado existente, usted no tiene que preocuparse acerca de las cosas arriba mencionadas. El artículo 10 jQuery text highlighter plugins en Sitepoint compara los populares complementos de resaltado. Esto incluye complementos de respuestas de esta pregunta.

Tenga una mirada en mark.js

mark.js es un plugin de tal manera que está escrito en JavaScript puro, sino que también está disponible como plugin de jQuery.Fue desarrollado para ofrecer más oportunidades que los otros plugins con opciones para:

  • de búsqueda de palabras clave por separado en lugar de la expresión completa
  • mapa diacríticos (Por ejemplo, si "justo" también deben coincidir "Justo")
  • ignoran partidos dentro de los elementos personalizados
  • uso de elementos personalizados destacando
  • uso resaltado clase personalizada
  • sinónimos mapa personalizados
  • de búsqueda también iFrames dentro
  • términos que no se encuentran recibir

DEMO

Alternativamente se puede ver this fiddle.

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 gratis y de código abierto desarrollado en GitHub (project reference).

-2
$(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í

+0

' hilight' no es un elemento HTML válido – user3631654

+0

Simplemente ignore esta advertencia, es su elemento personalizado, puede escribir lo que desee. ¿Has visto el violín? –

+0

@nickf mi script hace exactamente lo mismo que la respuesta aceptada –

0

He creado un concepto similar en repository que cambia los colores de los textos cuyos colores son reconocidos por html5 (que no tenemos que utilizar los valores reales #rrggbb y podría simplemente utilizar los nombres como HTML5 estandarizados alrededor de 140 de ellos)

colors.js colors.js

$(document).ready(function() { 
 
\t 
 
\t function hiliter(word, element) { 
 
\t \t var rgxp = new RegExp("\\b" + word + "\\b" , 'gi'); // g modifier for global and i for case insensitive 
 
\t \t var repl = '<span class="myClass">' + word + '</span>'; 
 
\t \t element.innerHTML = element.innerHTML.replace(rgxp, repl); 
 
\t \t \t 
 
\t \t \t }; 
 

 
\t hiliter('dolor', document.getElementById('dolor')); 
 
});
.myClass{ 
 

 
background-color:red; 
 
}
<!DOCTYPE html> 
 
<html> 
 
\t <head> 
 
\t \t <title>highlight</title> 
 
\t \t 
 
\t \t <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> 
 
\t 
 
\t \t <link href="main.css" type="text/css" rel="stylesheet"/> 
 
\t \t 
 
\t </head> 
 
\t <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> 
 
\t </body> 
 
</html>

2

JSFiddle

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; 
} 
0

Usted puede utilizar la función de siguiente para resaltar cualquier palabra en el 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 objetivo el elemento que contiene el texto, elegir la palabra para colorear y el color de elección.

Aquí es 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') 

enter image description here

Cuestiones relacionadas