Поиск 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

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, чтобы поместить его в отдельный тег в этой точке.