搜索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