业务中经常需要对数据进行下拉框的联动选择操作,可以假设成省份城市 省份城市县这样的多级联动
客户那边提供的数据大多为excel,格式都属于标准一行列的
假设需要对省份城市进行联动 实现如下
1 var pcd = []; 2 pcd[0] = ['北京', '北京']; 3 pcd[1] = ['天津', '天津']; 4 pcd[2] = ['河北', '石家庄']; 5 pcd[3] = ['河北', '唐山']; 6 pcd[4] = ['山西', '太原']; 7 pcd[5] = ['辽宁', '沈阳']; 8 pcd[6] = ['吉林', '长春']; 9 pcd[7] = ['黑龙江', '哈尔滨'];10 pcd[8] = ['上海', '上海'];11 pcd[9] = ['江苏', '南京'];12 pcd[10] = ['江苏', '无锡'];13 pcd[11] = ['江苏', '苏州'];14 pcd[12] = ['浙江', '杭州'];15 pcd[13] = ['浙江', '宁波'];16 pcd[14] = ['浙江', '温州'];17 pcd[15] = ['安徽', '合肥'];18 pcd[16] = ['福建', '福州'];19 pcd[17] = ['江西', '南昌'];20 pcd[18] = ['山东', '济南'];21 pcd[19] = ['山东', '青岛'];22 pcd[20] = ['河南', '郑州'];23 pcd[21] = ['湖北', '武汉'];24 pcd[22] = ['湖南', '长沙'];25 pcd[23] = ['广东', '广州'];26 pcd[24] = ['广东', '深圳'];27 pcd[25] = ['广西', '南宁'];28 pcd[26] = ['重庆', '重庆'];29 pcd[27] = ['四川', '成都'];30 pcd[28] = ['云南', '昆明'];31 pcd[29] = ['陕西', '西安'];32 33 Array.prototype.contains = function (e) {34 for (var i = 0; i < this.length; i++) {35 if (this[i] === e) {36 return true;37 }38 }39 return false;40 }41 42 document.getElementById("aprovincename").onchange = function () {43 bindCity(this.value);44 }45 document.getElementById("acityname").onchange = function () {46 bindDealer(this.value);47 }48 49 function bindProvince() {50 var items = new Array();51 var el = document.getElementById("aprovincename");52 el.length = 0;53 el.options.add(new Option('请选择省份', '0'));54 bindCity(0);55 for (var i = 0, len = pcd.length; i < len; i++) {56 if (!items.contains(pcd[i][0])) {57 items.push(pcd[i][0]);58 el.options.add(new Option(pcd[i][0], pcd[i][0]));59 }60 }61 }62 function bindCity(pid) {63 64 var el = document.getElementById("acityname");65 el.length = 0;66 el.options.add(new Option('请选择城市', '0'));67 68 if (pid === 0) {69 return;70 }71 var items = new Array();72 for (var i = 0, len = pcd.length; i < len; i++) {73 if (pcd[i][0] === pid && !items.contains(pcd[i][1])) {74 items.push(pcd[i][1]);75 el.options.add(new Option(pcd[i][1], pcd[i][1]));76 }77 }78 }79 80 bindProvince();
View Code
基本需求就是这样的 在此基础上如果需要设置下拉框选项的value值为ID值 那么需要修改相应方法绑定的数据索引
把这部分功能参数封装一下,让其满足多级联动
(function () { var Linkage = function (paras) { var _$ = function (id) { return document.getElementById(id); } var items = [], item = {}, data = paras.data; var drop = function (options) { this.element = _$(options.id); this.text = options.text || '请选择'; this.value = options.value || '0'; options.selected && (this.selected = options.selected); options.filter && (this.filter = options.filter); options.datachange && (this.datachange = options.datachange); if (items.length > 0) { this.prevdrop = items[items.length - 1]; var self = this; this.prevdrop.element.onchange = function () { self.bind(); } this.prevdrop.nextdrop = this; if (options.textIndex == undefined) { options.textIndex = Math.max(this.prevdrop.textIndex, this.prevdrop.valueIndex) + 1; } } this.textIndex = options.textIndex || items.length; this.valueIndex = options.valueIndex || this.textIndex; }; drop.prototype.bind = function () { var self = this, element = self.element, currentData = [], filterObj = {}, nextbind = false; element.length = 0; element.options.add(new Option(self.text, self.value)); self.nextdrop && self.nextdrop.bind(); if (self.prevdrop && self.prevdrop.element.value == self.prevdrop.value) { self.datachange && self.datachange(self.element, []); return; } for (var i = 0; i < data.length; i++) { if (self.prevdrop) { //如果此条数据在上级未使用跳过 if (self.prevdrop.element.value != data[i][self.prevdrop.valueIndex]) { continue; } //如果上级存在过滤方法 执行 if (self.prevdrop.filter) { var pf = self.prevdrop.filter(data[i]); if (pf == undefined ? false : !pf) { continue; } } } currentData.push(data[i]); var text = data[i][self.textIndex]; //排重 if (filterObj[text] != undefined) continue; filterObj[text] = text; //如果存在过滤方法进行过来处理 调用方式有待优化 if (self.filter) { var f = self.filter(data[i]); if (f == undefined ? false : !f) { continue; } } var option = new Option(text, data[i][self.valueIndex]); element.options.add(option); //如果是选定的内容 设置选项选中并设置调用下一个的绑定方法 if (self.selected && (typeof self.selected == 'function' ? self.selected() : self.selected) == text) { option.selected = true; nextbind = true; } } //如果选项中只有一个数据项 删除默认选项并设置调用下一个的绑定方法 if (element.length == 2) { element.remove(0); nextbind = true; } self.datachange && self.datachange(element, currentData); if (nextbind) { self.nextdrop && self.nextdrop.bind(); } } drop.prototype.gettext = function () { return this.element.options[this.element.selectedIndex].innerHTML; }; var add = function (optons) { var d = new drop(optons); items.push(d); item[item.id] = d; } var bind = function () { items[0].bind(); paras.success && paras.success(); } for (var i = 0; i < paras.items.length; i++) { add(paras.items[i]); } bind(); return { items: items, item: item, bind: bind } } window.AL = Linkage;})();
View Code
封装规则按照传递过来的对象数组顺序定义上下级关系,对象textIndex和valueIndex用于获取属于这个下拉框的索引值,默认情况使用当前对象的索引值,下一个取值为上一个最大索引+1;通过selected属性可以设置默认选择当前值
缺点:
1.JS不怎么会 效果是实现了 不知道是不是有更好的实现方式
2.数据格式支持上述pcd数组类的,喜欢后续能支持js对象,ajax请求接口拿到数据那种
3.只支持select下拉框联动 无法用于自定义div类的联动
--博客园不会怎么插入代码 直接在页面上面看效果--
原标题:下拉框联动方法封装
关键词: