it-roy-ru.com

Выделите слово с помощью jQuery

Мне в основном нужно выделить определенное Слово в блоке текста. Например, представьте, что я хотел выделить слово «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>

Как мне преобразовать вышеупомянутое во что-то подобное

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

Edit: Как Себастьянуказал , это вполне возможно без jQuery - но я надеялся, что может быть специальный метод jQuery, который позволит вам делать селекторы для самого текста. Я уже активно использую jQuery на этом сайте, поэтому хранение всего в jQuery сделало бы вещи немного более аккуратными.

89
nickf

Попробуйте выделить: JavaScript подсветка текста плагин 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();
};

Также попробуйте «обновленная» версия оригинального скрипта .

/*
 * 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);
    });
};
77
mlarsen
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');
41
Andrew Hedges

Почему использование самодельной функции подсветки - плохая идея

Причина, по которой, вероятно, плохая идея начать создавать свою собственную функцию подсветки с нуля, заключается в том, что вы наверняка столкнетесь с проблемами, которые другие уже решили. проблемы:

  • Вам нужно было бы удалить текстовые узлы с элементами HTML, чтобы выделить совпадения, не разрушая события DOM и не вызывая повторную регенерацию DOM (что будет, например, в случае innerHTML)
  • Если вы хотите удалить выделенные элементы, вам придется удалить элементы HTML с их содержимым, а также объединить разделенные текстовые узлы для дальнейшего поиска. Это необходимо, потому что каждый плагин подсветки ищет совпадения в текстовых узлах, и если ваши ключевые слова будут разбиты на несколько текстовых узлов, они не будут найдены.
  • Вам также необходимо создать тесты, чтобы убедиться, что ваш плагин работает в ситуациях, о которых вы не задумывались. И я говорю о кросс-браузерных тестах!

Звучит сложно? Если вам нужны такие функции, как игнорирование некоторых элементов при выделении, отображение диакритических знаков, отображение синонимов, поиск внутри фреймов, поиск по отдельным словам и т.д., Это становится все более и более сложным.

Использовать существующий плагин

При использовании существующего, хорошо реализованного плагина, вам не нужно беспокоиться о вышеперечисленных вещах. В статье 10 плагинов для подсветки текста jQuery в Sitepoint сравниваются популярные плагины подсветки. Это включает в себя плагины ответов на этот вопрос.

Посмотрите на mark.js

mark.js - такой плагин, который написан на чистом JavaScript, но также доступен как плагин jQuery. Он был разработан, чтобы предложить больше возможностей, чем другие плагины, с возможностью:

  • искать ключевые слова отдельно вместо полного термина
  • диакритические знаки на карте (например, если «justo» также должен соответствовать «justò»)
  • игнорировать совпадения внутри пользовательских элементов
  • использовать пользовательский элемент подсветки
  • использовать пользовательский класс подсветки
  • карта пользовательских синонимов
  • искать также внутри фреймов
  • получить не найденные условия

ДЕМО

В качестве альтернативы вы можете увидеть это скрипка .

Пример использования:

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

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

Это бесплатный и разработанный с открытым исходным кодом на GitHub ( ссылка на проект ).

27
dude

Вот вариант, который игнорирует и сохраняет регистр:

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

JSFiddle

Использует .each (), .replace (), .html (). Протестировано с jQuery 1.11 и 3.2.

В приведенном выше примере читается «ключевое слово», которое нужно выделить, и добавляется тег span с классом «highlight». Текст «ключевое слово» подсвечивается для всех выбранных классов в .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;
}
2
Van Peer

Вы можете использовать мой плагин подсветки 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]+/));

Более расширенное использование здесь

2
iamawebgeek

Вам нужно получить содержимое тега p и заменить все цвета в нем на выделенную версию.

Вам даже не нужно иметь jQuery для этого. :-)

2
Sebastian Hoitz

Я написал очень простую функцию, которая использует 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/

1
Hawkee

Вы можете использовать следующую функцию function, чтобы выделить любое слово в вашем тексте. 

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

 enter image description here

1
Cybernetic

Я создал хранилище по аналогичной концепции, которая изменяет цвета текстов, цвета которых распознаются html5 (нам не нужно использовать фактические значения #rrggbb и мы могли бы просто использовать имена, так как html5 стандартизирован около 140 из них)

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>

0
abe312