Скрипт пошуку на сторінці HTML. JavaScript пошук по сторінці

Багато відвідувачів сайтів не знають про пошук по сторінці за натисканням 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"). jQuery(this).html().replace(new RegExp(term, "ig"), "$&")); // виділяємо знайдені фрагменти n = jQuery("span.highlight").length; фрагментів console.log("n = "+n); if (n==0) 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("#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); 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 time_keyup = 0; var time_search = 0; html").animate((scrollTop: jQuery("span.highlight:first").offset().top-paddingtop), scrollspeed); // перехід до першого фрагменту )); function dosearch() ( term = jQuery( "#spterm").val(); jQuery ("span.highlight"). ;) var t = ""; jQuery("div#content"). new RegExp(term, "ig"), "$&")); // виділяємо знайдені фрагменти n = jQuery("span.highlight"). );if (n==0) jQuery("#spresult").html("Нічого не знайдено"); ="") // бонус (var t = window.location.hash.substr(1, 50); // вирізаємо текст jQuery("#spterm").val(t).keyup(); // вставляємо його в форму пошуку jQuery("#spgo").click(); // Переходимо до першого фрагменту)));

Весь код

НедолікиНа великих сторінках (приблизно 60 кб тексту) скрипт зависає на кілька хвилин.

Оновлена ​​відповідь:

Спочатку я не зрозумів, що ви хочете викликати веб-сторінку, яку ви не контролюєте, а потім використовувати JavaScript у своєму браузері для взаємодії з нею.

    Інформація в початковій відповіді нижче актуальна, але виникає питання: як змусити код працювати в правильному контексті? І відповідь: Є як мінімум два способи:

    У будь-якому пристойному браузері в наші дні є вбудовані засоби налагодження. Подивіться на меню для них, але у багатьох браузерах вони доступні за допомогою клавіші F12 або Ctrl + Shift + I. У цих інструментах ви знайдете "консоль", де ви можете ввести JavaScript і запустити його в контексті сторінки, на яку ви дивитесь.

    Це чудово підходить для виконання дій в інтерактивному режимі, але це трохи боляче повторювати його щоразу. Ви також можете помістити код у локальний файл (наприклад /home/tjc/foo.js), а потім, коли ви перейдете на сторінку, використовуйте консоль, щоб додати цей script на сторінку (що приведе до її виконання в контексті сторінка), наприклад:

    Як тільки ваш script зробить те, що ви хочете, ви можете перетворити його на bookmarklet . Це закладка браузера з використанням схеми JavaScript: , а не звичайної http: і т.д. Докладніше див. Посилання. Вам знадобиться інструмент, який візьме ваш код JavaScript і зробить вам необхідне URL-кодування, наприклад Bookmarklet Crunchinator або аналогічний.

Оригінальна відповідь:

Так що він знайде текст або отримає елемент з id/class...

Це три дуже різні питання:

    Щоб знайти текст на сторінці, у вас є кілька варіантів:

    • Якщо ви хочете тільки знайти текст, але не дбайте про те, який елемент містить його, ви можете просто переглянути innerHTML on document.body . innerHTML - рядок; при доступі до нього браузер створює HTML рядок для всіх елементів DOM в елементі, на який ви його викликаєте (і його нащадках). Зверніть увагу, що це не вихідний контент із сервера; це створюється "на льоту" під час доступу до елемента. Для багатьох випадків використання отримання цього рядка, а потім його перегляд може бути корисним. Зверніть увагу, що текст, який ви переглядаєте, є розміткою, наприклад, якщо ви шукали слово "таблиця", ви можете знайти його у реченні ("Ми сіли за стіл") або в розмітці (

      ...).

      Тут наведено приклад підрахунку слова I'm на сторінці за допомогою innerHTML: жива копія

      (function() ( var pageText = document.body.innerHTML; display("Count of "I\"m" на сторінці: " + pageText.match(/I"m/g).length); function display(msg) ) ( var p = document.createElement("p"); p.innerHTML = String(msg); document.body.appendChild(p); ) ))();

      Якщо вам потрібно з'ясувати, в якому елементі він знаходиться, вам потрібно буде написати рекурсивну функцію, що проходить через вузли сторінки, і для Text , переглядає текст усередині. Ось базовий приклад(функція – це функція walk): Жива копія | - див. примітку про приклади наприкінці.

      (function() ( var matches = , index; walk(matches, document.body, ""); function walk(matches, node, path) ( var child; switch (node.nodeType) ( case 1: // Element for (child = node.firstChild; child; child = child.nextSibling) ( walk(matches, child, path + "/" + node.tagName); ) break; case 3: // Text if (node.nodeValue.indexOf( "I"m") !== -1) ( matches.push("Found it at " + path); ) break; ) ) display("Matches found (" + matches.length + "):"); (index = 0; index< matches.length; ++index) { display(matches); } function display(msg) { var p = document.createElement("p"); p.innerHTML = String(msg); document.body.appendChild(p); } })();

      Щоб знайти елемент на сторінці id, використовуйте

      Здрастуйте шановні читачі блогу LifeExample, всі ми користуємося електронним пошуком по сторінці в наших веб-браузерах за допомогою гарячих клавіш CTRL+F або F3. І здається вже від таких привілеїв нам нікуди не подітися, оскільки самостійно читати весь вміст сторінки, часто буває ніколи. Біда в тому, що далеко не всі користувачі-початківці знають про таких прихованих можливостяхбудь-якого браузера, але їм можна допомогти, прикрутивши саморобний JavaScript пошук по сторінці, у тих проектах, де без нього зовсім ніяк.

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

      Шукати на сторінці потрібну інформаціюбуде зручніше, якщо для цього реалізувати відповідний інтерфейс:

      У полі потрібно ввести слово для пошуку та натиснути кнопку «Шукати», тут все інтуїтивно зрозуміло. Давайте перейдемо до реалізації самого механізму пошуку по сторінці та подивимося, які можуть бути нюанси під час його реалізації.

      Як шукати слово на сторінці?
      Потрібно перевірити коректність введення даних, у нашому випадку ми лише обріжемо пробільні символи з обох боків фрази для пошуку, а також просто перевіримо на форму на наявність у ній пошукового запиту.
      Так як дані статичні, і зберігаються тільки в DOM'e сторінки, пошук по ній буде проводитися саме за вмістом DOM (Document Object Model).
      Важливим є, щоб показати користувачеві всі результати, які знайшов наш JavaScript пошук. Тобто. підсвічувати фон під знайденими частинами сторінки.
      Так як цей міні модуль пошуку по сторінці має сенс підключати тільки до великих сторінок, які мають прокручування, то за наявності знайденої фрази десь поза зоною видимості непогано буде прокрутити scroll до знайденого елемента.
      Повторне використання пошуку також є важливим моментом у роботі даного скрипта. Т.к. підсвічування знайдених частин є результатом зміни вмісту DOM об'єкта, кожен наступний цикл пошуку повинен затирати результати попереднього і повертати вміст сторінки до вихідного вигляду, для подальших змін нової ітерації.
      Ну так коротко начебто б і все. Незважаючи на об'ємність виділених пунктів, реалізація їх не займає багато часу та місця у коді, ось готовий скрипт для механізму JavaScript пошуку по сторінці:


      var lastResFind=""; // Останній вдалий результат
      var copy_page=""; // копія сторінки в їхньому вигляді
      функція TrimStr(s) (
      s = s.replace(/^s+/g, "");
      return s.replace(/s+$/g, "");
      }
      function FindOnPage(inputId) (// шукає текст на сторінці, в параметр передається ID поля для введення
      var obj = window.document.getElementById(inputId);
      var textToFind;

      If (obj) (
      textToFind = TrimStr(obj.value);//обрізаємо прогалини
      ) else (
      alert("Введена фраза не знайдена");
      return;
      }
      if (textToFind == "") (
      alert("Ви нічого не ввели");
      return;
      }

      If(document.body.innerHTML.indexOf(textToFind)=="-1")
      alert("Нічого не знайдено, перевірте правильність введення!");

      If(copy_page.length>0)
      document.body.innerHTML=copy_page;
      else copy_page=document.body.innerHTML;

      Document.body.innerHTML = document.body.innerHTML.replace(eval("/name="+lastResFind+"/gi")," ");// стираємо попередні якорі для скрола
      document.body.innerHTML = document.body.innerHTML.replace(eval("/"+textToFind+"/gi")," "+textToFind+""); // Замінюємо знайдений текст посиланнями з якорем;
      lastResFind=textToFind; // Зберігаємо фразу для пошуку, щоб надалі по ній стерти всі посилання
      window.location = "#"+textToFind; // Переміщаємо скрол до останнього знайденого збігу
      }


      JavaScript пошук по сторінці



      Введіть слово або фразу для пошуку.


      ТоварВагаВартість



      Монітор 19 дюймів1 кг1900 руб.
      монітор 18 дюймів2 кг1800 руб.
      Монітор 20 дюймів2 кг1900 руб.


      Спробуйте протестувати пошуковими запитами«19», «2 кг» та іншими. Також раджу перевірити автомобільний скролінг, для цього додавайте текст до тих пір, поки праворуч не з'явиться смуга прокручування.

      Ось так виглядає приклад використання скрипту:

      Що стосується коментарів за кодом, напевно, вони тут зайві, тому що є всередині скрипта. Єдине, з чим можуть виникнути труднощі у новачків, це розуміння сенсу регулярних виразів при обрізанні прогалин. Всім кому знадобиться допомога, раджу почитати відповідну статтю про регулярні висловлювання.

      Реалізований у цій статті, за допомогою мови JavaScript, пошук по сторінці валідний у всіх браузерах, включаючи Internet Explorer.

      Кілька днів тому отримав тестове завдання від компанії на вакансію Front-end dev. Звісно, ​​завдання складалося з кількох пунктів. Але зараз йтиметься лише про один з них - організація пошуку по сторінці. Тобто. банальний пошук за введеним у полі текстом (аналог Ctrl+F у браузері). Особливість завдання в тому, що використання будь-яких JS фреймворків або бібліотек заборонено. Все писати на рідному JavaScript JavaScript .

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

      Якщо комусь цікаво, код брав .

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

      Чому скрипт працював некоректно? Все просто. Скрипт працює в такий спосіб. Спочатку в змінну записуємо весь вміст тега body, потім шукаємо збіги з регулярним виразом (задає користувач при введенні в текстове поле) і потім замінюємо всі збіги на наступний код:

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

      Ви вже напевно зрозуміли, в чому проблема, але я все ж таки поясню докладніше. Уявіть, що поле пошуку ввели слово «div» . Як ви розумієте, всередині body є безліч інших тегів, у тому числі div. І якщо ми всім до «div» застосуємо стилі, вказані вище, це вже буде не блок, а незрозуміло що, оскільки конструкція ламається. У результаті після перезапису розмітки ми отримаємо повністю зламану веб-сторінку. Виглядає так.

      Як бачите, сторінка повністю ламається. Коротше кажучи, скрипт виявився неробочим, і я вирішив написати свій із нуля, чому і присвячується ця стаття.

      Тож пишемо скрипт з нуля Як все у мене виглядає.

      Нині нас цікавить форма із пошуком. Обвів її червоною лінією.

      Давайте трохи розберемося. Я це реалізував так (поки чистий HTML). Форми з трьома тегами.

      Перший – для введення тексту;
      Другий - для скасування пошуку (зняти виділення);
      Третій – для пошуку (виділити знайдені результати).


      Отже, у нас є поле для введення та дві кнопки. 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.

      Перш ніж почнемо писати код, давайте відвернемося і спершу обговоримо, як усе має працювати. Тобто. по суті пропишемо план дій. Отже, нам треба, щоб при введенні тексту в полі йшов пошук по сторінці, але не можна зачіпати теги та атрибути. Тобто. лише текстові об'єкти. Як цього досягти – впевнений є багато способів. Але зараз використовуватимемо регулярні висловлювання.

      Отже, наступне регулярний виразшукатиме лише текст слід. виду: ">... текст...