几天前,我收到了该公司的空缺前端开发人员的测试任务。 当然,任务包括几点。 但是现在我们将只关注其中之一-页面上的搜索组织。 即 通过在字段中输入的文本(浏览器中Ctrl + F的类似键)进行普通搜索。 分配的特殊性是禁止使用任何JS框架或库。
全部使用本机JavaScript编写 。
(为清楚起见,我将继续在整篇文章中附有屏幕截图和代码,以便您和我都可以理解特定时刻我在说什么)寻找解决方案
首先想到的是:已经有人确切地写了这个,您需要Google并复制粘贴。 所以我做到了。 一个小时之内,我发现了两个很好的脚本,它们的工作原理基本相同,但是编写方式却不同。 我选择了一个我的代码更了解的代码,并将其插入到老人的页面中。
如果有人感兴趣,我在这里获取了代码。该脚本立即生效。 我以为问题已解决,但事实证明,脚本的作者没有冒犯,但存在巨大的缺陷。 该脚本搜索了标记的全部内容
...
并且,您可能已经猜到了,当搜索类似于标记或其属性的字符的任何组合时,整个HTML页面都会中断。
为什么脚本无法正常工作?
一切都很简单。 该脚本的工作方式如下。 首先,我们将
body标签的全部内容写到一个变量中,然后使用正则表达式查找匹配项(用户在输入文本字段时对其进行设置),然后将所有匹配项替换为以下代码:
<span style="background-color: yellow;">... ...</span>
然后,我们用收到的新标签替换当前的标签。 标记已更新,样式已更改,找到的所有结果在屏幕上以黄色突出显示。
您可能已经了解了问题所在,但是我将更详细地解释。 想象一下在搜索框中输入单词
“ div” 。 如您所知,
体内还有许多其他标签,包括
div 。 而且,如果我们都将上述样式应用于
“ div” ,那么这将不是一个障碍,但是由于设计中断,因此尚不清楚是什么。 结果,在覆盖标记之后,我们得到了一个完全损坏的网页。 看起来像这样。
在搜索之前:
完全褪色经过搜索后变成:
完全褪色如您所见,页面完全中断。 简而言之,该脚本原来是无效的,我决定从头开始编写自己的脚本,这就是本文的目的。
所以我们从头开始编写脚本
一切对我来说看起来如何。

现在,我们对搜索表单感兴趣。 他用红线圈了她一下。
让我们看一点。 我实现了如下(到目前为止是纯HTML)。 具有三个标签的表单。
第一个用于输入文本;
第二个用于输入文本。
第二个 -取消搜索(取消选择);
第三个是用于搜索(突出显示找到的结果)。
<form> <input type="text" value="" placeholder="Search" autofocus> <input type="button" value=" " title=" "> <input type="submit" value=" " title=" "> </form>
因此,我们有一个输入字段和2个按钮。 我将在js.js中编写JavaScript。 假设您已经创建并连接了它。
我们要做的第一件事:在单击搜索按钮和取消按钮时注册函数调用。 它看起来像这样:
<form> <input class="place_for_search" type="text" id="text-to-find" value="" placeholder="Search" autofocus> <input class="button_for_turn_back" type="button" onclick="javascript: FindOnPage('text-to-find',false); return false;" value=" " title=" "> <input class="button_for_search" type="submit" onclick="javascript: FindOnPage('text-to-find',true); return false;" value=" " title=" "> </form>
让我们解释一下这里的原因。
我们给文本字段
id =“ text-to-find” (
此id将引用js中的元素 )。
我们为取消
按钮提供以下属性:
type =“ button” onclick =“ javascript:FindOnPage('text-to-find',false); 返回false;“-
类型:按钮-
按下时,将调用FindOnPage函数(“文本查找”,false); 并传递带有文本的字段ID, false我们为搜索
按钮提供以下属性:
type =“ button” onclick =“ javascript:FindOnPage('text-to-find',true); 返回false;“-
类型:提交(不是按钮,因为您可以在此处输入字段后使用Enter键,也可以使用按钮)-
按下时,将调用FindOnPage函数(“文本到查找”,true); 并传递带有文本的字段ID,为true您可能会注意到另一个属性:
true / false 。 我们将使用它来确定按下了哪个按钮(取消搜索或开始搜索)。 如果单击取消,则传递
false 。 如果单击搜索,则传递
true 。
好,继续 转到JavaScript
我们假设您已经创建了js文件并将其连接到DOM。
在开始编写代码之前,让我们先休息一下,然后首先讨论一切应该如何工作。 即 本质上,我们将编写一个行动计划。 因此,我们需要在字段中输入文本时在页面上进行搜索,但标签和属性不应受到影响。 即 仅文本对象。 如何实现这一目标-我相信有很多方法。 但是现在我们将使用正则表达式。
因此,下一个正则表达式将仅查找文本跟踪。 类型:“> ...文本... <”。 即 仅搜索文本对象,而标签和属性保持不变。
/>(.*?)</g
因此,我们将找到要解析的代码的必要部分,并查找与用户输入的文本匹配的内容。 然后,我们将样式添加到找到的对象中,然后用新样式替换html代码。
让我们开始吧。 首先,我们需要的变量。
var input,search,pr,result,result_arr, locale_HTML, result_store;
并立即确定locale_HTML的值,而不管我们是否在寻找什么。 为了立即保存原始页面并能够重置样式,这是必需的。
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
好的,现在值得创建一个从DOM调用的函数。 立即估计内部应该有2个功能,每个功能都取决于所按下的按钮。 毕竟,我们要么进行搜索,要么将其归零。 如您所记得,这是由true / false属性控制的。 您还需要了解,当您再次搜索时,必须重新设置旧样式。 因此我们得到以下内容:
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
好的,部分逻辑已实现,继续。 必须检查接收到的单词的字符数。 毕竟,为什么我们需要寻找1个字母/符号。 通常,我决定将此字符数限制为3个以上。
因此,首先我们获取用户输入的值,然后根据其长度执行主搜索功能或警告和清零功能。 它看起来像这样:
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
现在,我将解释代码的这一部分。 唯一不清楚的是这一行:
函数FindOnPageBack(){document.body.innerHTML = locale_HTML; }
这里的一切都很简单: innerHTML方法返回对象的html代码。 在这种情况下,我们只需将当前正文替换为在加载整个页面时保存的原始正文即可。
我们继续前进。 我们给主要变量赋值。
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
因此,在这个阶段,我们已经有了主要的变量和值。 现在,我们需要使用突出显示的背景来提供代码样式的必要部分。 即 检查所选文本是否包含正则表达式(实际上,正则表达式再次选择了由正则表达式选择的文本)。 为此,您需要从输入的文本中做一个正则表达式(完成),然后执行以间歇方式传递的方法。 这里的eval()方法将为我们提供帮助。
通常,在替换文本并使用样式获得结果之后,我们需要将当前的html替换为接收到的html 。 我们做。
var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML;
本质上,一切都准备就绪,脚本已经在工作。 但是,请添加一些其他细节以提高美观度。
1)修剪用户输入的文本中的空格。 插入以下代码:
input = numer.replace(/^\s+/g,''); input = numer.replace(/[ ]{1,}/g,' ');
在此行之后:
input = document.getElementById(name).value;
2)我们将检查是否有巧合(如果未找到匹配项,我们将告知有关情况)。 将此代码插入变量后的功能FindOnPageGo()中。
var warning = true; for(var i=0;i<result.length;i++) { if(result[i].match(eval(search))!=null) { warning = false; } } if(warning == true) { alert(' '); }
您可以在此处查看源代码。
您可以在此处下载源代码。
现在全部。 当然,您可以将滚动条添加到找到的第一个结果中,进行实时ajax搜索,确实可以无休止地改进。 现在,这是在网站上进行的原始搜索。 本文的目的是帮助初学者,如果出现与我相同的问题。 毕竟,我没有找到简单的现成的解决方案。
PS:为了正确操作,有必要在标记之间纯文本的地方删除html文档中的文本连字符。
例如,代替
<p> </p>
必须
<p> </p>
这并不重要,您可以在服务上自动摆脱这些转移,但是,如果您在我之前已经了解,则可以同时告诉我如何解决。
另外,如果有人写了这篇文章,但是通过实时搜索分享了源代码,那么解析它将会很有趣。
我将很高兴听到建设性的批评,意见或建议。
最近,我添加了一些代码,在页面上进行了实时搜索。 这样问题就解决了。 HTML代码未更改。 JS可以看这里 。
使用类别为“ place_for_live_search”的标签进行搜索。 因此,为了使算法能够解析所需的内容,请添加类,然后完成。