selectBox模拟select元素-插件

话说,前端的select选择框,现在被要求有更多的功能,首先一点就是可以输入,单纯的为了满足这一点,就差不多直接把select放入幕后了,为什么说是放入幕后,而不是放弃呢,因为我们可以使用input框和隐藏的select来模拟这个功能啊,既然说是模拟了,那么其实也可以完全模拟的嘛。

概述

基于jQuery的一个模拟下拉框的小插件,适用于使用jQuery的项目中,至于为什么不写一个原生的呢,主要原因还是懒~~兼容性问题,太恶心人~~

该方法被我命名为selectBox,使用的构造函数的模式。

支持属性

直接是使用方法的问题了,直接实例化即可,没有内容部处理忘记new


var selectBox = new extendjQ.selectBox(options);


options是一个对象,内部可以定义一些需要的属性,其中包含一些必须包含的属性,也有一些可以不包含的属性。

selectBox支持的属性如下:

描述 实例
obj 绑定该方法的对应的input输入框元素,该方法找到的元素必须唯一。
该元素中,可以包含data-name和data-value属性,如果需要自动生成隐藏的input框时,
使用这两个属性来初始化隐藏input的name值和value值,如果有隐藏input输入,则这两个值无效
hiddenInput 隐藏的input,用于保存选中的元素的value值。
src 下拉框的显示,是ul样式,其中的li的text文本为下拉框的内容展示,
li标签中data-value,当对应的li被选中时,会把该data-value保存到hiddenInput中的value属性中
type 获取值的方法,取值为”ajax”,当type值设置为”ajax”时,
下拉框src中li的值,就会在每次ajax动态获取。
url 只有在设置了type=”ajax”时,该属性才有效,ajax的目标地址
dataFn 在ajax提交时,可能是有额外数据的,所以通过dataFn的回调处理数据
该属性可以是一个function,返回一个字符串,
也可以使一段字符串,字符串的结构都是固定为:“name=name1&value=value1”
data 如果src没有设置,想要在selectBox的实例化时,自动生成,则可以通过设置data属性执行,结构为一个数组:[{name:"name1",value:"value1"},{name:"name2",value:"value2"}]
parentClass 容器框的class名称,即src的className,如果设置了该值,则使用该值,如果没有设置,则使用默认的样式,用于自定义自己的样式
childClass 容器src内部元素的class名称,即li的className名称
width 设置容器的宽度,如果是单纯的数字,则按照该倍数显示
默认值为1,表示,按照input输入框的宽度显示
px,其他只支持以像素为单位的宽度设置

实例化之后,虽然有一些方法,但是这些方法,对于我们都是无用的,所以这里也不做介绍

下面就看下使用方法:

demo示例

先看一个简单的demo示例吧:demo,一睹为快

关于样式结构

该方法的HTML结构,是需要一个固定的结构的,所以,如果您使用的该方法,那么就需要和该方法有相同的结构,结构如下

				
<input type = "text" class = "" id = "testSelectBox" name = "selectBox" />
<input type = "hidden" id = "selectBoxName" name = "selectBoxName" value = "4" />
<ul class = "selectBox" id = "selectBox">
	<li class = "selectBoxItem" data-value = "1">陆家嘴</li>
	<li class = "selectBoxItem" data-value = "2">人民广场</li>
	<li class = "selectBoxItem" data-value = "3">南京东路</li>
	<li class = "selectBoxItem" data-value = "4">南京西路</li>
	<li class = "selectBoxItem" data-value = "5">张江高科</li>
	<li class = "selectBoxItem" data-value = "6">世纪大道</li>
	<li class = "selectBoxItem" data-value = "7">世纪公园</li>
	<li class = "selectBoxItem" data-value = "8">金科路</li>
	<li class = "selectBoxItem" data-value = "9">张南路</li>
</ul>

	

其中:

第一input输入框,是用于输入内容和显示选中内容的部分。

第二个隐藏的输入框,用于保存选中的data-value值的,如果是直接输入的,则该隐藏inputvalue为空
ul元素,下拉列表的显示,必须包含内容显示部分和data-value的值

OK,这个现在没有什么问题,就来看下这个方法的基本使用方法吧。

最简单的基本使用

最基本的使用方法,就是我把所有需要的三个元素,都是页面上已有的,就如在上一个部分的结构中,已有了两个input和一个ul的下拉框,此时如果想要把该部分进行实例化,就可以如下:


var selectBox = new extendjQ.selectBox({
	obj:"#testSelectBox",
	hiddenInput:"#selectBoxName",
	src:"#selectBox"
});


这个时候,就可以直接使用了,有兴趣可以直接查看:demo

上面的JS代码中,obj代表的是输入input框,hiddenInput为隐藏的input框,src为下拉框,除了obj是必须的外,其他两者,如果提供其他的一些参数,是可以省略的,请查看下一小节中的内容。

在上面的基础上,如果我想要控制下拉框的宽度,那么就有一个问题了,为了能更好的展示下拉框,所以下拉框的宽度是会在实例化时,进行计算并且赋值,计算的宽度就是对应的input的宽度,所以,如果你想要控制下拉框的宽度,就需要在实例化时,进行传入width属性,比如实例化时:


var selectBox = new extendjQ.selectBox({
	obj:"#testSelectBox",
	hiddenInput:"#selectBoxName",
	src:"#selectBox",
	width:2
	//此时,下拉框的宽度,是obj输入框宽度的2倍
});


var selectBox = new extendjQ.selectBox({
	obj:"#testSelectBox",
	hiddenInput:"#selectBoxName",
	src:"#selectBox",
	width:"300px"
	//此时,下拉框的宽度,就是300px
});


可以查看对应的demo2倍款demo像素款demo

懒人方法

即,该方法你只需要传入一个obj的属性即可,同时页面中,也不需要包含隐藏的inputul的下拉框。

所以,这个时候,结构只需要如下结构即可:

	
<input type = "text" class = "" id = "testSelectBox" name = "selectBox"
 data-name = "selectBoxName" data-value = "4"/>
<input type = "button" id = "apply" value = "Init" style = "margin-left:10px;"/>


其中,id="apply"button按钮,是为了更好的模拟,当点击该按钮之后,才会初始化该模拟的下拉框。

并且,注意在id = "testSelectBox"input元素中,有data-namedata-value的属性,这两个属性,是用于创建隐藏的input元素时,隐藏input元素的name值和初始value值,用于初始化。

此时的JS代码可以如下的初始化:

				
$("#apply").on("click",function(){
	var selectBox = new extendjQ.selectBox({
		obj:"#testSelectBox",
		data:[
		  {name:"陆家嘴",value:"1"},
		  {name:"人民广场",value:"2"},
		  {name:"南京东路",value:"3"},
		  {name:"南京西路",value:"4"},
		  {name:"张江高科",value:"5"},
		  {name:"世纪大道",value:"6"},
		  {name:"世纪公园",value:"7"},
		  {name:"金科路",value:"8"},
		  {name:"张南路",value:"9"}
		]
	});
});

				
			

demo查看地址:demo

当然,这个时候,你也可以传入一个width的属性,来控制下拉框的宽度显示。

如上代码可以看出,此时最简单的方法,就是在初始化时,只要objdata属性。obj的含义在前面的实例中已经说明,这里多出的data属性,下拉框的信息,name为页面展示内容,value为隐藏的内容,也就是最后显示在隐藏input中的值。

关于input输入框,隐藏的input元素,下拉框元素,这三者可以随意组合的,只要注意配合一些信息即可。不多说了。

如果细心的人,可以能在源代码中看到,如果只是要obj的话,那么下拉框的样式,是写在标签内部的,所以,为了能自己控制下拉框的样式,提供了另外的两个参数:

				
$("#apply").on("click",function(){
	var selectBox = new extendjQ.selectBox({
		obj:"#testSelectBox",
		data:[
		  {name:"陆家嘴",value:"1"},
		  {name:"人民广场",value:"2"},
		  {name:"南京东路",value:"3"},
		  {name:"南京西路",value:"4"},
		  {name:"张江高科",value:"5"},
		  {name:"世纪大道",value:"6"},
		  {name:"世纪公园",value:"7"},
		  {name:"金科路",value:"8"},
		  {name:"张南路",value:"9"}
		],
		parentClass:"selectBox",
		childClass:"selectBoxItem"
	});
});

				
			

如上代码,只要传入parentClasschildClass定义的class值,那么就可以使用自定义的class了。通过定义这两个CSS,可以使下拉框按照自己想要的方式显示。

使用自定义class的的demo查看地址:demo

ajax的获取方法

因为呢,有时候下拉框的内容,是需要ajax动态获取的,所以这里也可以在实例化时,把这个selectBox定义成ajax获取下拉框内容的。

关于ajax获取下拉框内容时,和上面下拉框内容固定两种方式,他们的差距就是,如果是下拉框固定的,那么在input输入框内容改变时,会动态的显示和隐藏下拉框的一些选项,以匹配输入框内输入的内容。而ajax获取的时候,当input框改变时,会把新获取的内容,重新写入下拉框。

ajax类的selectBox定义时,有两个非常重要的属性就是typeurldataFn这三个属性,如果想要设置为ajaxselectBox,那么首先要设置的是type="ajax",然后就是必须包含url属性,即必须有ajax的请求地址,至于dataFn的值,是可有可无的。

dataFn属性的存在是因为,有些ajax请求需要根据页面获取一些动态的属性,所以,dataFn可是一个function,该函数会返回一个"name=name1&value=value1"格式的字符串。

看下面的示例:

				
var testOther = $("#testOther");
$("#apply").on("click",function(){
	var obj = $("#testSelectBox");
	var selectBox = new extendjQ.selectBox({
		obj:obj,
		data:[
		  {name:"陆家嘴",value:"1"},
		  {name:"人民广场",value:"2"},
		  {name:"南京东路",value:"3"},
		  {name:"南京西路",value:"4"},
		  {name:"张江高科",value:"5"},
		  {name:"世纪大道",value:"6"},
		  {name:"世纪公园",value:"7"},
		  {name:"金科路",value:"8"},
		  {name:"张南路",value:"9"}
		],
		parentClass:"selectBox",
		childClass:"selectBoxItem",
		type:"ajax",
		url:obj.attr("data-url"),
		dataFn:function(){
			return testOther.attr("name")+"="+testOther.val();
		}
	});
});

				
			

可以查看demo示例:demo

OK,其实selectBox插件也是一个很简单的东西了,这个插件中,也尽量的在更好的模仿原生的select元素,比如上下键选择,回车选中等,有兴趣的,可以自己测试。

结束

没有什么结束语,写这个东西,也是因为顺便吧,正好要用到,所以平时就自己写了一个,然后加到项目中去了。

当然这里还是有些缺点的,比如,这里需要给每一个selectBox进行实例化,而不是根据结构,可以对一批selecBox进行的实例化,所以~~~有兴趣的可以自由修改吧,我觉得这样写应该有更好的可控性吧。

本文地址: http://www.zhangyunling.com/?p=276

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>