I have written a simple javascript searcher for a page and am running into some problems with mismatches/false matches as well as potentially poor css class matching.
If I click on the first example 'code' (which filters down to one element) then on the 'styling' link, the 'code' high-lighting remains. Needless to say this is undesirable.
I think that the problem will happen in the filtering part of the code but it all looks quite good to me. Especially since I am grabbing the text of the title rather than the HTML of it and then adding in a new span.
function filter(searchTerm) {
var searchPattern = new RegExp('(' + searchTerm + ')', 'ig'); // The brackets add a capture group
entries.fadeOut(150, function () {
noResults.hide();
$('header', this).each(function () {
$(this).parent().hide();
// Clear results of previous search
$('li', this).removeClass('searchMatchTag');
// Check the title
$('h1', this).each(function () {
var textToCheck = $('a', this).text();
if (textToCheck.match(searchPattern)) {
textToCheck = textToCheck.replace(searchPattern, '<span class="searchMatchTitle">$1</span>'); //capture group ($1) used so that the replacement matches the case and you don't get weird capitolisations
$('a', this).html(textToCheck);
$(this).closest('.workshopentry').show();
}
});
// Check the tags
$('li', this).each(function () {
if ($(this).text().match(searchPattern)) {
$(this).addClass('searchMatchTag');
$(this).closest('.workshopentry').show();
}
});
});
if ($('.workshopentry[style*="block"]').length === 0) {
noResults.show();
}
entries.fadeIn(150);
});
}
Some other combinations make this happen but some other s do not, making it very hard for me to track down the cause for this particular problem.
You can't trust user input with regular expressions without doing proper quoting. Consider using a quote function like this:
var rePattern = searchTerm.replace(/[.?*+^$\[\]\\(){}|]/g, "\\$&"),
searchPattern = new RegExp('(' + rePattern + ')', 'ig'); // The brackets add a capture group
Edit
As mentioned in the comments, it's not clear why capturing parentheses are being used to perform the search; you can use $&
as the replacement pattern. Of course, I would understand if you simplified the regular expression for this post :)
Generating searchPattern without escaping searchTerm could be a problem. A searchTerm of .*
would match anything.
How about using var match = textToCheck.indexOf(searchTerm) >= 0
instead?
This will return the index of the first instance of the substring searchTerm
in the text, otherwise, it will return -1.
Turn out I was missing a check to remove the previous matching tags.
var textToCheck = $('a', this).text();
if (textToCheck.match(searchPattern)) {
//capture group ($1) used so that the replacement matches the case and you don't get weird capitolisations
textToCheck = textToCheck.replace(searchPattern, '<span class="searchMatchTitle">$1</span>');
$('a', this).html(textToCheck);
$(this).closest('.workshopentry').show();
} else {
$('a', this).html(textToCheck);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.