Контакты

Поиск на странице с помощью javascript. JavaScript поиск по странице Результат работы формы открыть в новой вкладке с помощью атрибута target

Многие посетители сайтов не знают о поиске по странице по нажатию Ctrl+F и ищут необходимый фрагмент глазами, просто пролистывая текст. Этот способ становится проблематичным, если на странице текста больше, чем три-четыре экрана. Для таких посетителей я решил реализовать поиск по странице с использованием jQuery.
Пример подобного поиска есть на сайте Конституции РФ , но там он работает как-то странно.

ПредупреждениеЯ не профессиональный программист, просьба не пинать за кривой код и возможное изобретение велосипеда.HTML-формаПервым делом разместим на странице HTML-код формы поиска. Форма включает два элемента - поле для ввода текста и DIV для вывода результатов поиска.

CSSЗадаём два стиля: первый - для выделения фрагмента, второй - для ссылки на первый фрагмент.
span.highlight { background-color: #C6D9DB; cursor: pointer; } span.splink { color: #0A5794; cursor: pointer; } Настройка поиска var minlen = 3; // минимальная длина слова var paddingtop = 30; // отступ сверху при прокрутке var scrollspeed = 200; // время прокрутки var keyint = 1000; // интервал между нажатиями клавиш Подсветка фрагментовБазовая функциональность - подсветка фрагментов в тексте. Делается это с помощью регулярных выражений.
function dosearch() { term = jQuery("#spterm").val(); jQuery("span.highlight").each(function(){ //удаляем старую подсветку jQuery(this).after(jQuery(this).html()).remove(); }); var t = ""; jQuery("div.entry-content").each(function(){ // в селекторе задаем область поиска jQuery(this).html(jQuery(this).html().replace(new RegExp(term, "ig"), "$&")); // выделяем найденные фрагменты n = jQuery("span.highlight").length; // количество найденных фрагментов console.log("n = "+n); if (n==0) jQuery("#spresult").html("Ничего не найдено"); else jQuery("#spresult").html("Результатов: "+n); }); } jQuery("#spterm").keyup(function(){ if (jQuery("#spterm").val()!=term) // проверяем, изменилась ли строка if (jQuery("#spterm").val().length>=minlen) { // проверяем длину строки dosearch(); // если все в порядке, приступаем к поиску } else jQuery("#spresult").html(" "); // если строка короткая, убираем текст из DIVа с результатом }); Переход между фрагментамиМало просто выделить фрагменты, гораздо удобнее организовать быстрый переход между ними. Под формой размещаем ссылку перехода на первый найденный фрагмент. Чтобы не занимать место стрелками, клик на каждый фрагмент ведет к следующему. Клик на последний фрагмент возвращает пользователя к форме поиска.
if (n==0) jQuery("#spresult").html("Ничего не найдено"); else jQuery("#spresult").html("Результатов: "+n); if (n>1) // если больше одного фрагмента, то добавляем переход между ними { var i = 0; jQuery("span.highlight").each(function(i){ jQuery(this).attr("n", i++); // нумеруем фрагменты, более простого способа искать следующий элемент не нашел }); jQuery("span.highlight").not(":last").attr({title: "Нажмите, чтобы перейти к следующему фрагменту"}).click(function(){ // всем фрагментам, кроме последнего, добавляем подсказку jQuery("body,html").animate({scrollTop: jQuery("span.highlight:gt("+jQuery(this).attr("n")+"):first").offset().top-paddingtop}, scrollspeed); // переход к следующему фрагменту }); jQuery("span.highlight:last").attr({title: "Нажмите, чтобы вернуться к форме поиска"}).click(function(){ jQuery("body,html").animate({scrollTop: jQuery("#spterm").offset().top-paddingtop}, scrollspeed); // переход к форме поиска }); } Задержка запуска поискаПоиск в большом тексте и подсветка занимают несколько секунд, на которые страница зависает. При наборе длинного слова поиск производится после каждой введённой буквы.
jQuery("#spterm").keyup(function(){ var d1 = new Date(); time_keyup = d1.getTime(); if (jQuery("#spterm").val()!=term) // проверяем, изменилась ли строка if (jQuery("#spterm").val().length>=minlen) { // проверяем длину строки setTimeout(function(){ // ждем следующего нажатия var d2 = new Date(); time_search = d2.getTime(); if (time_search-time_keyup>=keyint) // проверяем интервал между нажатиями dosearch(); // если все в порядке, приступаем к поиску }, keyint); } else jQuery("#spresult").html(" "); // если строка короткая, убираем текст из DIVа с результатом }); БонусДобавим возможность создавать ссылки на любой текст на странице без использования . Достаточно создать ссылку на страницу и добавить #текст.
if (window.location.hash!="") // бонус { var t = window.location.hash.substr(1, 50); // вырезаем текст jQuery("#spterm").val(t).keyup(); // вставляем его в форму поиска jQuery("#spgo").click(); // переходим к первому фрагменту }

Весь код

jQuery(document).ready(function(){ var minlen = 3; // минимальная длина слова var paddingtop = 30; // отступ сверху при прокрутке var scrollspeed = 200; // время прокрутки var keyint = 1000; // интервал между нажатиями клавиш var term = ""; var n = 0; var time_keyup = 0; var time_search = 0; jQuery("body").delegate("#spgo", "click", function(){ jQuery("body,html").animate({scrollTop: jQuery("span.highlight:first").offset().top-paddingtop}, scrollspeed); // переход к первому фрагменту }); function dosearch() { term = jQuery("#spterm").val(); jQuery("span.highlight").each(function(){ //удаляем старую подсветку jQuery(this).after(jQuery(this).html()).remove(); }); var t = ""; jQuery("div#content").each(function(){ // в селекторе задаем область поиска jQuery(this).html(jQuery(this).html().replace(new RegExp(term, "ig"), "$&")); // выделяем найденные фрагменты n = jQuery("span.highlight").length; // количество найденных фрагментов console.log("n = "+n); if (n==0) jQuery("#spresult").html("Ничего не найдено"); else jQuery("#spresult").html("Результатов: "+n+". Перейти"); if (n>1) // если больше одного фрагмента, то добавляем переход между ними { var i = 0; jQuery("span.highlight").each(function(i){ jQuery(this).attr("n", i++); // нумеруем фрагменты, более простого способа искать следующий элемент не нашел }); jQuery("span.highlight").not(":last").attr({title: "Нажмите, чтобы перейти к следующему фрагменту"}).click(function(){ // всем фрагментам, кроме последнего, добавляем подсказку jQuery("body,html").animate({scrollTop: jQuery("span.highlight:gt("+jQuery(this).attr("n")+"):first").offset().top-paddingtop}, scrollspeed); // переход к следующему фрагменту }); jQuery("span.highlight:last").attr({title: "Нажмите, чтобы вернуться к форме поиска"}).click(function(){ jQuery("body,html").animate({scrollTop: jQuery("#spterm").offset().top-paddingtop}, scrollspeed); // переход к форме поиска }); } }); } jQuery("#spterm").keyup(function(){ var d1 = new Date(); time_keyup = d1.getTime(); if (jQuery("#spterm").val()!=term) // проверяем, изменилась ли строка if (jQuery("#spterm").val().length>=minlen) { // проверяем длину строки setTimeout(function(){ // ждем следующего нажатия var d2 = new Date(); time_search = d2.getTime(); if (time_search-time_keyup>=keyint) // проверяем интервал между нажатиями dosearch(); // если все в порядке, приступаем к поиску }, keyint); } else jQuery("#spresult").html(" "); // если строка короткая, убираем текст из DIVа с результатом }); if (window.location.hash!="") // бонус { var t = window.location.hash.substr(1, 50); // вырезаем текст jQuery("#spterm").val(t).keyup(); // вставляем его в форму поиска jQuery("#spgo").click(); // переходим к первому фрагменту } });

НедостаткиНа больших страницах (примерно 60 кб текста) скрипт зависает на пару минут. имя ключа параметра. Для поля поиска чаще всего применяется «q» или «text». значение ключа параметра. Чаще всего не задаётся. Пользователь может его изменить на свой текст, если не указаны атрибуты readonly и disabled . заблокировано изменение пользователем заблокированы доступ, изменение пользователем и передача данных текущего параметра поле не может быть пустым шаблон ввода как в регулярных выражениях JS , следование которому необходимо для отправки формы минимальное количество символов, необходимое для отправки формы максимальное количество символов, которое может набрать пользователь длина поля в символах подсказка-заглушка всплывающая подсказка при наведении курсора мышки автозаполнение. Современные браузеры показывают ранее введённые поисковые запросы на текущем домене. Можно его отключить или сделать более конкретизированным. список рекомендованных запросов проверяется орфография и грамматика фокус поля (то есть период между щелчком по элементу и щелчком вне элемента) получен при загрузке документа

Убрать в поле поиска крестик «Очистить», удаляющий ранее набранный текст input::-ms-clear { /* нестандартный псевдоэлемент IE */ display: none; } input::-webkit-search-cancel-button { /* нестандартный псевдоэлемент WebKit/Blink , но Esc по-прежнему будет удалять раннее введённый текст */ display: none; } Как работает форма поиска на сайте Самый простой HTML-код

Если набрать в поле «вопрос» и щелкнуть по кнопке «Найти», то адрес страницы изменится с « http://сайт/2011/06/forma-poiska-po-saitu..html?text=вопрос », как это происходит при нажатии на ссылку . При загрузке страницы, скрипт проверяет наличие заданных параметров в URL и при их обнаружении формирует и отображает результаты поиска по сайту.

Но в целях увеличения скорости загрузки документа, скрипт, обрабатывающий запрос, как правило, помещают только на одну страницу сайта, на которую будет сделан переход, если её адрес прописать в атрибуте action: « http://сайт/search/ ?text=вопрос ».

Для работы скрипта могут понадобиться дополнительные параметры, которые указываются в . Это поле не отображается.?searchid=808327 &text=вопрос ».

Результат работы формы открыть в новой вкладке с помощью атрибута target Где взять скрипт поиска по сайту

Можно воспользоваться

  • предложенным специальными сервисами Яндекса и Google ,
  • встроенным в используемую CMS (при наличии), например, на Blogger на « https://site.ru /search?q=вопрос », где « site.ru » заменить на свой адрес блога,
  • разработанным самостоятельно, например, на PHP.

Самый простой вариант - перенаправить запрос Google:>

Пару дней назад получил тестовое задание от компании на вакансию Front-end dev. Конечно же, задание состояло из нескольких пунктов. Но сейчас речь пойдет только об одном из них - организация поиска по странице. Т.е. банальный поиск по введенному в поле тексту (аналог Ctrl+F в браузере). Особенность задания была в том, что использование каких-либо JS фреймворков или библиотек запрещено. Все писать на родном native JavaScript .

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

Если кому интересно, код брал .

Скрипт сразу заработал. Я думал, что вопрос решен, но как оказалось, не в обиду автору скрипта, в нем был огромный недостаток. Скрипт вел поиск по всему содержимому тега... и, как вы уже наверное догадались, при поиске любого сочетания символов, которые напоминают тег или его атрибуты, ломалась вся страница HTML.

Почему скрипт работал некорректно? Все просто. Скрипт работает следующим образом. Сперва в переменную записываем все содержимое тега body , затем ищем совпадения с регулярным выражением (задает пользователь при вводе в текстовое поле) и затем заменяем все совпадения на следующий код:

...найденное совпадение...
А затем заменяем текущий тег body на новый полученный. Разметка обновляется, меняются стили и на экране подсвечиваются желтым все найденные результаты.

Вы уже наверняка поняли, в чем проблема, но я все же объясню подробней. Представьте, что в поле поиска ввели слово «div» . Как вы понимаете, внутри body есть множество других тегов, в том числе и div . И если мы всем к «div» применим стили, указанные выше, то это уже будет не блок, а непонятно что, так как конструкция ломается. В итоге после перезаписи разметки мы получим полностью сломанную веб-страницу. Выглядит это так.

Как видите, страница полностью ломается. Короче говоря, скрипт оказался нерабочим, и я решил написать свой с нуля, чему и посвящается эта статья.

Итак пишем скрипт с нуля Как все у меня выглядит.

Сейчас нас интересует форма с поиском. Обвел ее красной линией.

Давайте немного разберемся. Я это реализовал следующим образом (пока чистый HTML). Форма с тремя тегами.

Первый - для ввода текста;
Второй - для для отмены поиска (снять выделение);
Третий - для поиска (выделить найденные результаты).


Итак, у нас есть поле для ввода и 2 кнопки. JavaScript буду писать в файле js.js. Предпложим, что его вы уже создали и подключили.

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


Давайте немного поясню что тут и зачем нужно.

Полю с текстом даем id=«text-to-find» (по этому id будем обращатсья к элементу из js ).

Кнопке отмены даем такие атрибуты: type=«button» onclick=«javascript: FindOnPage("text-to-find",false); return false;»

- Тип: button
- При нажатии вызывается функция FindOnPage("text-to-find",false); и передает id поля с текстом, false

Кнопке поиска даем такие атрибуты: type=«button» onclick=«javascript: FindOnPage("text-to-find",true); return false;»

- Тип: submit (не кнопка потому, что тут можно юзать Enter после ввода в поле, а так можете и button использовать)
- При нажатии вызывается функция FindOnPage("text-to-find",true); и передает id поля с текстом, true

Вы наверняка заметили еще 1 атрибут: true/false . Его будем использовать для определения, на какую именно кнопку нажали (отменить поиск или начать поиск). Если жмем на отмену, то передаем false . Если жмем на поиск, то передаем true .

Окей, двигаемся дальше. Переходим к JavaScriptБудем считать, что вы уже создали и подключили js файл к DOM.

Прежде, чем начнем писать код, давайте отвлечемся и сперва обсудим, как все должно работать. Т.е. по сути пропишем план действий. Итак, нам надо, чтоб при вводе текста в поле шел поиск по странице, но нельзя затрагивать теги и атрибуты. Т.е. только текстовые объекты. Как этого достичь - уверен есть много способов. Но сейчас будем использовать регулярные выражения.

Итак, следующее регулярное выражение будет искать только текст след. вида: ">… текст...… текст...

Понравилась статья? Поделитесь ей