Your regex isn't working if there is a span
tag between the letters. Therefor you could replace reader[0].innerHTML
with reader[0].textContent
. This also solves the issue when the input is cleared.
By the way: if you use document.querySelector(...)
you can omit the [0]
in reader[0]
because it only selects the first element with that selector.
Working example: (simple for demonstration)
function refree() {
var reed = document.getElementById("search").value;
var reed1 = reed.toLowerCase();
var reader = document.querySelector(".deviceNameCardHead");
reader.innerHTML = reader.textContent.replace(new RegExp(reed1, 'gi'), `<span class="highlight">${reed}</span>`);
}
.highlight {
background: yellow;
}
<div id="devicesBtnData">
<div class="searchDevice">
<span class="searchDeviceBtn">Search Device</span>
<input id="search" type="search" placeholder="Try it" oninput="refree()">
</div>
<div class="deviceNameCard">
<h3 class="deviceNameCardHead">Lenova Yoga laptop Pro</h3>
</div>
</div>
To solve the issue that it changes the case of the yellow letters you need a bit more code.
First you have to store the string from .deviceNameCardHead
in a variable (for example reader_text
), convert it to lower case for a case insensitive search and store that also in a variable (for example lower_text
):
const reader_text = reader.textContent;
const lower_text = reader_text.toLowerCase();
Then you have to loop over all chars of reader_text
to find all occurrences of the search string and store all index values in an array (for example index_array
):
for(i = 0; i < lower_text.length; i++) {
const reed_index = lower_text.indexOf(reed1, i);
if(reed_index >= 0) {
index_array.push(reed_index);
}
}
Then you have to loop over the index_array
and store all occurrences from the original string in an array (for example highlight_array
) to obtain lower and upper case letters. To minimize an array to unique values you can use the Set()
constructor and spread syntax [...]
.
index_array = [...new Set(index_array)];
index_array.forEach(function(val) {
highlight_array.push(reader_text.substr(val, reed.length));
});
After that you have to loop over the highlight_array
and replace all upper and lower case occurrences separately with span.highlight
-wrapped values. To prevent the overwriting of reader_text
use a separate variable (for example highlight_text
):
let highlight_text = reader_text;
highlight_array = [...new Set(highlight_array)];
highlight_array.forEach(function(val) {
highlight_text = highlight_text.replaceAll(val, `<span class="highlight">${val}</span>`);
});
And finally you have to replace the string from .deviceNameCardHead
with highlight_text
:
reader.innerHTML = highlight_text;
Working example:
const reader = document.querySelector(".deviceNameCardHead");
const reader_text = reader.textContent;
const lower_text = reader_text.toLowerCase();
function refree() {
const reed = document.getElementById("search").value;
const reed1 = reed.toLowerCase();
let highlight_text = reader_text;
let highlight_array = [];
let index_array = [];
for(i = 0; i < lower_text.length; i++) {
const reed_index = lower_text.indexOf(reed1, i);
if(reed_index >= 0) {
index_array.push(reed_index);
}
}
index_array = [...new Set(index_array)];
index_array.forEach(function(val) {
highlight_array.push(reader_text.substr(val, reed.length));
});
highlight_array = [...new Set(highlight_array)];
highlight_array.forEach(function(val) {
highlight_text = highlight_text.replaceAll(val, `<span class="highlight">${val}</span>`);
});
reader.innerHTML = highlight_text;
}
.highlight {
background: yellow;
}
<div id="devicesBtnData">
<div class="searchDevice">
<span class="searchDeviceBtn">Search Device</span>
<input id="search" type="search" placeholder="Try it" oninput="refree()">
</div>
<div class="deviceNameCard">
<h3 class="deviceNameCardHead">Lenova Yoga press laptop Pro</h3>
</div>
</div>