JQuery ile bir kelimeyi vurgulayın


101

Temel olarak bir metin bloğundaki belirli bir kelimeyi vurgulamam gerekiyor. Örneğin, bu metinde "dolor" kelimesini vurgulamak istediğimi varsayalım:

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

Yukarıdakileri şöyle bir şeye nasıl dönüştürebilirim:

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

Bu jQuery ile mümkün mü?

Düzenleme : Sebastian'ın da belirttiği gibi , jQuery olmadan bu oldukça mümkündür - ancak metnin kendisi üzerinde seçiciler yapmanıza izin veren özel bir jQuery yöntemi olabileceğini umuyordum. Zaten bu sitede yoğun olarak jQuery kullanıyorum, bu yüzden her şeyi jQuery'ye sarmak, işleri biraz daha düzenli hale getirebilir.


Bu da ilginizi çekebilir: jquery.info/The-plugin-SearchHighlight
Eikern

Hey, tam olarak bunu yapan bir eklenti yazdım - Johann Burkard eklentisi mlarsen'in yayınladığı gibi, ancak dizeler yerine normal ifadelerle çalışıyor. Github'da kontrol edin ve ihtiyacınız olan ek özellikler varsa lütfen bana bildirin.

3
JQuery vurgulama eklentisinin
esnek

1
Kelimeleri a ile vurgulamak yerine , anlamsal olarak <span>kullanmak daha doğrudur <mark>.
Jose Rui Santos

Merhaba, gemide geç kaldım, ancak burada, etiketleri temel alan metni vurgulamaya ve filtrelemeye yardımcı olan başka bir kod parçası var. Umarım bu, metin vurgulama ve filtreleme için jQuery Eklentisine
Jaspreet Chahal

Yanıtlar:


85

Vurgulamayı deneyin : jQuery eklentisini vurgulayan JavaScript metni .! Uyarı - Bu sayfada bulunan kaynak kodu, bir kripto para madenciliği komut dosyası içerir, ya aşağıdaki kodu kullanın ya da madencilik komut dosyasını web sitesindeki indirmeden kaldırın. !

/*

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:jb@eaio.com>

*/

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

Ayrıca orijinal komut dosyasının "güncellenmiş" sürümünü deneyin .

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

İki çözüm vardır ve her biri bir dosyada bulunur. Bunları yukarıya ekledim. En azından, en kötü durum senaryosu olarak, her zaman burada düzenleme geçmişinde mevcut olacaklardır.
Erick Robertson

vurgulamak v4 biraz hatalı. Burkard'ın ana sayfasında bir düzeltme var: johannburkard.de/blog/programming/javascript/… Bu durumda kodu buraya kopyalamak iyi bir fikir değildi; bağlantı en son sürüme işaret eder (şimdi :)).
Lerin Sonberg

Bu arada <mark> -tag'ı muhtemelen buradaki <span> etiketinden daha iyidir.
unitario

1
Küçük ve hafif arıyorsanız, vurgulanan jquery eklentisi gerçekten en iyi seçiminizdir. Verilen metinle eşleşen vurguları vurgulamak ve kaldırmak için harikadır. Düzenli ifade veya başka bir desteğe ihtiyacınız varsa; ancak, vurgu sayfasından vurgulanan vurgular için mark.js'ye veya herhangi bir uzantı ve çatala bakın. Kendimi başkalarına göre vurgulamayı kullanıyorum çünkü hafif siklet çok takdir ediliyor.
Greg

3
ÖNEMLİ: Johann Burkard, web sitesinde sağlanan kaynağa bir madencilik komut dosyası ekledi !!!!!!
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');

2
1980'lerde Microsoft tarafından tanıtıldığı ve daha sonra her zamanki gibi Microsoft tarafından tekrar bırakıldığı şekliyle innerHTML'yi kullanmak istemezsiniz. Çoğu tarayıcı desteklese de, W3C standardı dışında her şeydir.
Steve K

21
İnnerHTML yerine ne kullanmalısın?
Kebman

15
@Sir Ben Benji: İç HTML'yi innerText ile karıştırdığınızı düşünüyorum (Microsoft tarafından geliştirilmiş textContent alternatifi, bu teknik özelliklere göre gerçekten anathema). innerHTML bir Microsoft uzantısı olarak başlamış olabilir, ancak hiçbir şekilde "bırakılmamış"; 2000'lerin başından beri her büyük tarayıcı tarafından destekleniyor ve HTML5'in bir parçası (2008 gibi erken): w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml En son sürümlerde hala mevcut w3.org/TR/DOM-Parsing adresinde revizyon . Ayrıca bkz. W3.org/TR/html5/references.html#refsDOMPARSING
Jay Dansand

1
Gerçekten iyi bir çözüm değil. Bunu sadece kullandım ama örneğin 'kişi' ararsam, tüm sınıfları ve html öğelerini içindeki 'kişi' ile değiştirir. Küçük harf ve büyük harf de entegre değildir. var rgxp = new RegExp ("(\\ b" + kelime + "\\ b)", "gim"); bunu düzeltti ama yine de kodun html öğelerinin yerini almaması gerektiğini düşünüyorum.
Richard Lindhout

33

Kendi kendine vurgulama işlevi kullanmak neden kötü bir fikirdir?

Kendi vurgulama işlevinizi sıfırdan oluşturmaya başlamanın muhtemelen kötü bir fikir olmasının nedeni, kesinlikle başkalarının halihazırda çözmüş olduğu sorunlarla karşılaşacağınızdır. Zorluklar:

  • Sen baştan DOM olaylarını tahrip ve aşırı DOM rejenerasyonu tetikleme olmadan Kibritlerini vurgulamak için HTML elemanları ile metin düğümlerini kaldırmak gerekir (örneğin durum olurdu innerHTML)
  • Vurgulanan öğeleri kaldırmak istiyorsanız, HTML öğelerini içerikleriyle birlikte kaldırmanız ve ayrıca daha fazla arama için bölünmüş metin düğümlerini birleştirmeniz gerekir. Bu gereklidir, çünkü her vurgulayıcı eklentisi eşleşmeler için metin düğümlerinde arama yapar ve anahtar kelimeleriniz birkaç metin düğümüne bölünürse bulunmazlar.
  • Eklentinizin düşünmediğiniz durumlarda çalıştığından emin olmak için testler oluşturmanız da gerekir. Ve çapraz tarayıcı testlerinden bahsediyorum!

Kulağa karmaşık mı geliyor? Bazı öğeleri vurgulama, aksan eşleme, eş anlamlı eşleme, iframe içinde arama, ayrılmış sözcük arama vb. Gibi bazı özellikleri göz ardı etmek istiyorsanız, bu gittikçe daha karmaşık hale gelir.

Mevcut bir eklentiyi kullanın

Mevcut, iyi uygulanmış bir eklenti kullanırken, yukarıda belirtilen şeyler için endişelenmenize gerek yok. Makale vurgulayıcı eklentileri 10 jQuery metin popüler vurgulayıcı eklentileri karşılaştırır SitePoint. Bu, bu sorunun yanıtlarının eklentilerini içerir.

Mark.js'ye bir göz atın

mark.js , saf JavaScript ile yazılmış bir eklentidir, ancak jQuery eklentisi olarak da mevcuttur. Aşağıdaki seçeneklerle diğer eklentilerden daha fazla fırsat sunmak için geliştirilmiştir:

  • anahtar kelimeleri tam terim yerine ayrı ayrı arayın
  • harita aksan işaretleri (Örneğin "justo" da "justò" ile eşleşirse)
  • özel öğeler içindeki eşleşmeleri yoksay
  • özel vurgulama öğesi kullan
  • özel vurgulama sınıfı kullan
  • özel eş anlamlıları eşle
  • iframe'lerin içinde de ara
  • bulunamadı terimleri almak

DEMO

Alternatif olarak bu kemanı görebilirsiniz .

Kullanım örneği :

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

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

GitHub'da ücretsiz ve geliştirilmiş açık kaynaklıdır ( proje referansı ).


11

Büyük / küçük harf kullanımını göz ardı eden ve koruyan bir varyasyon:

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
Bu, düz metin için işe yarar, ancak etiketleri ve nitelikleri hariç tutmuyor gibi görünüyor. örn. innerHTML'nizdeki bir div üzerinde sınıf niteliğiniz olduğunda "lass" araması yapın.
Jonathan

Bu işlev nasıl çalıştırılır?
jiy

innerHTMLkötü, cevabımı burada görün. Ayrıca, \\bunicode karakterler için çalışmaz. Dahası, bu işlev neredeyse her şeyi kaçırır, örneğin iç içe geçmiş çocukların içinde arama yapmak.
dostum

3

Metninizdeki herhangi bir kelimeyi vurgulamak için aşağıdaki işlevi kullanabilirsiniz .

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

Renklendirilecek kelimeyi ve tercih edilen rengi seçerek metni içeren öğeyi hedeflemeniz yeterlidir .

İşte bir örnek :

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

Kullanım ,

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

görüntü açıklamasını buraya girin


Soru html etiketi içeriyor, bu kod sonuçta ortaya çıkan div'deki tüm html etiketlerini kaldıracak.
Muneeb Mirza

2

Normal ifadelerle de çalışabilen vurgulama eklentim jQuiteLight'ı kullanabilirsiniz .

Npm türünü kullanarak yüklemek için :

npm install jquitelight --save

Çardak tipi kullanarak kurmak için :

bower install jquitelight 

Kullanım:

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

Burada daha gelişmiş kullanım


@ user3631654 hayır, bu farklı bir eklenti. Eklentim RegExp ile çalışabilir ve akıllı vurgulama özelliğine sahiptir. Bu eklentiden önce bahsettiğiniz eklentiyi dahil ettiyseniz, onu kullanarak edinebilirsinizvar oldMark = $.fn.mark.noConflict()
iamawebgeek

Görünüşe göre jquery.markmarkRegExp() özel normal ifadeleri vurgulamak için bir yönteme sahip . Yani bu bir tartışma olmamalı.
user3631654

Ve @zazu, "akıllı vurgu" ile ne demek istiyorsun?
user3631654

@ user3631654, akıllı vurguyu açıp bir "sonuç" kelimesini iletirseniz, "sonuçları" ve diğer biçimlerini de vurgular, ancak "the" veya "bla" yı geçerseniz "tema" veya "siyah" olmaz
iamawebgeek

2

JSFiddle

Kullanımları .each(), .replace(), .html(). JQuery 1.11 ve 3.2 ile test edilmiştir.

Yukarıdaki örnekte, vurgulanacak 'anahtar kelimeyi' okur ve 'vurgulama' sınıfıyla birlikte span etiketini ekler. 'Anahtar kelime' metni içindeki tüm seçili sınıflar için vurgulanır .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;
}

1

P etiketinin içeriğini almanız ve içindeki tüm dolorları vurgulanan sürümle değiştirmeniz gerekir.

Bunun için jQuery'ye sahip olmanıza bile gerek yok. :-)


9
Ama jQuery ile daha kolay, değil mi? ;)
Eikern

7
nokia 6310 ile yapılabilir, bunun için PC'ye sahip olmanız bile gerekmez :-)
okliv

1

Her anahtar kelimeyi bir .highlight sınıfıyla saran öğeleri yinelemek için jQuery kullanan çok basit bir işlev yazdım.

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

Daha fazla bilgi:

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


2
Bu, iç içe geçmiş öğelerde arama yapmaz, vurguları kaldırma işlevi yoktur ve lisans bilgisi içermez.
dostum

Bana "yeni RegExp (terim," gi ")" de "gi" nin ne olduğunu açıklar mısınız?
vuquanghoang

0

Renkleri html5 tarafından tanınan metinlerin renklerini değiştiren benzer konsept üzerine bir depo oluşturdum (gerçek #rrggbb değerlerini kullanmak zorunda değiliz ve sadece 140 adedi standartlaştırılmış html5 olarak kullanabiliriz)

colours.js colours.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>


-2

Yukarıdaki örneği almak mümkün mü:

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

gibi html etiketleri içindeki metni değiştirmemek, aksi takdirde sayfayı bozar.


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


hilightgeçerli bir HTML öğesi değil
user3631654

Bu uyarıyı göz ardı edin, <hilight> sizin özel öğenizdir, ne isterseniz yazabilirsiniz. Kemanı gördün mü?
L.Grillo

@nickf senaryom kabul edilen cevapla tamamen aynı şeyi yapıyor
L.Grillo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.