从输入字段中搜索一个术语并在没有值时将其重置,超过两个字符的单词有问题(包括延迟功能)
Search for a term from an input field and reset it if the is no value, problem with words with more than two character (delay function included)
我建立了一个输入字段来在我的问答页面上搜索一些关键字。我构建的系统不止于此,因为它还打开和关闭带有答案的 div(来自输入和其他不同的 HTML 标签),但我专注于输入字段.
首先是我的代码,然后是我的问题:
const searchfaq = $('#text-search');
const searchtarget = $(".nodisplay");
const htmltochange = searchtarget.map(function() {
return $(this).children().find('p').html();
}).get();
function delay(callback, ms) {
var timer = 0;
return function() {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
callback.apply(context, args);
}, ms || 0);
};
}
searchfaq.keyup(delay(function(e) {
let val = $(this).val().toLowerCase();
searchtarget.hide();
searchtarget.prev().children('.minus').removeClass('rotate');
searchtarget.each(function(index) {
let text = $(this).html().toLowerCase();
let paragraph = $(this).children().find('p');
let otherparagraph = searchtarget.children().find('p');
if (text.indexOf(val) != -1) {
$(this).show();
$(this).prev().children('.minus').addClass('rotate');
var re = new RegExp(val, 'gi');
paragraph[0].innerHTML = htmltochange[index].replace(re, `<mark>$&</mark>`);
}
if (val.length === 0) {
paragraph[0].innerHTML = htmltochange[index];
$(this).hide();
searchtarget.prev().children('.minus').removeClass('rotate');
}
});
}, 500));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="lazyblock-faq-search">
<h1>Frequently Asked Questions</h1>
<form _lpchecked="1">
<input id="text-search" type="text" aria-label="search-for-answers" placeholder="Search for answers">
</form>
</div>
<div class="lazyblock-faq">
<div class="row">
<aside class="col-md-3">
<ul class="sticky-top">
<li class="active">
<a href="#chapter-1">Chapter 1</a>
</li>
<li class="">
<a href="#chapter-2">Chapter 2</a>
</li>
</ul>
</aside>
<div class="question-and-answer col-md-9">
<h2 id="chapter-1">Chapter 1</h2>
<div class="single-faq">
<h3>This is a question</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-Z2cLmzB">
<div class="row">
<div class="col-md-12">
<p>This is the answer</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a question 2</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZhBtAi">
<div class="row">
<div class="col-md-12">
<p>This is the answer 2</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>Question 3 ?</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZPm3XU">
<div class="row">
<div class="col-md-12">
<p>This is the answer 3</p>
</div>
</div>
</div>
</div>
</div>
<h2 id="chapter-2">Chapter 2</h2>
<div class="single-faq">
<h3>This is a question 4</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-1sQXGa">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 4</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a question 5</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZioRKT">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 5</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a quesition 6 and it has a weird layout</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-2fxKyB">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 6</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
代码以这种方式工作。用户将在输入字段中插入一个字符串,并且将在 div 中使用 class 'no-display' 精确地在其 HTML 中搜索单词(我必须指定它因为,在原始代码中,特定的 div 内部将包含 HTML,而不仅仅是文本)。
该代码有两个注意事项:
我不得不添加一个延迟函数,因为出于某种原因,如果没有它,它只能用于前两个字符,然后它将无法找到任何其他单词。
连接到问题 1,如果您尝试在输入字段中插入另一个值(字符串),它不会在某种意义上正确重置,它将无法找到任何不同的词。让我们举个例子:我将插入单词 test,然后如果我试图从中删除一个单词,(string tes) 它仍然会将其包装在 mark 标记中的单词。但是,如果我在末尾再次添加字符 T,它将找不到带有单词 test 的 div,代码将失败。
此外,在重置为初始值(val.length === 0)之前,我会看到每个单词都包含在标签中。
这是一个错误还是我遗漏了什么?
对于 1) 和 2)(延迟无关)你的问题是你的比较 let text=
使用 current html,而不是原来的 htmltochange
.
经过搜索,当前 html 现在有 <mark>
个标签。
因此,如果您搜索 " is "
,您的 html 从 This is the
更改为 This<mark> is </mark>the
- 当您搜索 " is the"
时,它不匹配在 <mark> is </mark>the
.
而不是.html()
,使用.text()
获取没有标记的文本,然后它工作正常(至少那部分,没有检查其余部分,例如也改变原来的htmltochange
).这也意味着你没有得到 false-positives,例如在你的原始代码中搜索“div”,“div”出现在每个答案的 html 中,所以他们都显示出来了。
searchtarget.each(function(index) {
let text = $(this).text().toLowerCase();
- resetting to the initial value (val.length === 0) will see every word wrapped in a tag
这是由于 if
的顺序 - 您的第一个 if
查找空白并突出显示它们,第二个然后隐藏它们。
颠倒顺序,使其首先检查 length===0
,然后仅在不为 0 时才进行搜索。
已更新fiddle:
const searchfaq = $('#text-search');
const searchtarget = $(".nodisplay");
const htmltochange = searchtarget.map(function() {
return $(this).children().find('p').text();
}).get();
function delay(callback, ms) {
var timer = 0;
return function() {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
callback.apply(context, args);
}, ms || 0);
};
}
searchfaq.keyup(delay(function(e) {
let val = $(this).val().toLowerCase();
//console.log(val)
searchtarget.hide();
searchtarget.prev().children('.minus').removeClass('rotate');
searchtarget.each(function(index) {
let text = $(this).text().toLowerCase();
let paragraph = $(this).children().find('p');
let otherparagraph = searchtarget.children().find('p');
if (val.length === 0) {
paragraph[0].innerHTML = htmltochange[index];
$(this).hide();
searchtarget.prev().children('.minus').removeClass('rotate');
}
else if (text.indexOf(val) != -1) {
$(this).show();
$(this).prev().children('.minus').addClass('rotate');
var re = new RegExp(val, 'gi');
paragraph[0].innerHTML = htmltochange[index].replace(re, `<mark>$&</mark>`);
}
});
}, 500));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="lazyblock-faq-search">
<h1>Frequently Asked Questions</h1>
<form _lpchecked="1">
<input id="text-search" type="text" aria-label="search-for-answers" placeholder="Search for answers">
</form>
</div>
<div class="lazyblock-faq">
<div class="row">
<aside class="col-md-3">
<ul class="sticky-top">
<li class="active">
<a href="#chapter-1">Chapter 1</a>
</li>
<li class="">
<a href="#chapter-2">Chapter 2</a>
</li>
</ul>
</aside>
<div class="question-and-answer col-md-9">
<h2 id="chapter-1">Chapter 1</h2>
<div class="single-faq">
<h3>This is a question</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-Z2cLmzB">
<div class="row">
<div class="col-md-12">
<p>This is the answer</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a question 2</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZhBtAi">
<div class="row">
<div class="col-md-12">
<p>This is the answer 2</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>Question 3 ?</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZPm3XU">
<div class="row">
<div class="col-md-12">
<p>This is the answer 3</p>
</div>
</div>
</div>
</div>
</div>
<h2 id="chapter-2">Chapter 2</h2>
<div class="single-faq">
<h3>This is a question 4</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-1sQXGa">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 4</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a question 5</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZioRKT">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 5</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a quesition 6 and it has a weird layout</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-2fxKyB">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 6</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
我建立了一个输入字段来在我的问答页面上搜索一些关键字。我构建的系统不止于此,因为它还打开和关闭带有答案的 div(来自输入和其他不同的 HTML 标签),但我专注于输入字段.
首先是我的代码,然后是我的问题:
const searchfaq = $('#text-search');
const searchtarget = $(".nodisplay");
const htmltochange = searchtarget.map(function() {
return $(this).children().find('p').html();
}).get();
function delay(callback, ms) {
var timer = 0;
return function() {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
callback.apply(context, args);
}, ms || 0);
};
}
searchfaq.keyup(delay(function(e) {
let val = $(this).val().toLowerCase();
searchtarget.hide();
searchtarget.prev().children('.minus').removeClass('rotate');
searchtarget.each(function(index) {
let text = $(this).html().toLowerCase();
let paragraph = $(this).children().find('p');
let otherparagraph = searchtarget.children().find('p');
if (text.indexOf(val) != -1) {
$(this).show();
$(this).prev().children('.minus').addClass('rotate');
var re = new RegExp(val, 'gi');
paragraph[0].innerHTML = htmltochange[index].replace(re, `<mark>$&</mark>`);
}
if (val.length === 0) {
paragraph[0].innerHTML = htmltochange[index];
$(this).hide();
searchtarget.prev().children('.minus').removeClass('rotate');
}
});
}, 500));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="lazyblock-faq-search">
<h1>Frequently Asked Questions</h1>
<form _lpchecked="1">
<input id="text-search" type="text" aria-label="search-for-answers" placeholder="Search for answers">
</form>
</div>
<div class="lazyblock-faq">
<div class="row">
<aside class="col-md-3">
<ul class="sticky-top">
<li class="active">
<a href="#chapter-1">Chapter 1</a>
</li>
<li class="">
<a href="#chapter-2">Chapter 2</a>
</li>
</ul>
</aside>
<div class="question-and-answer col-md-9">
<h2 id="chapter-1">Chapter 1</h2>
<div class="single-faq">
<h3>This is a question</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-Z2cLmzB">
<div class="row">
<div class="col-md-12">
<p>This is the answer</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a question 2</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZhBtAi">
<div class="row">
<div class="col-md-12">
<p>This is the answer 2</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>Question 3 ?</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZPm3XU">
<div class="row">
<div class="col-md-12">
<p>This is the answer 3</p>
</div>
</div>
</div>
</div>
</div>
<h2 id="chapter-2">Chapter 2</h2>
<div class="single-faq">
<h3>This is a question 4</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-1sQXGa">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 4</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a question 5</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZioRKT">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 5</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a quesition 6 and it has a weird layout</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-2fxKyB">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 6</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
代码以这种方式工作。用户将在输入字段中插入一个字符串,并且将在 div 中使用 class 'no-display' 精确地在其 HTML 中搜索单词(我必须指定它因为,在原始代码中,特定的 div 内部将包含 HTML,而不仅仅是文本)。
该代码有两个注意事项:
我不得不添加一个延迟函数,因为出于某种原因,如果没有它,它只能用于前两个字符,然后它将无法找到任何其他单词。
连接到问题 1,如果您尝试在输入字段中插入另一个值(字符串),它不会在某种意义上正确重置,它将无法找到任何不同的词。让我们举个例子:我将插入单词 test,然后如果我试图从中删除一个单词,(string tes) 它仍然会将其包装在 mark 标记中的单词。但是,如果我在末尾再次添加字符 T,它将找不到带有单词 test 的 div,代码将失败。
此外,在重置为初始值(val.length === 0)之前,我会看到每个单词都包含在标签中。
这是一个错误还是我遗漏了什么?
对于 1) 和 2)(延迟无关)你的问题是你的比较 let text=
使用 current html,而不是原来的 htmltochange
.
经过搜索,当前 html 现在有 <mark>
个标签。
因此,如果您搜索 " is "
,您的 html 从 This is the
更改为 This<mark> is </mark>the
- 当您搜索 " is the"
时,它不匹配在 <mark> is </mark>the
.
而不是.html()
,使用.text()
获取没有标记的文本,然后它工作正常(至少那部分,没有检查其余部分,例如也改变原来的htmltochange
).这也意味着你没有得到 false-positives,例如在你的原始代码中搜索“div”,“div”出现在每个答案的 html 中,所以他们都显示出来了。
searchtarget.each(function(index) {
let text = $(this).text().toLowerCase();
- resetting to the initial value (val.length === 0) will see every word wrapped in a tag
这是由于 if
的顺序 - 您的第一个 if
查找空白并突出显示它们,第二个然后隐藏它们。
颠倒顺序,使其首先检查 length===0
,然后仅在不为 0 时才进行搜索。
已更新fiddle:
const searchfaq = $('#text-search');
const searchtarget = $(".nodisplay");
const htmltochange = searchtarget.map(function() {
return $(this).children().find('p').text();
}).get();
function delay(callback, ms) {
var timer = 0;
return function() {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
callback.apply(context, args);
}, ms || 0);
};
}
searchfaq.keyup(delay(function(e) {
let val = $(this).val().toLowerCase();
//console.log(val)
searchtarget.hide();
searchtarget.prev().children('.minus').removeClass('rotate');
searchtarget.each(function(index) {
let text = $(this).text().toLowerCase();
let paragraph = $(this).children().find('p');
let otherparagraph = searchtarget.children().find('p');
if (val.length === 0) {
paragraph[0].innerHTML = htmltochange[index];
$(this).hide();
searchtarget.prev().children('.minus').removeClass('rotate');
}
else if (text.indexOf(val) != -1) {
$(this).show();
$(this).prev().children('.minus').addClass('rotate');
var re = new RegExp(val, 'gi');
paragraph[0].innerHTML = htmltochange[index].replace(re, `<mark>$&</mark>`);
}
});
}, 500));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="lazyblock-faq-search">
<h1>Frequently Asked Questions</h1>
<form _lpchecked="1">
<input id="text-search" type="text" aria-label="search-for-answers" placeholder="Search for answers">
</form>
</div>
<div class="lazyblock-faq">
<div class="row">
<aside class="col-md-3">
<ul class="sticky-top">
<li class="active">
<a href="#chapter-1">Chapter 1</a>
</li>
<li class="">
<a href="#chapter-2">Chapter 2</a>
</li>
</ul>
</aside>
<div class="question-and-answer col-md-9">
<h2 id="chapter-1">Chapter 1</h2>
<div class="single-faq">
<h3>This is a question</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-Z2cLmzB">
<div class="row">
<div class="col-md-12">
<p>This is the answer</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a question 2</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZhBtAi">
<div class="row">
<div class="col-md-12">
<p>This is the answer 2</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>Question 3 ?</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZPm3XU">
<div class="row">
<div class="col-md-12">
<p>This is the answer 3</p>
</div>
</div>
</div>
</div>
</div>
<h2 id="chapter-2">Chapter 2</h2>
<div class="single-faq">
<h3>This is a question 4</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-1sQXGa">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 4</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a question 5</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-ZioRKT">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 5</p>
</div>
</div>
</div>
</div>
</div>
<div class="single-faq">
<h3>This is a quesition 6 and it has a weird layout</h3>
<div class="icon-faq">
<span class="minus">+</span>
<span class="plus">–</span>
</div>
<div class="nodisplay collapse" style="display: none;">
<div class="lazyblock-content " id="content-extra-2fxKyB">
<div class="row">
<div class="col-md-12">
<p>This is just a test for question 6</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>