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

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

90 голосов
/ 23 сентября 2008

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

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

Ответы [ 13 ]

78 голосов
/ 23 сентября 2008

Попробуйте выделение: подсветка текста 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: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);
    });
};
41 голосов
/ 23 сентября 2008
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');
28 голосов
/ 24 сентября 2015

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

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

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

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

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

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

Взгляните на mark.js

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

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

DEMO

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

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

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

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

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

11 голосов
/ 20 апреля 2010

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

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>";});
    });
};
2 голосов
/ 25 июня 2017

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 голосов
/ 01 июня 2015

Вы можете использовать мой плагин выделения jQuiteLight , который также может работать с регулярными выражениями.

Для установки с помощью npm введите:

npm install jquitelight --save

Для установки с помощью беседка введите:

bower install jquitelight 

Использование:

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

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

1 голос
/ 01 марта 2018

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

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

Просто предназначается для элемента , который содержит текст, , выбирая слово для раскрашивания и color по выбору.

Вот пример :

<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 голос
/ 21 февраля 2013

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

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

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

0 голосов
/ 12 октября 2016

Я создал репозиторий по аналогичной концепции, который изменяет цвета текстов, цвета которых распознаются 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...