该文章是基于chengyanfen 的模拟下拉列表select,做的二次修改,改为了多选操作
背景:select的option下放不进去多选的input框,需要进行模拟select
缺陷:未作浏览器的兼容性,取消下拉时存在点击body之外时取消事件不执行
依赖:jQuery,resert.css
/**
* 思路:
* 1.设置公用数组,为页面初始化和页面操作提供便利
* 2.当下拉的选项中在点击时分两种状态:
* ----① 当前为选中状态执行两个操作,更新显示的数组和隐藏的数组 (两者都为删除操作)
* ----② 当前为未选中状态时也是执行两个操作,给显示的数组和隐藏的数组执行添加操作
*/
css
/* 模拟下拉的样式 */
.simulateSelect-box {
width: 197px;
height: 27px;
line-height: 27px;
border: 1px solid #aaa;
/*float: left;*/
margin-right: 20px;
text-indent: 5px;
position: relative;
display: inline-block;
z-index: 99999;
bottom:-8px;
}
.simulateSelect-text {
height: 27px;
padding-right: 17px;
background: url(http://ourjs.github.io/static/2015/arrow.png) no-repeat right center;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
/*控制省略号*/
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
-webkit-text-overflow: ellipsis;
}
.simulateSelect-option {
display: none;
position: absolute;
background: #fff;
width: 100%;
left: -1px;
border: 1px solid #aaa;
}
.simulateSelect-option li {
height: 22px;
line-height: 22px;
color: #555;
cursor: pointer;
}
.simulateSelect-option li.seleced {
background: #06C;
color: #fff;
}
.simulateSelect-box input[type="checkbox"] {
width: 16px;
height: 16px;
}
.simulateSelect-box .w-100per {
width: 100%;
}
.simulateSelect-box .fo-pos {
position: relative;
}
.simulateSelect-box .fo-pos-a {
position: absolute;
}
.simulateSelect-box .inline-block {
display: inline-block;
}
.simulateSelect-box label {
padding-left: 16px;
}
.simulateSelect-box .fo-pos-a_t-5 {
top: 5px;
}
html
<!-- 模拟下拉框区域 -->
<div class="simulateSelect-box mb-3">
<div class="simulateSelect-text" data-value=""></div>
<ul class="simulateSelect-option">
<li class="fo-pos">
<input type="checkbox" id="sh01" name="yiqi[]" class="fo-pos-a fo-pos-a_t-5" value="A">
<label for="sh01" class="inline-block w-100per">A</label>
</li>
<li class="fo-pos">
<input type="checkbox" id="sh02" name="yiqi[]" class="fo-pos-a fo-pos-a_t-5" value="8">
<label for="sh02" class="inline-block w-100per">B</label>
</li>
<li class="fo-pos">
<input type="checkbox" id="sh03" name="yiqi[]" class="fo-pos-a fo-pos-a_t-5" value="C">
<label for="sh03" class="inline-block w-100per">C</label>
</li>
<li class="fo-pos">
<input type="checkbox" id="sh04" name="yiqi[]" class="fo-pos-a fo-pos-a_t-5" value="D">
<label for="sh04" class="inline-block w-100per">D</label>
</li>
</ul>
<input type="hidden" class="selected-input" data-value="A,C,D" name="yiqi" value=""/>
<!-- <input type="hidden" class="selected-input" data-value=""/> -->
</div>
js
//数组去重
Array.prototype.delCopy = function () {
var len = this.length;
for (var a = 0, n = []; a < len; a++) {
if (n.indexOf(this[a]) == -1) {
n.push(this[a])
}
}
return n;
};
//查找位置
Array.prototype.indexOf = function (val) {
for (var i = 0; i < this.length; i++) {
if (this[i] == val) return i;
}
return -1;
};
//删除指定位置的数组内元素
Array.prototype.remove = function (val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
var moni = {
str: [],//多选显示在框里的字符串
str_n: [],//多选显示隐藏域的name值字符串
init: function () {
var _this = this;
var $box = $('div.simulateSelect-box');//父级容器
var $option = $('ul.simulateSelect-option', $box);//option区域
var $txt = $('div.simulateSelect-text', $box);//放置 多选显示在框里的字符串 的区域
var speed = 10;//下拉窗口闭合的速度
/**
* 当点击显示的字符串区域时,下拉弹窗要显示
*/
$txt.click(function (e) {
//找到当前点击元素的兄弟元素ul.simulateSelect-option
var $current = $(this).siblings('ul.simulateSelect-option');
//显示当前下拉
$current.slideToggle(speed);
return false;
});
/**
* 思路:
* 当下拉的选项中在点击时分两种状态:
* ----① 当前为选中状态执行两个操作,更新显示的数组和隐藏的数组 (两者都为删除操作)
* ----② 当前为未选中状态时也是执行两个操作,给显示的数组和隐藏的数组执行添加操作
*/
$option.find('li')
//初始化选中项
.mousedown(function () {
//获取当前input点击时有没有被选中
var isChecked = $(this).find('input[type="checkbox"]').is(":checked");
console.log(isChecked);
if (isChecked) {
//如果是选中的了就执行 删除操作
//显示的字符串去重
_this.str.delCopy();
//移除掉显示的字符串中当前点击的
_this.str.remove($(this).find('input').val());
//隐藏的name值去重
_this.str_n.delCopy();
//移除掉隐藏的name值中当前点击的
_this.str_n.remove($(this).find('input').val());
//console.log(_this.str);
} else {
//赋值操作
//添加到显示中当前点击的字符串
_this.str.unshift($(this).find('input').val());
//添加到隐藏的name值中当前点击的
_this.str_n.unshift($(this).find('input').val());
}
//再次去重
//显示的字符串赋值给str_rel
var str_rel = _this.str.delCopy();//去重
//隐藏的字符串赋值给str_n_rel
var str_n_rel = _this.str_n.delCopy();//去重
//给显示的字符串执行拼接操作
for (var i = 0, set_str = ''; i < str_rel.length; i++) {
if (i == (str_rel.length - 1)) {
//如果是最后一个就不加','
set_str += str_rel[i]
} else {
//不是最后一个就每个都在后面拼接','
set_str += str_rel[i] + ','
}
}
for (var n = 0, set_str_n = ''; n < str_n_rel.length; n++) {
if (n == (str_rel.length - 1)) {
//隐藏的name 如果是最后一个就不加','
set_str_n += str_n_rel[n]
} else {
//隐藏的name不是最后一个就每个都在后面 拼接 ','
set_str_n += str_n_rel[n] + ','
}
}
//赋值 操作
//给显示的字符串 赋值 拼接好的字符串
_this.setshowStr(set_str);
//给隐藏的name字符串 赋值 拼接好的字符串
_this.sethiddenStr(set_str_n);
return false;
})
.mouseover(function () {
//如果鼠标在哪个li上,就给当前的添加选中,当前li的兄弟元素移选中
//暂时没用了
});
//关闭 下拉的UL
$('body').click(function (e) {
if (e.target.parentNode.parentNode.nodeName == 'UL') {
//如果点击的当前元素的父级的父级的nodeName是UL时执行的操作
} else {
//如果点击的当前元素的父级的父级的nodeName不是UL时执行关闭
$option.slideUp(speed);
}
})
},
//给显示的字符串 赋值 拼接好的字符串
setshowStr: function (set_str) {
$('div.simulateSelect-text').text(set_str);
},
//给隐藏的name字符串 赋值 拼接好的字符串
sethiddenStr: function (set_str_n) {
$('input.selected-input').attr('data-value', set_str_n);
//$('input.selected-input').val(set_str_n);
},
twoInit: function () {
var _this = this;
//隐藏的name
var data_value = $('input.selected-input').attr('data-value');
//下拉的ul中的模拟的option
var m_s_o = $('.simulateSelect-option');
//判断是否有值
//是为了页面初次渲染时页面初始化 => 包括给显示的赋值和设置选中
if (data_value) {
//截取形成数组
var data_v_arr = data_value.split(',');
var yiqi_arr=$(m_s_o).find('input');
for(var z=0;z<yiqi_arr.length;z++){
for(var x=0;x<data_v_arr.length;x++){
if($(yiqi_arr[z]).val()==data_v_arr[x]){
$($(yiqi_arr[z])).attr("checked", "checked");
_this.str.unshift($(yiqi_arr[z]).val());
_this.str_n.unshift($(yiqi_arr[z]).val());
}
}
}
//给显示字符串赋值拼接好的字符串
_this.setshowStr(_this.str);
//给隐藏的name字符串赋值拼接好的字符串
_this.sethiddenStr(_this.str_n);
_this.init();
} else {
_this.init();
}
}
};
moni.twoInit();
下载地址:
传送门