开发工具与关键技术:VS2015、JS、JQuery
作者:曾浩源
撰写时间:2019.3.28
无论是在前端或者后端,一些表单是必不可少的,有了表单,那么表单的样式也是五花八门。
一个精美的表单或许可以让你的页面焕然一新。
文本框、复选框、单选框、按钮等等都可以通过css样式从而去改变它,但唯独选择下拉框不可以。选择的下拉框是根据浏览器的样式而改变的,各个浏览器的选择下拉框样式也有差异,但也是默认的。
我们用css样式,只能改变回填框(select)样式和选择框(option)的字体、背景,
样式如下: 代码:
发现(option)的边框,边距等等都是无法改变的,那怎么办?
所以我就参考了layui的选择框和网上下载的一个选择框,都是利用js,新建div标签或者ul li标签存放选择框内容,最后再利用js将选择框的一些功能也能在新建的标签内实现。
下面是我参考完后自己制作的一个选择框:
主要改变的有:改变滚动条,鼠标划过伪类,右边小三角旋转,背景颜色透明和展开与收回效果(同时包含原有功能,disabled属性无法选择,selected属性选中回填)。
要制作一个选择框,当然首先写一个普通的选择框如下:
<select name="selects">
<option value="new">最新的</option>
<option value="unaudited" disabled="">未审核</option>
<option value="nothrough" selected="">未通过</option>
<option value="audit">正在审核</option>
<option value="测试1">测试1</option>
<option value="测试2">测试2</option>
<option value="测试3">测试3</option>
<option value="测试4">测试4</option>
<option value="测试5">测试5</option>
</select>
然后写一个新的“选择框”
里面装着(input)和一个(i)小图标:(input)设置只读和text类型
<div class="select_text">
<input class="select_title hiddeninput" type="text" readonly="">
<i class="select_icon"></i>
</div>
新建一个js文件,扩展 jQuery 元素集来提供新的方法
jQuery.fn.extend 利用该方法创建属于自己的插件 selectFrom 名字可以随意起
jQuery.fn.selectForm = function (options) {//接收
var defaults = {
callBack: function (res) { }
};
var ops = $.extend({}, defaults, options);//返回被扩展的对象。不修改defaults 的情况下添加 options内容
var selectList = $(this).find('select option');//根据传来 包括新旧选择框的div 获取它的option标签的内容 以数组的格式存储
var that = this;//声明变量that,作为局部变量
var html = '';//声明变量html 作为css样式
}
在旧下拉框和“新下拉框”外用一个div包括两个下拉框
然后在js文件里面,并且在创建插件的方法下面如下面的方法
$('.select_box0').selectForm({//传递
callBack: function (val) { }
});
传递接受后,就开始读取select标签的值,继续在创建插件的方法里,遍历select标签的值,放到各个
// 读取select 标签的值
html += '<ul class="select_list select_ul custom-scroll">';//新选择框的头
//新选择框的内容
$(selectList).each(function (idx, item) {//遍历所有选项,一一添加进新下拉框内
var val = $(item).val();//获取选项的值
var valText = $(item).html();//获取选项的html内容
var selected = $(item).attr('selected');//获取选项的selected属性
var disabled = $(item).attr('disabled');//获取选项的disabled属性
var isSelected = selected ? 'select_selected' : '';//利用三目运算判断selected是否为true 有值为true undefined为false
var isDisabled = disabled ? 'select_disabled' : '';//利用三目运算判断disabled是否为true 有值为true undefined为false
if (selected) {//判断该选项是否有selected属性 有就添加select_selected类
html += '<li class="' + isSelected + ' select_li" data-value="' + val + '"><a title="' + valText + '">' + valText + '</a></li>';
$(that).find('.select_title').val(valText);
} else if (disabled) {//判断该选项是否有disabled属性 有就添加select_disabled类
html += '<li class="' + isDisabled + ' select_li" data-value="' + val + '"><a>' + valText + '</a></li>';
} else {//没有就平常添加
html += '<li class="select_li" data-value="' + val + '"><a title="' + valText + '">' + valText + '</a></li>';
};
});
html += '</ul>';//新选择框的尾
$(that).append(html);//在大div里追加该新下拉框
$(that).find('select').hide();//而旧的下拉框则隐藏
这样就完成了最基本下拉框显示,当然还有一些样式,例如:
/*select*/
.my_MenuSelect{
display: inline-flex;
}
/*下拉框ul样式*/
.select_ul{
position: absolute;
background: rgba(6, 0, 255, 0.3);
width: 100px;
height:100px;
overflow-x:auto;
margin-left: -6px;
margin-top: 24px;
display:none;
border:0.1px solid transparent;
}
/*下拉框li样式*/
.select_li{
padding-top: 5px;
padding-left: 9px;
border:0.1px solid transparent;
}
/*下拉框鼠标hover伪类*/
.select_li:hover{
background: rgba(255, 255, 255, 0.3);
border:0.1px solid rgba(255, 255, 0, 0.2);
}
/*下拉框选项选中样式*/
.select_li.select_selected{
background: rgba(95, 184, 120, 0.4);
border:0.1px solid rgba(255, 255, 0, 0.2);
}
/*包括下拉框和图标的div样式*/
.select_text{
height:25px;
}
/*下拉框input样式*/
.hiddeninput{
width: 100%;
height: 25px;
line-height: 25px;
border: 0;
background-color: transparent;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0;
cursor: pointer;
margin-top: 0px;
margin-left: 3px;
text-shadow: 0px -1px 6px white, 0px -2px 20px yellow, 0px -5px 20px #ff8000, 0px -10px 40px red;
}
/*图标样式*/
.select_icon {
width: 8px;
height: 6px;
background-repeat: no-repeat;
background-image: url('../image/icon_arrow_down_x2.png');
opacity:0.4;
background-size: 100%;
right: -82px;
top: -24px;
position: relative;
transition: all .2s;
display: inline-block;
}
/*展开下拉框图标旋转样式*/
.select_icon_arrow {
-webkit-transform: rotate(-180deg);
transform: rotate(-180deg);
}
/*下拉框选项锁定样式*/
.select_disabled.select_li{
cursor: no-drop;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
还有下拉框的功能没完成呢,继续:
下面是选中的选项回填到“下拉框内”
首先是点击“新下拉框”选项下拉框展开,小图标旋转
//点击选择
$(that).on('click', '.select_text', function () {
$(that).find('.select_list').slideToggle(100);
$(that).find('.select_icon').toggleClass('select_icon_arrow');
});
然后就是选中选项,添加 选中类 并且回填数据到新旧下拉框
//点击选择列表
$(that).find('.select_list li').not('.select_disabled').on('click', function () {//当点击到没有disabled属性的选项时
var val = $(this).data('value');//获取该选项的值
var valText = $(this).find('a').html();//获取该选项下的a标签的html
$(that).find('.select_title').val(valText);//找到“新下拉框”的文本框,将获取到的valText赋值给它
$(that).find('.select_icon').toggleClass('select_icon_arrow');//图标旋转 toggleClass()对设置或移除被选元素的一个或多个类进行切换。
$(this).addClass('select_selected').siblings().removeClass('select_selected');//该选项添加 选中类 并遍历其同胞 删除选中类
$(this).parent().slideToggle(50);//收起选项框
for (var i = 0; i < selectList.length; i++) {//遍历循环 旧下拉框选项
var selectVal = selectList.eq(i).val();//获取每一个值 赋值给变量
if (val == selectVal) {//判断是否相等
$(that).find('select').val(val);//从该大div内找到select标签,赋值(也就是回填旧下拉框)
break;//跳出循环
};
};
ops.callBack(val); //返回值
});
到这里就完成了选中选项回填到新旧下拉框的功能,最后一步就是下拉框选项框的收起,点到下拉框以外是地方,下拉框将会收起。如下:
//其他元素被点击则收起选择
$(document).on('mousedown', function (e) {//鼠标按下事件
closeSelect(that, e);
});
到这里jQuery.fn.extend 利用该方法创建创建的方法结束
在外面新建一个方法 closeSelect(that,e);
function closeSelect(that, e) {
var selects = $(that).find('.select_list');//获取该大div里的“新下拉框”(用于收起选项框)
var selectsEl = $(that).find('.select_list')[0];//获取该大div里的“新下拉框”
var selectsBoxEl = $(that)[0];//获取该大div select_box?
var target = e.target;//获取鼠标点的地方 例如:点了html
//判断“新下拉框”是否等于html 和 “新下拉框”是否有 html的内容 和 该大div是否有 html的内容
if (selectsEl !== target && !$.contains(selectsEl, target) && !$.contains(selectsBoxEl, target)) {
if ($(that).parent().find('.select_list').css("display") == "block") {//判断“新下拉框是否展开”
selects.slideUp(50);//展开就选项框收起
$(that).children().find('.select_icon').toggleClass('select_icon_arrow');// 图标旋转
}
};
}
这样子就整个“新的下拉框”就完成了,但还不完美。如果有多个“新的下拉框”就会出现bug,所以要在传递的方法做一下改动,例如有两个:
Select_box0和select_box1就需要如下:
var select_boxs = $(".html").find(".my_MenuSelect");
for (var i = 0; i < select_boxs.length; i++) {
var classone = select_boxs[i].classList[0];
$('.' + classone).selectForm({//传递
callBack: function (val) { }
});
}
获取所有my_MenuSelect的类的,for循环遍历获取第一个类的名称然后复制给变量 classone,传递的函数参数化就可以了。