Выделить слово с помощью jQuery
мне в принципе нужно выделить определенное слово в тексте. Например, представьте, что я хотел выделить слово "долор" в этом тексте:
<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 сделало бы вещи, возможно, немного более аккуратными.
13 ответов:
попробовать выделите: JavaScript text higlighting jQuery plugin.
/* 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); }); };
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');
почему использование самодельной функции подсветки является плохой идеей
причина, по которой это, вероятно, плохая идея, чтобы начать строить свою собственную функцию подсветки с нуля, потому что вы, безусловно, столкнетесь с проблемами, которые другие уже решили. Проблемы:
- вам нужно будет удалить текстовые узлы с элементами HTML, чтобы выделить ваши матчи, не разрушая события DOM и не вызывая регенерацию DOM снова и снова (что было бы в случае с например,
innerHTML)- если вы хотите удалить выделенные элементы, вам придется удалить HTML-элементы с их содержимым, а также объединить разделенные текстовые узлы для дальнейшего поиска. Это необходимо, потому что каждый плагин highlighter ищет внутри текстовых узлов совпадения, и если ваши ключевые слова будут разбиты на несколько текстовых узлов, они не будут найдены.
- также необходимо построить тесты, чтобы убедиться, что ваш плагин работает в ситуациях, которые вы не мысль. И я говорю о кросс-браузерных тестах!
звучит сложно? Если вы хотите, чтобы некоторые функции, такие как игнорирование некоторых элементов из подсветки, диакритическое отображение, отображение синонимов, поиск внутри iframes, поиск отдельных слов и т. д. это становится все более и более сложным.
использовать существующий плагин
при использовании существующего, хорошо реализованного плагина вам не нужно беспокоиться о вышеназванных вещах. В статье 10 jQuery текстовый маркер Плагины on Sitepoint сравнивает популярные плагины маркеров. Это включает в себя Плагины ответов на этот вопрос.
посмотреть Марк.js
Марк.js это такой плагин, который написан на чистом JavaScript, но также доступен как плагин jQuery. Он был разработан, чтобы предложить больше возможностей, чем другие плагины с вариантами:
поиск по ключевым словам отдельно полного термина
- диакритика карты (например, если "justo" также должен соответствовать "justò")
- игнорировать совпадения внутри пользовательских элементов
- использовать пользовательский элемент подсветки
- использовать пользовательский класс подсветки
- карта пользовательских синонимов
- поиск также внутри iframes
- получить не найденные термины
вы можете ознакомиться этот скрипка.
пример использования:
// Highlight "keyword" in the specified context $(".context").mark("keyword"); // Highlight the custom regular expression in the specified context $(".context").markRegExp(/Lorem/gmi);это бесплатный и разработанный с открытым исходным кодом на GitHub (ссылка на проект).
вот вариант, который игнорирует и сохраняет case:
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>";}); }); };
вам нужно получить содержимое тега p и заменить все долоры в нем выделенной версией.
вам даже не нужно jQuery для этого. : -)
вы можете использовать мой плагин выделения 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]+/));более продвинутое использование здесь
использует .каждый. ,)(заменять. ,)(формат HTML.)( Протестировано с помощью jQuery 1.11 и 3.2.
В приведенном выше примере читает "ключевое слово", которое будет выделено, и добавляет тег span с классом "highlight". Текст 'ключевое слово' выделяется для всех выбранных классов в поле .каждый.)(
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; }
Я написал очень простую функцию, которая использует jQuery для перебора элементов упаковки каждого ключевого слова .выделите класс.
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); }); }); } }Подробнее:
вы можете использовать следующие функции выделить любое слово в тексте.
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')
Я создал хранилище на аналогичной концепции, которая изменяет цвета текстов, цвета которых распознаются html5 (нам не нужно использовать фактические значения #rrggbb и можно просто использовать имена, поскольку html5 стандартизировал около 140 из них)
$( 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>
Если вы действительно игра, вы можете посмотреть источник StackOverflow для того, как он делает подсветку синтаксиса на блоках кода ;)
по существу, вам нужно будет просто динамически вставлять HTML (лучше всего использовать spans) там, где они вам нужны.
можно ли получить этот пример выше:
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-тегов, как, это в противном случае ломает страницу.
$(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 здесь


Comments