基于jQuery的三级联动控件

来源:互联网 发布:外汇行情数据接口 编辑:程序博客网 时间:2024/06/06 05:46

三级联动控件在日常开发中经常会用到,比如选择省市区,年月日等情况,而原生的html并没有这样的一个控件,闲暇之余,写了这么一个控件,预览效果如下:
这里写图片描述
废话不多说,直接贴代码:
jquery.dropmenu.css

.dropmenu {    width: auto;    height: auto;}.dropmenu > .top {    position: relative;    width: 100%;    height: 30px;    border: 1px #cccccc solid;    font-size: 0;    overflow:hidden;}.dropmenu > .top >.data {    float: left;    padding: 0 5px;    width: 100%;    height: 30px;    line-height: 30px;    font-size: 16px;    border-right: 1px #cccccc solid;    background: #dddddd;}.dropmenu > .top > .data > p {    padding: 0 30px 0 0;    margin: 0;    white-space:nowrap;    word-break:break-all;    text-overflow:ellipsis;    overflow:hidden;}.dropmenu > .top > .btn {    position: absolute;    right: 0;    width: 30px;    height: 30px;    line-height: 30px;    font-size: 16px;    text-align: center;    cursor: pointer;    z-index: 1;    background: #ffffff;}.dropmenu > .drop {    position: absolute;    margin-top: -1px;    height: auto;    width: auto;    z-index: 999;    background: #fff;    font-size: 0;}.dropmenu > .drop > .options {    display: inline-block;    vertical-align: top;    height: auto;    width: auto;    border-left: 1px #cccccc solid;    border-right: 1px #cccccc solid;    border-top: 1px #cccccc solid;}.dropmenu > .drop > .options > ul {    margin: 0;    padding:0;    list-style-type: none;}.dropmenu > .drop > .options > ul > li {    padding:0 5px;    height: 30px;    line-height: 30px;    border-bottom: 1px #cccccc solid;    cursor: pointer;    font-size: 14px;}.dropmenu > .drop > .options > ul > li:hover {    background: #cccccc}

jquery.dropmenu.js

if (jQuery === undefined)    throw new Error("本控件基于jQuery,请先引入jQuery相关文件!")$.fn.dropmenu = function(config) {    return DropMenu.call(this,config)}var DropMenu = function(config) {    this.top = null//顶部部分    this.drop = null//下拉部分    this.width = null//top的宽度    this.optionsWidth = null//options区域宽度    this.last = false//是否允许选择非末级    this.cache = {}//缓存解析的数据    this.options = [] //下拉数据    this.data = {}//被选中的数据    this.interface = null//如果需要从网络请求数据    this.listener = {}//事件监听    $.extend(this,DropMenu.prototype,config)    this.init()    this.bind()    this.adjust()    return this}/** * 初始化控件视图 */DropMenu.prototype.init = function() {    this.top = $("<div class='top'>")    this.top.append("<div class='data'><p></p></div>")    this.top.append("<div class='btn'>▼</div>")    this.drop = $("<div class='drop'>")    this.drop.hide()    if (this.width !== null)        this.top.css("width",this.width)    this.append(this.top)    this.append(this.drop)}/** * 绑定事件 */DropMenu.prototype.bind = function () {    this.top.on("click.api.dropmenu.display",".btn",this,DropMenu.prototype.display)    this.drop.on("click.api.dropmenu.click",".options > ul > li",this,DropMenu.prototype.click)    this.drop.on("mouseleave.api.dropmenu.leave",".options",this,DropMenu.prototype.leave)    this.drop.on("mouseover.api.dropmenu.slide",".options > ul > li",this,DropMenu.prototype.slide)}/** * 调整和绑定数据 * @param level 需要加载的数据的级别(1,2,3),默认为1 * @param offsetTop 偏移 * @param parent 父级关键字 */DropMenu.prototype.adjust = function(level,offsetTop,parent) {    if (level === undefined || isNaN(level))        level = "1"    var data = this.parse(level,parent)    if (data === undefined || data.length === 0)        return;    var options = $("<div class='options' data-level='"+level+"'>")    var ul = $("<ul>")    for (var i=0 ; i < data.length ; i++) {        ul.append("<li data-key='"+data[i].key+"'>"+data[i].value+"</li>")    }    options.append(ul)    if (offsetTop !== undefined && !isNaN(offsetTop))        options.css("margin-top",offsetTop+"px")    if (this.optionsWidth !== null)        options.css("width",this.optionsWidth)    this.drop.append(options)}/** * 解析options,并将解析过的直接存入缓存,方便直接使用 */DropMenu.prototype.parse = function(level,parent){    if (this.options === undefined || this.options.length === 0)        return    if (level === undefined)        level = "1"    if (parent !== undefined && this.cache[parent] !== undefined)        return this.cache[parent]    var result = new Array    for (var i=0;i<this.options.length;i++) {        if (level === this.options[i].level && parent === this.options[i].parent) {            result.push(this.options[i])        }    }    if (parent === undefined)        this.cache["top"] = result    else        this.cache[parent] = result    return result}/** * btn点击事件 * @param event */DropMenu.prototype.display = function(event) {    var plugin = event.data    plugin.drop.fadeToggle()}/** * 下拉列表中选项的鼠标移动事件 * @param event */DropMenu.prototype.slide = function(event) {    var plugin = event.data    var level = $(this.closest(".options")).attr("data-level")    var nextLevel = "1"    if (level === "1") {        plugin.drop.find(".options:gt(0)").remove()        nextLevel = "2"    }else if (level === "2") {        plugin.drop.find(".options:gt(1)").remove()        nextLevel = "3"    }else if (level === "3") {        return    }    var offsetTop = this.offsetTop - 1    var parent = $(this).attr("data-key")    plugin.adjust(nextLevel,offsetTop,parent)}/** * item点击事件 * @param event */DropMenu.prototype.click = function (event) {    var plugin = event.data    var level = $(this).closest(".options").attr("data-level")    var parent = $(this).attr("data-key")    var key = $(this).attr("data-key")    var value = $(this).text()    var p = plugin.top.find(".data > p")    var children = null    if (!plugin.last && level === "1" ) {        children = plugin.parse("2",parent)    }else if (!plugin.last && level === "2") {        children = plugin.parse("3",parent)    }    if (children === null || children.length === 0) {        p.text(value)        p.attr("key",key)        plugin.drop.hide()        plugin.data["key"]=key        plugin.data["value"]=value        if (plugin.listener.select !== undefined)            plugin.listener.select(plugin.data,this,plugin)    }}/** * 鼠标离开options区域事件 * @param event */DropMenu.prototype.leave = function (event) {    var plugin = event.data    var to = event.toElement    if (to.closest(".options") == null) {        plugin.drop.hide()        plugin.drop.find(".options:gt(0)").remove()    }}DropMenu.prototype.request = function() {}DropMenu.prototype.getData = function () {    return this.data}

index.html

<!DOCTYPE html><html><head>    <title>测试</title>    <meta charset="UTF-8">    <script src='https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js'></script>    <link rel="stylesheet" type="text/css" href="jquery.dropmenu.css">    <script type="text/javascript" src="jquery.dropmenu.js"></script></head><body>    <div class="dropmenu"></div>    <script type="text/javascript">        $(function(){            var obj=$(".dropmenu").dropmenu({                "width":"210px",                "optionsWidth" : "210px",                "options":[                    {"key":"1","value":"湖南省","level":"1"},                    {"key":"2","value":"湖北省","level":"1"},                    {"key":"3","value":"河北省","level":"1"},                    {"key":"4","value":"河南省","level":"1"},                    {"key":"5","value":"广东省","level":"1"},                    {"key":"6","value":"广西省","level":"1"},                    {"key":"7","value":"福建省","level":"1"},                    {"key":"8","value":"安徽省","level":"1"},                    {"key":"21","value":"长沙市","level":"2","parent":"1"},                    {"key":"22","value":"株洲市","level":"2","parent":"1"},                    {"key":"23","value":"衡阳市","level":"2","parent":"1"},                    {"key":"24","value":"邵阳市","level":"2","parent":"1"},                    {"key":"21","value":"武汉市","level":"2","parent":"2"},                    {"key":"22","value":"黄石市","level":"2","parent":"2"},                    {"key":"23","value":"十堰市","level":"2","parent":"2"},                    {"key":"24","value":"宜昌市","level":"2","parent":"2"},                    {"key":"25","value":"襄阳市","level":"2","parent":"2"},                    {"key":"26","value":"鄂州市","level":"2","parent":"2"},                    {"key":"27","value":"荆门市","level":"2","parent":"2"},                    {"key":"28","value":"孝感市","level":"2","parent":"2"},                    {"key":"21","value":"石家庄市","level":"2","parent":"3"},                    {"key":"22","value":"唐山市","level":"2","parent":"3"},                    {"key":"23","value":"秦皇岛市","level":"2","parent":"3"},                    {"key":"24","value":"邯郸市","level":"2","parent":"3"},                    {"key":"21","value":"邢台市","level":"2","parent":"3"},                    {"key":"41","value":"开封市","level":"2","parent":"4"},                    {"key":"42","value":"洛阳市","level":"2","parent":"4"},                    {"key":"43","value":"安阳市","level":"2","parent":"4"},                    {"key":"231","value":"茅箭区","level":"3","parent":"23"},                    {"key":"232","value":"张湾区","level":"3","parent":"23"},                    {"key":"233","value":"十堰经济技术开发区","level":"3","parent":"23"},                    {"key":"234","value":"郧阳区","level":"3","parent":"23"},                    {"key":"235","value":"郧西县","level":"3","parent":"23"},                    {"key":"236","value":"竹山县","level":"3","parent":"23"},                    {"key":"237","value":"竹溪县","level":"3","parent":"23"},                    {"key":"238","value":"房县","level":"3","parent":"23"}                ]            });        })    </script></body></html>

本控件仅供学习使用,可能存在一定的BUG,欢迎大家指正。

原创粉丝点击