Выделите слово с помощью 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?

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

Ответ 1

Попробуйте выделить: 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);
    });
};

Ответ 2

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

Ответ 3

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

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

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

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

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

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

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

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

  • поиск ключевых слов отдельно, а не полный термин
  • map diacritics (Например, если "justo" также должен соответствовать "justò" )
  • игнорировать совпадения внутри пользовательских элементов
  • использовать пользовательский элемент выделения
  • использовать пользовательский класс выделения
  • отображение пользовательских синонимов
  • поиск внутри внутри iframe
  • получить не найденные условия

DEMO

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

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

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

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

Это бесплатный и разработанный open-source на GitHub (ссылка на проект).

Ответ 4

Здесь вариация, которая игнорирует и сохраняет случай:

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

Ответ 5

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

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 html() function will produce the desired result.
</div>

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

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

enter image description here

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

Ответ 6

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

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

Ответ 7

JSFiddle

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

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

Ответ 8

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

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

Ответ 9

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

Ответ 10

Я создал репозиторий на аналогичной концепции, которая изменяет цвета текстов, цвета которых распознаются html5 (мы не знаем, t должны использовать фактические значения #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>

Ответ 11

Если вы действительно играете, вы можете просмотреть источник StackOverflow для того, как он выделяет синтаксис на кодовых блоках;)

По существу вам придется просто динамически вставлять HTML (в зависимости от ваших возможностей).

Ответ 12

Можно ли получить этот вышеприведенный пример:

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-тегов, например, это в противном случае ломает страницу.

Ответ 13

$(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 здесь