На странице: поле поиска и текст на странице. Задача - найти все совпадения, которые встречаються на странице, после введения текста в поисковую строку и нажатия на кнопку Поиск
<input type = "submit" value = "Поиск">
<p class = "h2">Заголовок первый</p>
<p>Текст первого заголовка</p>
<p>Тут еще какой то текст</p>
<p class = "h2">Заголовок второй</p>
<p>Текст второго заголовка</p>
<p class = "h2">Заголовок для первого абзаца</p>
<p>Заголовок первый</p>
Скрипт для поиска:
let str = document.querySelector('.search').value;
//let str = 'Заголовок второй на https://javascript.info';
let regexp = /второй/ig;
let result;
while (result = regexp.exec(str)) {
alert( `Найдено ${result[0]} на позиции ${result.index}` );
}
должен работать таким образом что после того как пользователь ввел слово, которое встречается в этом тексте - ему алертом выдало это слово и количество слов которые есть на этой странице.
Вопроса 2 по этому скрипту:
Как реализовать точное совпадение введенного слова из инпута (вместо этого let regexp = /второй/ig; ), почему там regexp? и есть ли другой какой то метод для поиска чтобы выбирать точные совпадения?
Сделать поиск не по всем словам на странице, которые встречаються, а только по тем, которые с class = “h2”
Тут трохи не зрозуміло
Все ж таки - “алертом выдало это слово и количество слов которые есть на этой странице” ?
Або як у коді
На кожне співпадіння має видаватись алерт?
Або
Чи один алерт з першим співпадінням та загальна кількість співпадінь?
Може бути щось таке;
var searchString = 'typedValue';
var elems = document.querySelectorAll('h2');
var matches = 0;
elems.forEach((elem, index) => {
if (elem.innerText.toLowerCase().indexOf(searchString.toLowerCase()) >= 0) {
matches++;
}
});
alert( `Слово ${searchString} найдено ${matches} раз`);
спасибо за подсказку, но если заменить regexp на indexOf - то выдает ошибку
indexOfFirst.exec is not a function
Пример кода тут https://jsfiddle.net/n3ywjhxt/2/
Или ошибка - не в замене методов, а в чем то другом?
нет, не на каждое. Alert здесь нужен для JSFiddle потому что там console.log не отображаеться, поэтому там алерт нагляднее чтобы не копировать код и не открывать у себя…
Цель задачи - найти совпадения (все которые встречаються в тексте на странице) после того как пользователь ввел слово и нажал на кнопку Поиск. Вместо заданного примера в переменной
var searchString = ‘typedValue’;
задать значение в эту переменную слово которое будет вводить пользователь:
var searchString = document.querySelector(‘.search’).value;
Вот на этом этапе не понимаю как сделать. Результатом должно быть одно или несколько слов (в зависимости от того что ввел пользователь, если ввел слово “Заголовок” - то в консоль должно три слова Заголовок выпасть (потому что 3 раза встречаеться в h2), если ввел “второй” - то только одно).
Результатом работы скрипта в дальнейшем должна быть манипуляция с DOM (если слово в тексте найдено - значит его отметить, например жирным шрифтом). Это сейчас пример с алертом - чтобы упростить задачу (разбить на подзадачи).
щось таке, дякую…
Додала до цього скрипта роботу з ДОМ (додавання кольору до всіх знайдених співпадінь, але чомусь застосовується колір тільки до першого знайденого співпадіння (хоча співпадінь знаходить 3 штуки) https://jsfiddle.net/5xnqfcvw/
Там потрібно також циклом присвоювати? (для змінної де присвоюється колір - перебирати елементи циклом), але хоча і там і там цикл…навіщо їх аж два… Чи причина не в цьому?
Да, присваивать тоже придется в цикле, но не обязательно создавать еще один. У тебя ведь уже есть цикл, в котором ты проверяешь строки на совпадение:
if (elem.innerText.toLowerCase().indexOf(searchString.toLowerCase()) >= 0) {
matches++;
}
Также обрати внимание, что у тебя вот тут происходит:
var matches = 0;
var match = document.querySelector('p');
...
matches = match;
match.style.color = "red";
matches - это счетчик совпадений match - это первый элемент p на странице (при этом он никогда не меняется). Ты присваиваешь одно другому и потом назначаешь ему цвет, поэтому всегда будет подсвечиваться только первый p.
Попробуй написать сама, если не получится, посмотри cюда
А также:
Как вернуть цвет строки обратно, если мы введем другое значение для поиска?
Что если в одной строке искомое значение встречается несколько раз (текст текст)?
почему создала еще одну переменную для цвета текста, - потому что нельзя применить его для переменной matches
Если записать
var matches = document.querySelector(‘p’); – тогда не присваивает цвет вообще нигде
После того как значение найдено в строке поиска (подсвечено красным), если стереть из строки искомое слово и ввести заново другое - скрипт срабатывает так что первое совпадение становится черным как и было раньше, а новое - выделяется красным. Там уже ничего дописывать в работу этого скрипта не надо. Или я не понимаю вопрос.
тот есть если переменной изначально задавать числовое значение, а потом повторно навешать на нее стили - то она воспринимаеться как число? (а числу стиль применить нельзя). То есть одной переменной нельзя присваивать 2 разных значения - числовое и нечисловое (ДОМ-узел)?
Одной переменной можно присваивать разные значения, но это в любом случае будет либо DOM-элемент, либо число. DOM-элементу можно навешивать стиль. Числу - нельзя.
вот тут elem.innerText.toLowerCase().indexOf(searchString.toLowerCase()) >= 0
ты же не проверяешь, сколько раз встречается совпадение. Просто проверяешь, что оно есть.
но мы же не знаем сколько раз будет встречаться одно и то же слово в одном предложении. По этому не можем написать условие
elem.innerText.toLowerCase().indexOf(searchString.toLowerCase()) > 1
Или там надо как то проверять - что если в innerText который относиться к селектору .h2 - и подставлять это условие elem.innerText.toLowerCase().indexOf(searchString.toLowerCase()) > 1
?
Или вообще не то?
Да, тебе нужно проверять содержимое innerText, но indexOf в том виде, в котором ты его используешь, не подходит, потому что он возвращает только первое совпадение. Грубо говоря, показывает тебе, есть ли в строке то, что ты ищешь, или нет.
Добавила это в коде https://jsfiddle.net/c3mu69yh/1/
В итоге - на этой строке
elem.indexOf(searchString, matches + 1);
выдает ошибку что
elem.indexOf is not a function
Что здесь имеется ввиду? Оно же elem.indexOf не есть функцией, а присваивание какого то метода. Почему в консоли определяется как функция?