Поиск JQuery в статической HTML-странице с подсветкой найденного слова
Я пытаюсь сделать простой поиск внутри статической HTML-страницы с помощью JQuery. Я должен упомянуть, что это только мой первый опыт работы с JQuery.
Я пытаюсь изменить фон найденного слова на странице, и это то, что я пробовал до сих пор:
myJavascript.js:
$(document).ready(function(){
$('#searchfor').keyup(function(){
page = $('#all_text').text();
searchedText = $('#searchfor').val();
$("p:contains('"+searchedText+"')").css("color", "white");
});
});
Здесь также код HTML:
page.html:
<html>
<head>
<title>Test page</title>
</head>
<body bgcolor="#55c066">
<input type="text" id="searchfor"></input>
<p id="all_text">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euism modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.
<font color="red">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tinci futurum.</font>
</p>
</body>
<script src="jquery-1.7.2.min.js"></script>
<script src="myJavascript.js"></script>
</html>
После проверки страницы с помощью Firebug я вижу, что переменные в JQuery действительно получают значение из поля ввода, но я предполагаю, что я испортил выделенную часть.
Заранее благодарим за помощь!
Ответы
Ответ 1
Сделайте что-то вроде этого
$("p:contains('"+searchedText+"')").each( function( i, element ) {
var content = $(element).text();
content = content.replace( searchedText, '<span class="search-found">' + searchedText + '</span>' );
element.html( content );
});
.search-found {
text-decoration: underline;
}
p.s. это будет работать, только если каждый из "элементов" имеет только текстовое содержимое, иначе он удалит дочерние узлы.
EDIT: удалено дополнительное ")" в обратном вызове each
Ответ 2
Почему использование функции самозащитой подсветки - это плохая идея
Причина, по которой, вероятно, плохая идея начать создавать собственную функцию подсветки с нуля, состоит в том, что вы наверняка столкнетесь с проблемами, которые другие уже решили. Задачи:
- Вам нужно будет удалить текстовые узлы с элементами HTML, чтобы выделить ваши совпадения, не разрушая события DOM и запуская регенерацию DOM снова и снова (что было бы, например, с помощью
innerHTML
)
- Если вы хотите удалить выделенные элементы, вам нужно будет удалить элементы HTML с их содержимым, а также объединить разделенные текстовые узлы для дальнейшего поиска. Это необходимо, потому что каждый плагин highlighter ищет внутри текстовых узлов для совпадений, и если ваши ключевые слова будут разделены на несколько текстовых узлов, они не будут найдены.
- Вам также нужно будет создать тесты, чтобы убедиться, что ваш плагин работает в ситуациях, о которых вы не думали. И я говорю о кросс-браузерных тестах.
Звучит сложно? Если вам нужны некоторые функции, такие как игнорирование некоторых элементов выделения, диакритическое отображение, сопоставление синонимов, поиск внутри iframe, разделенный поиск по словам и т.д., Это становится все более сложным.
Использовать существующий плагин
При использовании существующего, хорошо внедренного плагина вам не нужно беспокоиться о вышеуказанных вещах. В статье 10 jQuery текстовых плагинов с подсветкой на сайте Sitepoint сравниваются популярные плагины с подсветкой. Это включает в себя плагины ответов на этот вопрос.
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 (ссылка на проект).
Пример выделения ключевого слова mark.js с кодом
$(function() {
$("input").on("input.highlight", function() {
// Determine specified search term
var searchTerm = $(this).val();
// Highlight search term inside a specific context
$("#context").unmark().mark(searchTerm);
}).trigger("input.highlight").focus();
});
mark {
background: orange;
color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/mark.js/7.0.0/jquery.mark.min.js"></script>
<input type="text" value="test">
<div id="context">
Lorem ipsum dolor test sit amet
</div>
Ответ 3
Вот мой: http://jsfiddle.net/x8rpY/1/
JS:
$('#searchfor').keyup(function(){
var page = $('#all_text');
var pageText = page.text().replace("<span>","").replace("</span>");
var searchedText = $('#searchfor').val();
var theRegEx = new RegExp("("+searchedText+")", "igm");
var newHtml = pageText.replace(theRegEx ,"<span>$1</span>");
page.html(newHtml);
});
CSS
#all_text span
{
text-decoration:underline;
background-color:yellow;
}
Работает также для повторного поиска.
Ответ 4
$(function() {
$("input").on("input.highlight", function() {
// Determine specified search term
var searchTerm = $(this).val();
// Highlight search term inside a specific context
$("#context").unmark().mark(searchTerm);
}).trigger("input.highlight").focus();
});
mark {
background: orange;
color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/mark.js/7.0.0/jquery.mark.min.js"></script>
<input type="text" value="test">
<div id="context">
Lorem ipsum dolor test sit amet
</div>
Ответ 5
(для чего вы хотите использовать фоновый цвет, а не цвет, для фона)
Я бы создал класс css для обычного и отдельного (унаследованного) класса css для выделенного текста, а затем с помощью JQuery изменил класс css, когда вы найдете то, что ищете.
Только мои первоначальные мысли, хотя и не уверены, есть ли лучший способ сделать это.
EDIT: если вы хотите изменить только определенное слово, вам придется изменить innerHTML, чтобы поместить его в отдельный тег в этой точке.
Ответ 6
Вот еще один пример, который я быстро взломал: http://jsfiddle.net/VCJUX/