开篇
这学期来一直在忙项目,整整一个学期都在做,自己的看书计划也没能实施。不过还是有不少收获的,是对以前看过的 JS Patterns 系列的综合运用,所以光看是不够的,一定要能应用到实际的业务中,并根据具体业务相应调整。趁着现在这段时间,想把以前写过的代码重新review一遍,并抽出可复用的功能把它们改写成通用组件,既是自己总结和提升的机会,也把它们作为以后的代码积累。
最近这个项目是做在线编程教育的,既然是教育,当然会跟学校挂钩,所以注册的时候就涉及到学校选择。我就从这里入手,讲述下如何一步步做成学校选择器的js组件。
界面设计
由于本人设计能力拙劣,所以偷懒直接参考了人人网里的学校选择器的画风。
我们这里只做了国内的高校,比人人网少一层,先从简,定义了下面的元素。
1 | <div class="school-box-wrapper"> |
我们通过自定义属性data-xxx
来存储ID,这里的学校ID采用的是教育部标准的学校代码,而省份ID无实际含义。参照上面的图,写出了以下样式。
1 | .school-box-wrapper{ |
大体效果如图,依样画葫芦还凑合吧。
学校数据存储
上面的demo中学校是hard code到元素中的,但实际上不可能这样做。我们需要定义school的数据格式。
1 | [ |
于是我们将抓来的所有学校数据生成一个JSON对象放在全局中。学校列表.js
省份-学校 级联
首先定义目标元素,province和school区域的父元素,以及province和school元素的copy(省得动态生成元素时写HTML了)。
1 | var $provinceDiv = $('.school-box-provinces'); |
其次,要定义变量将当前选中的province存起来,我们再定义一个变量指向全局的SCHOOL_LIST
。
1 | var provinces = SCHOOL_LIST; |
1.开始写初始化province区域的代码。
1 | var initProvinces = function(){ |
2.初始化学校,当然要根据传入的provinceId
。
1 | var getProvinceById = function(pid){ |
3.为province绑定click
事件,这样就能级联起来。
1 | var onProvinceClick = function(){ |
4.同样为school添加click
,还需要定义两个表单里的元素。
1 | var $schoolInput = $('#schoolInput'); |
5.添加动画以及统一初始化方法
1 | var $schoolBox = $('.school-box-wrapper'); |
6.最后为了避免变量作用域的污染,我们定义一个自执行函数,去包裹以上所有js代码。
1 | (function(){ |
7.添加下点缀,让它每次showSchoolBox
时都能自定选中前一次选择的province。
1 | var lastProvinceIndex = 0; //最后一次点击的index,用于初始化选中 |
还有吗?
到这里一个简单的demo完成了,但是js代码和当前页面的HTML元素耦合很大,如果改了HTML则js也要相应的改。那么问题来了,如果在另一个页面也需要这样的学校选择器该怎么办呢?复制大段代码吗?