开发工具与关键技术: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,传递的函数参数化就可以了。