jQuery로 단어 강조


101

기본적으로 텍스트 블록에서 특정 단어를 강조 표시해야합니다. 예를 들어,이 텍스트에서 "고통"이라는 단어를 강조하고 싶다고 가정 해보십시오.

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

위의 내용을 다음과 같이 어떻게 변환합니까?

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

jQuery로 가능합니까?

편집 : Sebastian이 지적했듯이 이것은 jQuery 없이도 가능하지만 텍스트 자체에서 선택기를 할 수있는 jQuery의 특별한 방법이 있기를 바랐습니다. 나는 이미이 사이트에서 jQuery를 많이 사용하고 있기 때문에 모든 것을 jQuery로 묶어두면 아마도 좀 더 깔끔해질 것이다.


이것은 또한 흥미로울 수 있습니다 : jquery.info/The-plugin-SearchHighlight
Eikern

이봐 요, 정확히이 작업을 수행하는 플러그인을 작성했습니다. 이것은 Johann Burkard 플러그인 mlarsen이 게시 한 것과 비슷하지만 문자열 대신 정규 표현식으로 작동합니다. github에서 확인하고 필요한 추가 기능이 있으면 알려주세요.

3
jQuery 하이라이트 플러그인의 관대 한 버전이 필요한 경우 : http://www.frightanic.com/2011/02/27/lenient-jquery-highlight-plugin-javascript/
Marcel Stör

1
단어를으로 강조 표시하는 대신 의미 론적으로 <span>를 사용하는 것이 더 정확합니다 <mark>.
Jose Rui Santos

안녕하세요 저는 늦게 탑승했지만 태그를 기반으로 텍스트를 강조 표시하고 필터링하는 데 도움이되는 또 다른 코드 스 니펫이 있습니다. 바라건대 그 의지 도움말 사람 jQuery를 텍스트 강조를위한 플러그인 및 필터링
Jaspreet Chahal

답변:


85

시도 강조 : 자바 스크립트 텍스트가 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: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();
};

또한 원본 스크립트"업데이트 된"버전을 사용해보십시오 .

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

두 가지 솔루션이 있으며 각각 하나의 파일에 포함됩니다. 위에 추가했습니다. 최소한 최악의 경우에는 편집 기록에서 항상 여기에서 사용할 수 있습니다.
Erick Robertson

하이라이트 v4는 약간 버그가 있습니다. Burkard의 홈페이지에 수정 사항이 있습니다. johannburkard.de/blog/programming/javascript/… 이 경우 여기에 코드를 복사하는 것은 좋지 않았습니다. 링크는 최신 버전을 가리 킵니다 (현재 :)).
Lerin Sonberg

그건 그렇고 <mark>-태그는 여기에서 <span> 태그보다 낫습니다.
unitario

1
작고 가벼운 것을 찾고 있다면 하이라이트 jquery 플러그인이 최선의 선택입니다. 주어진 텍스트와 일치하는 하이라이트를 강조 표시하고 제거하는 데 유용합니다. 정규 표현식이나 기타 지원이 필요한 경우 그러나 하이라이트 페이지에서 링크 된 하이라이트에 대한 mark.js 또는 확장 및 포크를 확인하십시오. 가벼움이 높이 평가되기 때문에 나는 다른 사람들보다 자신을 강조 표시합니다.
Greg

3
중요 : Johann Burkard는 그의 웹 사이트에 제공된 소스에 마이닝 스크립트를 포함했습니다 !!!!!!
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
80 년대에 마이크로 소프트에 의해 소개되었고, 나중에 마이크로 소프트가 평소처럼 다시 떨어 뜨린 것처럼 innerHTML을 사용하고 싶지 않습니다. 대부분의 브라우저가 지원하지만 W3C 표준을 제외한 모든 것입니다.
Steve K

21
innerHTML 대신 무엇을 사용해야합니까?
Kebman 2013 년

15
@Sir Ben Benji : innerHTML과 innerText를 혼동하고 있다고 생각합니다 (텍스트 콘텐츠에 대한 Microsoft에서 개발 한 대안, 실제로 사양에 대한 혐오감). innerHTML은 Microsoft 확장으로 시작되었을 수 있지만 "삭제"되지 않았습니다. 2000 년대 초반부터 모든 주요 브라우저에서 지원되었으며 HTML5의 일부입니다 (빠르면 2008 년) : w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml 여전히 최신 버전에 있습니다. w3.org/TR/DOM-Parsing 에서 개정 . 참조 w3.org/TR/html5/references.html#refsDOMPARSING
제이 Dansand

1
정말 좋은 해결책이 아닙니다. 나는 이것을 방금 사용했지만 예를 들어 'person'을 검색하면 모든 클래스와 html 요소가 'person'으로 대체됩니다. 그리고 소문자와 대문자도 통합되지 않습니다. var rgxp = new RegExp ( "(\\ b"+ word + "\\ b)", "gim"); 수정했지만 여전히 코드가 html 요소를 대체해서는 안된다고 생각합니다.
Richard Lindhout

32

직접 만든 하이라이트 기능을 사용하는 것이 나쁜 생각 인 이유

처음부터 자신 만의 하이라이트 기능을 구축하는 것이 좋지 않은 이유는 다른 사람들이 이미 해결 한 문제에 부딪 힐 것이기 때문입니다. 과제 :

  • DOM 이벤트를 파괴하지 않고 DOM 재생성을 반복적으로 트리거하지 않고 일치 항목을 강조하기 위해 HTML 요소가있는 텍스트 노드를 제거해야합니다 (예 :이 경우 innerHTML).
  • 강조 표시된 요소를 제거하려면 콘텐츠와 함께 HTML 요소를 제거하고 추가 검색을 위해 분할 된 텍스트 노드를 결합해야합니다. 이는 모든 하이 라이터 플러그인이 텍스트 노드 내부에서 일치를 검색하고 키워드가 여러 텍스트 노드로 분할되면 찾을 수 없기 때문에 필요합니다.
  • 또한 생각하지 않은 상황에서 플러그인이 작동하는지 확인하기 위해 테스트를 빌드해야합니다. 그리고 저는 브라우저 간 테스트에 대해 이야기하고 있습니다!

복잡하게 들리나요? 강조 표시, 분음 부호 매핑, 동의어 매핑, iframe 내부 검색, 분리 된 단어 검색 등에서 일부 요소를 무시하는 것과 같은 일부 기능을 원하는 경우 이는 점점 더 복잡해집니다.

기존 플러그인 사용

잘 구현 된 기존 플러그인을 사용할 때 위에 언급 된 것에 대해 걱정할 필요가 없습니다. Sitepoint 의 기사 10 jQuery 텍스트 하이 라이터 플러그인은 인기있는 하이 라이터 플러그인 을 비교합니다. 여기에는이 질문의 답변 플러그인이 포함됩니다.

mark.js 살펴보기

mark.js 는 순수한 JavaScript로 작성된 플러그인이지만 jQuery 플러그인으로도 사용할 수 있습니다. 다음과 같은 옵션이있는 다른 플러그인보다 더 많은 기회를 제공하도록 개발되었습니다.

  • 전체 용어 대신 개별적으로 키워드 검색
  • 지도 분음 부호 (예 : "justo"가 "justò"와 일치해야하는 경우)
  • 맞춤 요소 내 일치 무시
  • 맞춤 강조 표시 요소 사용
  • 사용자 지정 강조 표시 클래스 사용
  • 맞춤 동의어 매핑
  • iframe 내에서도 검색
  • 찾을 수없는 용어 받기

데모

또는 이 바이올린을 볼 수 있습니다 .

사용 예 :

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

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

GitHub에서 무료로 개발 된 오픈 소스입니다 ( 프로젝트 참조 ).


11

다음은 대소 문자를 무시하고 보존하는 변형입니다.

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
이것은 일반 텍스트에서 작동하지만 태그와 속성을 제외하지 않는 것 같습니다. 즉, innerHTML의 div에 클래스 속성이있을 때 "lass"를 검색합니다.
Jonathan

이 함수는 어떻게 호출됩니까?
jiy

innerHTML여기에서 내 대답을 참조하십시오. 또한 \\b유니 코드 문자에 대해서는 작동하지 않습니다. 더욱이이 함수는 중첩 된 자식 내부 검색과 같이 거의 모든 것을 놓칩니다.
dude

3

다음 기능 을 사용 하여 텍스트의 모든 단어를 강조 표시 할 수 있습니다 .

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

간단히 요소 대상 텍스트를 포함 단어 선택 색상 화와 색상 선택을.

다음은 예입니다 .

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

사용법 ,

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

여기에 이미지 설명 입력

Azle 은 이것에 대한 좋은 기능도 가지고 있습니다. 클래스를 사용하므로 대상으로 지정하려는 텍스트 블록에 클래스 이름을 지정하기 만하면됩니다.

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

2

정규식과 함께 작동 할 수있는 하이라이트 플러그인 jQuiteLight 를 사용할 수 있습니다.

npm 유형을 사용하여 설치하려면 :

npm install jquitelight --save

bower 유형을 사용하여 설치하려면 :

bower install jquitelight 

용법:

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

여기에 고급 사용법


@ user3631654 아니 그건 다른 플러그인입니다. 내 플러그인은 RegExp와 함께 작동 할 수 있으며 스마트 하이라이트 기능이 있습니다. 이 플러그인 전에 언급 한 플러그인 당신이 포함되어있는 경우, 당신은 그것을 사용하여 얻을 수 있습니다var oldMark = $.fn.mark.noConflict()
iamawebgeek

jquery.mark 에는 markRegExp()사용자 지정 정규식을 강조 표시 하는 메서드가있는 것 같습니다 . 그래서 이것은 논쟁이되어서는 안됩니다.
user3631654

@zazu, "스마트 하이라이트"란 무엇을 의미합니까?
user3631654

@ user3631654 스마트 강조 표시를 켜고 "consequnce"라는 단어를 전달하면 "consequences"라는 단어와 다른 형식도 강조 표시되지만 "the"또는 "bla"를 전달하면 "theme"또는 "black"을 사용하지 않습니다.
iamawebgeek

2

JSFiddle

.each (), .replace (), .html ()을 사용합니다. jQuery 1.11 및 3.2로 테스트되었습니다.

위의 예에서 강조 표시 할 'keyword'를 읽고 'highlight'클래스와 함께 span 태그를 추가합니다. .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 태그의 내용을 가져 와서 그 안의 모든 dolors를 강조 표시된 버전으로 바꿔야합니다.

이를 위해 jQuery가 필요하지 않습니다. :-)


9
그러나 jQuery를 사용하면 더 쉽습니다. ;)
Eikern

7
이 노키아 6310과 함께 할 수있는, 당신도 :-)이를 위해 PC가 필요하지 않습니다
okliv

1

jQuery를 사용하여 각 키워드를 .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);
            });
        });
    }
}

더 많은 정보:

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


2
중첩 된 요소를 검색하지 않고 강조 표시를 제거하는 기능이 없으며 라이센스 정보가 없습니다.
친구

"new RegExp (term,"gi ")"에서 'gi'가 무엇인지 설명해 주시겠습니까?
vuquanghoang

0

html5에서 색상을 인식하는 텍스트의 색상을 변경하는 유사한 개념 으로 저장소 를 만들었습니다 (실제 #rrggbb 값을 사용할 필요가 없으며 약 140 개에 대해 표준화 된 html5로 이름을 사용할 수 있음)

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

위의 예를 얻을 수 있습니까?

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

와 같은 html 태그 내부의 텍스트를 바꾸지 않으려면 페이지가 손상됩니다.


-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


hilight유효한 HTML 요소가 없습니다
user3631654

이 경고를 무시하십시오. <hilight>는 사용자 지정 요소입니다. 원하는대로 작성할 수 있습니다. 바이올린 봤어?
L.Grillo

@nickf 내 스크립트 허용 대답 정확히 같은 일을 수행
L.Grillo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.