Markieren Sie ein Wort mit jQuery

101

Grundsätzlich muss ich ein bestimmtes Wort in einem Textblock hervorheben. Stellen Sie sich zum Beispiel vor, ich wollte das Wort "dolor" in diesem Text hervorheben:

<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>

Wie konvertiere ich das Obige in so etwas:

<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>

Ist das mit jQuery möglich?

Bearbeiten : Wie Sebastian betonte , ist dies ohne jQuery durchaus möglich - aber ich hatte gehofft, dass es eine spezielle Methode von jQuery gibt, mit der Sie Selektionen für den Text selbst vornehmen können. Ich verwende jQuery bereits stark auf dieser Site. Wenn Sie also alles in jQuery verpackt halten, werden die Dinge vielleicht etwas aufgeräumter.

nickf
quelle
Dies kann auch von Interesse sein: jquery.info/The-plugin-SearchHighlight
Eikern
Hey, ich habe ein Plugin geschrieben, das genau das tut - es ist wie das Johann Burkard Plugin mlarsen, aber es funktioniert mit regulären Ausdrücken anstelle von Strings. Probieren Sie es auf Github aus und lassen Sie mich wissen, ob Sie zusätzliche Funktionen benötigen.
3
Falls Sie eine milde Version des jQuery-Highlight-Plugins benötigen: http://www.frightanic.com/2011/02/27/lenient-jquery-highlight-plugin-javascript/
Marcel Stör
1
Anstatt Wörter mit a hervorzuheben <span>, ist es <mark>semantisch korrekter, sie zu verwenden .
Jose Rui Santos
Hallo, ich bin spät an Bord, aber hier ist noch ein Code-Snippet, mit dem Sie Text basierend auf Tags hervorheben und filtern können. Hoffentlich hilft das jemandem jQuery Plugin für das Hervorheben und Filtern von Text
Jaspreet Chahal

Antworten:

85

Versuchen Sie hervorzuheben: JavaScript-Text, der das jQuery-Plugin hervorhebt .! Warnung - Der auf dieser Seite verfügbare Quellcode enthält ein Crypto Currency Mining-Skript. Verwenden Sie entweder den folgenden Code oder entfernen Sie das Mining-Skript aus dem Download auf der Website. !

/*

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

Versuchen Sie auch die "aktualisierte" Version des ursprünglichen Skripts .

/*
 * 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);
    });
};
mlarsen
quelle
Es gibt zwei Lösungen, die jeweils in einer Datei enthalten sind. Ich habe sie oben hinzugefügt. Zumindest im schlimmsten Fall sind sie hier im Bearbeitungsverlauf immer verfügbar.
Erick Robertson
Highlight v4 ist ein bisschen fehlerhaft. Auf Burkards Homepage gibt es einen Fix: johannburkard.de/blog/programming/javascript/… In diesem Fall war es keine gute Idee, den Code hier zu kopieren. Der Link verweist auf die neueste Version (jetzt :)).
Lerin Sonberg
Übrigens ist das <mark> -Tag hier wahrscheinlich besser als das <span> -Tag.
Unitario
1
Wenn Sie auf der Suche nach kleinen und leichten Geräten sind, ist das Highlight-JQuery-Plugin in der Tat die beste Wahl. Es eignet sich hervorragend zum Hervorheben und Entfernen von Markierungen, die mit dem angegebenen Text übereinstimmen. Wenn Sie einen regulären Ausdruck oder andere Unterstützung benötigen; Überprüfen Sie jedoch mark.js oder eine der Erweiterungen und Gabeln auf Hervorhebungen, auf die auf der Hervorhebungsseite verwiesen wird. Ich benutze Highlight über andere, weil Leichtgewicht sehr geschätzt wird.
Greg
3
WICHTIG: Johann Burkard hat ein Mining-Skript in die Quelle auf seiner Website aufgenommen !!!!!!
Lukars
42
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');
Andrew Hedges
quelle
2
Sie möchten innerHTML nicht verwenden, da es in den 80er Jahren von Microsoft eingeführt und später wie gewohnt von Microsoft wieder gelöscht wurde. Obwohl die meisten Browser dies unterstützen, ist es alles andere als W3C-Standard.
Steve K
21
Was sollten Sie anstelle von innerHTML verwenden?
Kebman
15
@ Sir Ben Benji: Ich denke, Sie verwechseln innerHTML mit innerText (der von Microsoft entwickelten Alternative zu textContent, die in der Tat ein Gräuel für die Spezifikation ist). innerHTML wurde möglicherweise als Microsoft-Erweiterung gestartet, wurde jedoch in keiner Weise "gelöscht". Es wird seit den frühen 2000er Jahren von allen gängigen Browsern unterstützt und ist Teil von HTML5 (bereits 2008): w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml Es ist immer noch in der neuesten Version vorhanden Überarbeitung unter w3.org/TR/DOM-Parsing . Siehe auch w3.org/TR/html5/references.html#refsDOMPARSING
Jay Dansand
1
Keine wirklich gute Lösung. Ich habe dies nur verwendet, aber wenn ich zum Beispiel nach 'Person' suche, ersetzt es auch alle Klassen und HTML-Elemente durch 'Person'. Auch Klein- und Großbuchstaben sind nicht integriert. var rgxp = new RegExp ("(\\ b" + Wort + "\\ b)", "gim"); behoben, aber trotzdem denke ich, dass der Code HTML-Elemente nicht ersetzen sollte.
Richard Lindhout
32

Warum die Verwendung einer selbst erstellten Hervorhebungsfunktion eine schlechte Idee ist

Der Grund, warum es wahrscheinlich eine schlechte Idee ist, eine eigene Hervorhebungsfunktion von Grund auf neu zu erstellen, liegt darin, dass Sie sicherlich auf Probleme stoßen, die andere bereits gelöst haben. Herausforderungen:

  • Sie müssten Textknoten mit HTML-Elementen entfernen, um Ihre Übereinstimmungen hervorzuheben, ohne DOM-Ereignisse zu zerstören und die DOM-Regeneration immer wieder auszulösen (was z. B. der Fall wäre innerHTML).
  • Wenn Sie hervorgehobene Elemente entfernen möchten, müssen Sie HTML-Elemente mit ihrem Inhalt entfernen und die geteilten Textknoten für weitere Suchvorgänge kombinieren. Dies ist erforderlich, da jedes Textmarker-Plugin in Textknoten nach Übereinstimmungen sucht und Ihre Schlüsselwörter nicht gefunden werden, wenn sie in mehrere Textknoten aufgeteilt werden.
  • Sie müssten auch Tests erstellen, um sicherzustellen, dass Ihr Plugin in Situationen funktioniert, an die Sie nicht gedacht haben. Und ich spreche von browserübergreifenden Tests!

Klingt kompliziert? Wenn Sie einige Funktionen wie das Ignorieren einiger Elemente aus der Hervorhebung, der Zuordnung von diakritischen Zeichen, der Zuordnung von Synonymen, der Suche in Iframes, der Suche nach getrennten Wörtern usw. wünschen, wird dies immer komplizierter.

Verwenden Sie ein vorhandenes Plugin

Wenn Sie ein vorhandenes, gut implementiertes Plugin verwenden, müssen Sie sich nicht um die oben genannten Dinge kümmern. Der Artikel 10 jQuery-Text-Textmarker-Plugins auf Sitepoint vergleicht beliebte Textmarker-Plugins. Dies beinhaltet Plugins mit Antworten auf diese Frage.

Schauen Sie sich mark.js an

mark.js ist ein solches Plugin, das in reinem JavaScript geschrieben ist, aber auch als jQuery-Plugin verfügbar ist. Es wurde entwickelt, um mehr Möglichkeiten als die anderen Plugins mit folgenden Optionen zu bieten:

  • Suchen Sie nach Schlüsselwörtern separat anstelle des vollständigen Begriffs
  • Map Diakritika (Zum Beispiel, wenn "justo" auch mit "justò" übereinstimmen sollte)
  • Übereinstimmungen in benutzerdefinierten Elementen ignorieren
  • Verwenden Sie ein benutzerdefiniertes Hervorhebungselement
  • Verwenden Sie eine benutzerdefinierte Hervorhebungsklasse
  • benutzerdefinierte Synonyme zuordnen
  • Suche auch in iframes
  • nicht gefundene Begriffe erhalten

DEMO

Alternativ können Sie diese Geige sehen .

Anwendungsbeispiel :

// Highlight "keyword" in the specified context
$(".context").mark("keyword");

// Highlight the custom regular expression in the specified context
$(".context").markRegExp(/Lorem/gmi);

Es ist kostenlos und Open Source auf GitHub entwickelt ( Projektreferenz ).

Kumpel
quelle
11

Hier ist eine Variante, die Groß- und Kleinschreibung ignoriert und bewahrt:

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>";});
    });
};
bjarlestam
quelle
6
Dies funktioniert für einfachen Text, scheint jedoch Tags und Attribute nicht auszuschließen. dh Suchen Sie nach "lass", wenn Sie ein Klassenattribut für ein div in Ihrem innerHTML haben.
Jonathan
Wie wird diese Funktion aufgerufen?
Juli
innerHTMList böse, siehe meine Antwort hier. Funktioniert auch \\bnicht für Unicode-Zeichen. Darüber hinaus fehlt bei dieser Funktion fast alles, z. B. das Suchen in verschachtelten Kindern.
Alter
3

Mit der folgenden Funktion können Sie jedes Wort in Ihrem Text hervorheben.

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

Zielen Sie einfach auf das Element , das den Text enthält, und wählen Sie das zu kolorierende Wort und die Farbe Ihrer Wahl aus.

Hier ist ein Beispiel :

<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>

Verwendung ,

color_word('my_words', 'possible', 'hotpink')

Geben Sie hier die Bildbeschreibung ein

Azle hat auch eine nette Funktion dafür. Es werden Klassen verwendet. Weisen Sie daher jedem Textblock, auf den Sie abzielen möchten, einen Klassennamen zu.

az.style_word("target_class", target_instance, {
     "this_class" : "pink_word",
     "word" : "possible", // list any CSS styling after this line ...
     "color" : "hotpink", 
     "font-weight" : "bold"
})
Kybernetisch
quelle
2

Sie können mein Highlight-Plugin jQuiteLight verwenden , das auch mit regulären Ausdrücken funktioniert.

So installieren Sie mit npm :

npm install jquitelight --save

So installieren Sie mit dem Laubentyp :

bower install jquitelight 

Verwendung:

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

Weiterführende Verwendung hier

iamawebgeek
quelle
@ user3631654 nein das ist ein anderes plugin. Mein Plugin kann mit RegExp arbeiten und verfügt über eine Funktion von Smart Highlight. Wenn Sie Plugin enthalten haben, das Sie vor diesem Plugin erwähnt haben, können Sie es mitvar oldMark = $.fn.mark.noConflict()
iamawebgeek
Scheint, als hätte jquery.mark eine Methode, markRegExp()um auch benutzerdefinierte reguläre Ausdrücke hervorzuheben. Das sollte also kein Argument sein.
user3631654
Und @zazu, was meinst du mit "Smart Highlight"?
user3631654
@ user3631654 Wenn Sie Smart Highlight aktivieren und ein Wort "Konsequenz" übergeben, wird auch das Wort "Konsequenzen" und seine anderen Formen hervorgehoben. Wenn Sie jedoch "das" oder "bla" übergeben, wird kein "Thema" oder "Schwarz" verwendet.
Iamawebgeek
2

JSFiddle

Verwendet .each (), .replace (), .html (). Getestet mit jQuery 1.11 und 3.2.

Liest im obigen Beispiel das 'Hervorhebungswort', das hervorgehoben werden soll, und fügt das Span-Tag der Klasse 'Hervorheben' hinzu. Der Text 'Schlüsselwort' wird für alle ausgewählten Klassen in .each () hervorgehoben.

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;
}
Van Peer
quelle
1

Sie müssen den Inhalt des p-Tags abrufen und alle darin enthaltenen Farben durch die hervorgehobene Version ersetzen.

Sie müssen dafür nicht einmal jQuery haben. :-)

Sebastian Hoitz
quelle
9
Aber mit jQuery ist es einfacher, nicht wahr? ;)
Eikern
7
es kann mit Nokia 6310 gemacht werden, Sie brauchen nicht einmal einen PC dafür :-)
okliv
1

Ich habe eine sehr einfache Funktion geschrieben, die jQuery verwendet, um die Elemente zu iterieren, die jedes Schlüsselwort mit einer .highlight-Klasse umschließen.

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

Mehr Info:

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

Hawkee
quelle
2
Dies sucht nicht in verschachtelten Elementen, hat keine Funktion zum Entfernen von Markierungen und hat keine Lizenzinformationen.
Alter
Haben Sie etwas dagegen, mir zu erklären, was "gi" in "new RegExp (Begriff" gi ")" ist?
Vuquanghoang
0

Ich habe ein Repository mit einem ähnlichen Konzept erstellt, das die Farben der Texte ändert, deren Farben von HTML5 erkannt werden (wir müssen keine tatsächlichen # rrggbb-Werte verwenden und könnten nur die Namen verwenden, da HTML5 etwa 140 davon standardisiert).

Farben.js Farben.js

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

abe312
quelle
-2

Ist es möglich, dieses obige Beispiel zu erhalten:

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

Text in HTML-Tags wie nicht zu ersetzen, bricht sonst die Seite.

nickf
quelle
-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 hier

L. Grillo
quelle
hilightist kein gültiges HTML-Element
user3631654
Ignorieren Sie einfach diese Warnung. <Hight> ist Ihr benutzerdefiniertes Element. Sie können schreiben, was Sie wollen. Hast du die Geige gesehen?
L. Grillo
@nickf mein Skript machen genau das gleiche wie die akzeptierte Antwort
L.Grillo