在上一篇中我们用观察者模式实现了自定义事件的功能,让应用层的事件回调更加松耦合。但是到此为止学校选择器仅仅做了基本的省份和学校的级联功能,现在我们要为它添加搜索的功能。
界面设计
依旧模仿人人网的学校设计,它也有个动态搜索框,如图。
先依样画葫芦把元素和样式搞出来
1 | <div class="search-school-wrapper"> |
这里的元素最后都要搬到js中去生成,先写在html里为了调样式。
1 | .search-school-wrapper{ |
如何搜索
我们当然首先想到发送一个Ajax请求,然后后台去数据库模糊查询,最后返回一个学校列表的数据。甚至做的更好一些的话,可以定义关键词匹配度,然后根据这个值来调整返回的学校列表的顺序。
在之前的章节中,我们将一个很大的SCHOOL_LIST
变量存在了js中,包含了后台数据库中的所有学校。这里我们继续这个思路,采用的是直接在js本地搜索。
1 | var reg = eval('/' + keywords.split('').join('\\S*') + '/'); |
这里keywords
就是用户输入的text,我们用这样一个正则去匹配SCHOOL_LIST
的学校名称,最后将一个列表刷新到页面元素上。
扩展组件功能
1.在私有静态变量里添加元素copy
1 | var $searchSchoolCopy = $('...省略...即上面那段html'); |
2.初始化新的元素
1 | var initSearchSchool = function(instance){ |
3.搜索学校的动态刷新
1 | var updateSearchList = function(schools, $searchDiv, $searchList, $searchEmpty){ |
这里采用与之前实现省份-学校级联功能类似的办法,由于这些方法写成了类的静态私有方法(因为我不想把它们暴露到类的外面,也不想让每个类的实例都存有该方法的备份),所以需要把具体实例涉及到的DOM元素作为参数传到这些方法中。
4.为搜索学校绑定事件
1 | var initSearchSchool = function(instance){ |
5.搜索框中选定学校,触发自定义事件(给类的外部)
1 | var initSearchSchool = function(instance){ |
6.应用层使用组件时添加一项初始化参数
1 | var schoolBox = new SchoolBox({ |
这里通过搜索框选择的学校触发的也是schoolChosen
事件,所以对应用层来说是透明的。即应用层不需要知道该事件来自省份-学校级联,还是来自学校搜索框。
精益求精
虽然简单实现了搜索框的功能,其实只能算“过滤”,这个系列就要这样结束了吗?细心的同学会发现上面的demo搜索框出来的结果只能用鼠标点击,不支持键盘事件。而根据我们平时使用别人软件的习惯,经常是输入完关键字后按方向键选择匹配的项,然后直接按回车键进入下一步。我将在下一篇中来实现这个功能。