搜索div时突出显示结果

我有这样的div设置:

 
hello world test 123
lorem ipsum test test1 testing
attack on titan
fullmetal alchemist

我允许用户搜索div:

 jQuery(document).ready(function() { jQuery("#search").on("keyup click input", function () { var val = jQuery(this).val(); if (val.length) { jQuery(".entry").hide().filter(function () { return jQuery('.title, .description',this).text().toLowerCase().indexOf(val.toLowerCase()) != -1; }).show(); } else { jQuery(".entry").show(); } }); }); 

效果很好,试试jsFiddle 。

我的问题是,如何突出搜索条件? 例如,如果用户搜索test ,我想将文本test包装到标记中。

编辑:请注意,我知道如何搜索/替换文本,但我似乎无法使用我的搜索function正常工作。

优化的解决方案

在评论中讨论了所有问题并尝试优化解决方案以使其不会缺少最终的错误之后,我重构了代码并对其进行了优化:

 $(document).ready(function() { $("#search").on("keyup click input", function() { var val = jQuery(this).val(); var regExp = new RegExp(val, 'ig'); var reg = new RegExp('(.+)<\/span>', 'ig'); if (val.length) { $(".entry").hide().filter(function() { var found = $('.title, .description', this).text().toLowerCase().indexOf(val.toLowerCase()) != -1; if (val.length > 3) { $('.title, .description', this).each(function(k, v) { if ($(v).text().match(regExp)) { $(v).html($(v).text().replace(regExp, '$&')); } else { $(v).html($(v).text().replace(reg, '$&')); } }); } else { $('.title, .description', this).each(function(k, v) { $(v).html($(v).text().replace(reg, '$&')); }); } return found; }).show(); } else { $('.title, .description').each(function(k, v) { $(v).html($(v).text().replace(reg, '$&')); }); $(".entry").show(); } }); }); 
 .highlight { background-color: blue } 
   
hello world test 123
lorem ipsum test test1 testing
attack on titan
fullmetal alchemist

尝试使用contains(text)而不是filter()最初隐藏All div。然后只显示包含div的文本。并使用new RegExp()将span元素应用于子元素中的匹配字母

对于正则表达式中忽略区分大小写的匹配ig ,还添加了对contains大小写不敏感的代码

更新了针对儿童的.title, .description修复

 jQuery(document).ready(function() { jQuery("#search").on("input", function() { var val = jQuery(this).val() jQuery(".entry").hide() jQuery(".entry:contains(" + val + ")").show() jQuery(".entry").each(function() { if ($(this).find(".title, .description:contains(" + val + ")")) { $(this).find(".title, .description:contains(" + val + ")").html(function() { return $(this).text().replace(new RegExp('('+val+')', 'ig'), '$1') }) } }) }); }) jQuery.expr[':'].contains = function(a, i, m) { return jQuery(a).text().toUpperCase() .indexOf(m[3].toUpperCase()) >= 0; }; 
 .entry { background: #fff; margin-bottom: 10px; width: 300px; } span { color: red; } 
   
hello world test 123
lorem ipsum test test1 testing
Attack on titan
fullmetal alchemist
For nested element on titan
fullmetal alchemist nested

试试这个:

 document.getElementById('search').onkeyup = userInput; document.getElementById('search').onclick = userInput; document.getElementById('search').oninput = userInput; var allEntries = document.querySelectorAll('.entry'); function userInput () { var val = this.value; for (var i = 0; i < allEntries.length; i++) { var entryElement = allEntries[i]; var title = entryElement.querySelector('.title'); var description = entryElement.querySelector('.description'); var noHtmlSearchStr = ''; if (title) noHtmlSearchStr += title.innerText; if (description) noHtmlSearchStr += description.innerText; if (noHtmlSearchStr.length > 0) { if (noHtmlSearchStr.toLowerCase().indexOf(val.toLowerCase()) != -1) { // Remove existing  tags. var regexp1 = new RegExp('(|<\/b>)', 'gi'); if (title) title.innerHTML = title.innerHTML.replace(regexp1, ''); if (description) description.innerHTML = description.innerHTML.replace(regexp1, ''); if (val.length > 3) { var regexp2 = new RegExp('(' + val + ')(?!>)', 'gi'); if (title) title.innerHTML = title.innerHTML.replace(regexp2, '$1'); if (description) description.innerHTML = description.innerHTML.replace(regexp2, '$1'); } entryElement.style.display = 'block'; } else { entryElement.style.display = 'none'; } } } } 
 .entry { background: #fff; margin-bottom: 10px; width: 300px; } 
  
hello world test 123
div lorem ipsum test
test1
testing span
attack on titan
fullmetal alchemist
attack on titan
Let's not go to Camelot, 'tis a silly place