一个下拉选择省市区的组件

项目中的表单经常涉及下拉选择,有些需要层级关联,比如选择省市区,有些则不需要,只有一级。现自己封装了一个符合项目ui设计的下拉框。

要求:符合AMD规范;依赖jq;兼容ie8;

组件代码如下:

define('vDrop', [
  'jquery'
], function ($) {
  'use strict';
  /** 
* 组件名:v-drop,一个下拉框组件
* 
* @exports vDrop
* @author Viocexx
* @version 1.0
* @class
*/

  var vDropCreate = function (params) {
    /**
     * @description 初始化下拉框组件
     * @param {id}  id 下拉框生成的父级id
     * @param {tabs}  示例:["省","市","区","街道"],确定下拉框是几级的,与datajson里的数据层级要对应上,只有一级时不传这个参数。
     * @param {datajson}  datajson 下拉框显示数据
     * @param {callback}  选择后的回调函数
     */

    this.id = params.id;
    this.tabs = params.tabs;
    this.datajson = params.datajson;
    this._call = params.callback;
    var _this = this;

    // 初始化函数 生成最外层div 选择结果显示框 和 下拉选择框
    this.init = function () {
      var dropHTML = '<div style="position:relative" class="js-dropbox"></div>';
      $("#" + _this.id).html(dropHTML);
      var ls = _this.tabs;
      var dropHtml = ''
      if (ls == undefined) {
        dropHtml = '<div class="dropInput js-area"><span>点击下拉选择</span></div>'
          + '<div class="dropDownBox js-area-box"></div>';
      } else {
        var le = ls.length;
        dropHtml = '<div class="dropInput js-area">'
        for (var i = 0; i < le; i++) {
          dropHtml += i < le - 1 ?
            '<span>--</span>/' :
            '<span>--</span>'
        }
        dropHtml += '</div>'
          + '<div class="dropDownBox js-area-box"></div>'
      }

      $("#" + _this.id).find(".js-dropbox").html(dropHtml);
      _this.downBox()

    }

    // 生成下拉选项里的内容  分区域的时候有tab  不分区域的时候没有tab
    this.downBox = function () {
      var ls = _this.tabs;
      var downHtml = ''
      if (ls == undefined) {
        downHtml = '<div class="js-areaBox"></div>';
      }
      else {
        var le = ls.length;
        downHtml = '<div class="clearfix vregionBox js-region">';
        for (var i = 0; i < ls.length; i++) {
          var ac = i == 0 ? 'vchi' : '';
          downHtml += '<div class="fl ' + ac + '" style="width:' + 100 / le + '%">' + ls[i] + '</div>'
        }
        downHtml += '</div><div class="js-areaBox"></div>';
      }
      $("#" + _this.id).find(".js-area-box").html(downHtml);
      _this.areaBox();
    };

    // 区域盒子里的数据渲染
    this.areaBox = function () {
      var data = _this.datajson;
      var ls = _this.tabs;
      var areHtml = '<ul class="js-address-ul dropShow">';
      if (ls != undefined) {

        for (var i = 0; i < data.length; i++) {
          if (data[i].parent == "CN") {
            areHtml += '<li data-id="' + data[i].id + '"><p>' + data[i].name + '</p></li>'
          }
        }
        areHtml += '</ul>';

        for (var i = 0; i < ls.length - 1; i++) {
          areHtml += '<ul class="js-address-ul">请先选择上一级</ul>'
        }
      } else if (ls == undefined) {
        for (var i = 0; i < data.length; i++) {
          areHtml += '<li data-id="' + data[i].id + '"><p>' + data[i].name + '</p></li>'
        }
        areHtml += '</ul>';
      }
      $("#" + _this.id).find(".js-areaBox").append(areHtml);
      _this.domFunc();
    }

    // 渲染下一级数据
    this.createNext = function (id) {
      var data = _this.datajson;
      var areHtml = '';
      for (var i = 0; i < data.length; i++) {
        if (data[i].parent == id) {
          areHtml += '<li data-id="' + data[i].id + '"><p>' + data[i].name + '</p></li>'
        }
      }
      return areHtml
    }

    // 下拉框里的dom 操作函数
    this.domFunc = function () {
      var regionIndex = "";
      var myindex = "";
      var liIdLs = [];
      $('#' + _this.id).on("click", ".js-area", function (e) {
        var e = e || window.e;
        stopFunc(e);
        var width = $(this).width();
        $(this).siblings(".js-area-box").width(width).addClass("dropShow");
        regionIndex = $(this).siblings(".js-area-box").find(".js-areaBox").children(".js-address-ul").length;
      }).on("click", ".js-region div", function (e) {
        var e = e || window.e;
        stopFunc(e);
        var index = $(this).index();
        $(this).addClass("vchi").siblings().removeClass("vchi");
        $(this).parent().siblings(".js-areaBox").find(".js-address-ul").eq(index).addClass("dropShow").siblings().removeClass("dropShow");
      }).on("click", ".js-address-ul li", function (e) {
        var e = e || window.e;
        stopFunc(e);
        var dataId = $(this).attr("data-id");
        var nextContent = _this.createNext(dataId);
        myindex = $(this).parent().index() + 1;
        console.log(_this)
        liIdLs[myindex - 1] = dataId;
        var tresult = $(this).children("p").text();
        $(this).parent().parent().parent().siblings(".js-area").find("span").eq(myindex - 1).html(tresult).attr("title", tresult).attr("data-id", dataId).nextAll("span").html("--").attr("title", "");
        if (myindex == regionIndex) {
          $(this).parent().parent().parent().removeClass("dropShow");
          $("#" + _this.id).attr("data-id", liIdLs);
          if (_this._call != undefined) {
            _this._call(liIdLs);
          }

        } else {
          $(this).parent().removeClass("dropShow").eq(myindex).addClass("dropShow");
          $(this).parent().parent().find(".js-address-ul").eq(myindex).addClass("dropShow").html(nextContent);
          $(this).parent().parent().siblings(".js-region").find("div").eq(myindex).addClass("vchi").siblings().removeClass("vchi");
        }
      }).on("click", ".js-area-box", function (e) {
        var e = e || window.e;
        stopFunc(e);
      })

      $("body").on("click", function (e) {
        var e = e || window.e;
        stopFunc(e);
        $(".js-area-box").removeClass("dropShow")
      })

      // 阻止事件冒泡
      function stopFunc(e) {
        /*标准浏览器有效 IE不行   e.stopPropagation();*/
        /*没有兼容性问题阻止事件冒泡e.cancelBubble = true;*/
        e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
      }
    }
  }
  var vDrop = {};
  vDrop.init = function (params) {
    var newT = new vDropCreate(params);
    newT.init();
  }
  return vDrop;
})

遇到的问题:

最开始的时候没有关注this指向问题,当页面有两个地方需要使用下拉框组件的时候,先加载的组件数据会被后加载的数据覆盖。于是做了修改,封装为了对象,使用时new。

require.config:

//模块的加载
//在主模块里面,对模块的加载行为进行自定义 require.config(参数),此参数就是一个对象
require.config({
  baseURL: '/VDrop/js',
  paths: {
    jquery: "/VDrop/js/jquery-1.11.3.min",
    vDrop: "/VDrop/v-drop/VDrop"
  },

});

使用实例:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>drop</title>
  <link rel="stylesheet" href="../v-drop/v-drop.css">
  <style>
    body {
      font-size: 14px;
      padding: 100px;
    }

    #div1 {
      width: 500px;
      margin-top: 50px;
    }

    #div2 {
      width: 500px;
      margin-top: 50px;

    }
  </style>
</head>
<body>
  <div id="div1"></div>
  <div id="div2"></div>
</body>
<script src="../js/require.js"></script>
<script src="../js/require-conf.js"></script>
<script>
  require(['jquery', 'vDrop'], function ($, t) {
    var tablist = ["省", "市", "区"];
    var listArea = [
      {
        id: "100",
        name: "安徽省",
        parent: "CN"
      },
      {
        id: "101",
        name: "河南省",
        parent: "CN"
      },
      {
        id: "1001",
        name: "合肥市",
        parent: "100"
      }, {
        id: "1002",
        name: "芜湖市",
        parent: "100"
      },
      {
        id: "10011",
        name: "蜀山区",
        parent: "1001"
      }, {
        id: "10021",
        name: "镜湖区",
        parent: "1002"
      },
      {
        id: "1011",
        name: "郑州市",
        parent: "101"
      },
      {
        id: "10111",
        name: "某某区",
        parent: "1011"
      },
    ]

    var list2 = [
      {
        id: "100",
        name: "01"
      },
      {
        id: "101",
        name: "02"
      }
    ];
    function _cll(val) {
      console.log(val, 'ids')
    }
    $(function () {
      t.init({ id: "div1", datajson: listArea, tabs: tablist });
      t.init({ id: "div2", datajson: list2, callback: _cll });
    })
  })

</script>

</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值