以下是 jQuery自定义下拉框js代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>jQuery自定义下拉框</title>
<link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="css/jquery.customSelect.css" />
</head>
<body>
<div id="container">
<h2 style="margin-bottom: 0">Examples</h2>
<div class="example-container">
<h2>A custom-range select</h2>
<select id="rangeSelect">
<option value="1p">1+ bedrooms</option>
<option value="2p">2+ bedrooms</option>
<option value="3p">3+ bedrooms</option>
</select> </div>
<div class="example-container">
<h2>A standard select</h2>
<select id="singleSelect">
<option value="cola">A glass of cola</option>
<option selected value="lemonade">A class of lemonade</option>
<option value="tea">A cup of tea</option>
</select> </div>
<div class="example-container">
<h2>A multi select</h2>
<select id="multipleSelect" multiple>
<option value="cake">A tasty cake</option>
<option value="burger">A fatty burger</option>
<option value="cola">A large cola</option>
</select> </div>
<pre id="debug_log">Loading...</pre>
</div>
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="js/jquery.customSelect.js"></script>
<script>
$(document).ready(function () {
$('#debug_log').html('Debug log...<br>');
function debug(what) {
$('#debug_log').append(what + "<br>");
}
$('#singleSelect, #multipleSelect').customSelect({
focus: function () {
debug('Got focus');
},
blur: function () {
debug('Lost focus');
},
change: function () {
debug('Widget value changed');
}
});
$('#rangeSelect').customSelect({
customRange: true,
windowFormatter: function (value) {
if (value.indexOf('bedrooms') === -1) {
value += ' bedrooms';
}
return value.replace(/bedrooms/, '<strong>bedrooms</strong>');
}
});
$('select').change(function () {
debug('Native select value changed to: ' + $(this).val());
});
});
</script>
</body>
</html>
JS代码(jquery.customSelect.js):
/*! customSelect:a jQuery UI widget to select items and ranges http://github.com/rixth/customSelect*/
/*jshint browser:true,jquery:true,indent:2,white:true,curly:true,forin:true,noarg:true,immed:true,newcap:true,noempty:true */
(function ($){
var openClass = 'ui-customSelect-open',disabledClass = 'ui-customRange-disabled',eventPrefix = 'customselect',createCustomRange,createCustomValue;
$.widget("ui.customSelect",{
options:{
placeholder:'Please select some items',defaultValue:null,customRange:false,customValue:false,customValuePlaceholder:'custom value',customRanges:null,windowFormatter:function (value){
return value;
}
,customRangeHelper:function (min,max){
var value,display;
if (min && max){
value = min + '-' + max;
display = min == max ? min:(min + ' to ' + max);
}
else if (min && !max){
value = min + 'p';
display = min + '+';
}
else if (!min && max){
value = '0-' + max;
display = '0 to ' + max;
}
return [value,display];
}
,reverseRangeHelper:function (string){
if (string.match(/^\d+-\d+$/)){
return string.split('-');
}
else if (string.match(/^\d+p$/)){
return [string.match(/^(\d+)p$/)[1],''];
}
}
}
,_create:function (){
var self = this,options = self.options,defaultValue = options.defaultValue,select = this.element,root,rootHtml,isOpen = false;
if (!select.is('select')){
throw new TypeError("jquery.customSelect expects a <select> element.");
}
self.userCustomValue = null;
self.rootId = select.attr('id') + '_customSelect';
// Create the base HTML,the window and dropdown rootHtml = [ '<div class="ui-customSelect">',' <div class="ui-customSelect-window"><span></span>',' <div class="ui-customSelect-arrow ui-customSelect-downArrow">▼
</div>',' <div class="ui-customSelect-arrow ui-customSelect-upArrow">▲
</div>',' </div>',' <div class="ui-customSelect-dropdown"><ul></ul></div>','</div>' ];
// Place ourselves this.root = root = $(rootHtml.join('')).attr('id',self.rootId);
select.after(root).hide();
this.window = root.find('.ui-customSelect-window span');
this.list = root.find('ul');
self._createFromSelect();
self._setWindowText();
// Bind events self.window.parent().click(function (event){
self._trigger(isOpen ? 'blur':'focus',event);
}
);
root.delegate('li>input','change',function (event){
self.userCustomValue = null;
self._setWindowText();
select.val(self.getVal()).trigger('change');
self._trigger('change',event,{
element:this,value:this.value}
);
$('.ui-customSelect-rangeContainer input,.ui-customSelect-customValue').val('');
$('.ui-customSelect-error').hide();
self.userCustomValue = null;
}
);
select.on(eventPrefix + 'focus',function (){
if (!root.hasClass(disabledClass)){
isOpen = true;
root.addClass(openClass);
// Close when a click is detected on something other than the widget $(document).on('click.customRange' + self.rootId,function (event){
if (!$.contains(root[0],event.target)){
self._trigger('blur');
}
}
);
}
}
).on(eventPrefix + 'blur',function (){
$(document).off('click.customRange' + self.rootId);
isOpen = false;
root.removeClass(openClass);
}
).on(eventPrefix + 'disabled',function (){
root.addClass(disabledClass);
if (isOpen){
self._trigger('blur');
}
}
).on(eventPrefix + 'enabled',function (){
root.removeClass(disabledClass);
}
);
if (self.isMultiple && defaultValue){
function setDefaultItem(){
if (!self.getVal().length){
self.list.find('input[value=' + defaultValue + ']').attr('checked',true).change();
}
}
;
select.on(eventPrefix + 'change',setDefaultItem);
setDefaultItem();
}
if (!self.isMultiple && (options.customRange || options.customValue)){
self.setCustomValueError = function (error){
root.find('.ui-customSelect-error').show().html(error);
}
;
if (options.customRange){
createCustomRange.call(self,root,this.list,options);
}
else if (options.customValue){
createCustomValue.call(self,root,this.list,options);
}
}
}
,setVal:function (value){
var existingOption = this.element.find('option[value=' + value + ']'),customRange;
if (existingOption.length && !existingOption[0].attributes['data-custom']){
this.element.val(value);
this.reload();
this._setWindowText();
}
else{
if (this.options.customRange){
customRange = this.options.reverseRangeHelper(value);
this.root.find('.ui-customSelect-min').val(customRange[0]);
this.root.find('.ui-customSelect-max').val(customRange[1]);
setCustomUIValues.call(this,null,customRange);
}
else if (this.options.customValue){
this.root.find('.ui-customSelect-customValue').val(value);
setCustomUIValues.call(this,null,value);
}
}
}
,getVal:function (){
if (this.userCustomValue !== null){
return this.userCustomValue;
}
var result = this.root.find('li>input:checked').map(function (){
return this.value;
}
).toArray();
return result.length ? result[this.isMultiple ? 'slice':'pop']():(this.isMultiple ? []:null);
}
,friendlyVal:function (){
return this.root.find('input:checked+label').map(function (){
return this.innerHTML;
}
).toArray();
}
,_setWindowText:function (windowValue){
var value;
if (!windowValue){
value = this.friendlyVal();
windowValue = value.length ? value.join(','):this.options.placeholder;
}
this.window.html(this.options.windowFormatter(windowValue));
}
,_createFromSelect:function (){
var self = this,idCounter = 0,list = self.list,insertionPoint = list.prev()[0] || list.parent();
self.isMultiple = self.element.attr('multiple');
list.empty();
this.element.children().each(function (){
var element = this,id = self.rootId + '_' + (idCounter++),label = '<label for="' + id + '">' + element.innerHTML + '</label>',input;
if (self.isMultiple){
input = $('<input id="' + id + '" type="checkbox" value="' + element.value + '">');
}
else{
input = $('<input id="' + id + '" name="' + self.rootId + '_radio" type="radio" value="' + element.value + '">');
}
list.append($('<li></li>').append(input).append(' ').append(label));
// For some reason,this needs to happen after appending,otherwise // IE7 appears to "forget" the checked flag. if (element.selected){
input.attr('checked',true);
}
}
);
}
,reload:function (){
// Remove all custom options this.element.find('option[data-custom]').remove();
this.root.find("input[type='text']").val('').blur();
this.userCustomValue = null;
this._createFromSelect();
}
,_setOption:function (name,value){
if (name === 'disabled'){
this._trigger((value ? 'dis':'en') + 'abled');
}
}
,destroy:function (){
$.Widget.prototype.destroy.apply(this,arguments);
$(document).off('click.customRange' + this.rootId);
this.root.remove();
this.element.show();
}
}
);
function setCustomUIValues(event,value){
var self = this,temp,displayValue,dataValue,option;
if (self.options.customRange){
temp = self.options.customRangeHelper(value[0],value[1]);
dataValue = temp[0];
displayValue = temp[1];
}
else{
dataValue = displayValue = value;
}
self._setWindowText(displayValue);
self.userCustomValue = dataValue;
option = $('<option data-custom="true" value="' + dataValue + '">' + displayValue + '</option>');
self.element.find('option[data-custom]').remove();
self.element.append(option.attr('selected',true)).trigger('change',event);
self._trigger('change',event);
self.root.find('input:checked').attr('checked',false);
}
createCustomValue = function (root,list,options){
var self = this,optionValue = options.customValue,input;
list.before($([ '<div class="ui-customSelect-customValueContainer">',' <input class="ui-customSelect-customValue" type="text" placeholder="' + options.customValuePlaceholder + '" />',' <div style="display:none" class="ui-customSelect-error"></div>','</div>' ].join('')));
input = root.find('.ui-customSelect-customValue');
function customValueHandler(event){
var value = input.val();
if (self._trigger('customvaluechange',event,{
value:value,widget:self}
)){
$('.ui-customSelect-error').hide();
setCustomUIValues.call(self,event,value);
self._trigger('blur');
}
}
if (typeof(optionValue) === 'string' || typeof(optionValue) === 'number'){
input.val(optionValue);
customValueHandler();
}
input.keydown(function (event){
if (event.which === 13){
customValueHandler(event);
}
}
);
}
;
createCustomRange = function (root,list,options){
var customRangeHtml,errorDiv,minInput,maxInput,self = this;
customRangeHtml = [ '<div class="ui-customSelect-rangeContainer">',' <input type="text" class="ui-customSelect-min" placeholder="min" /> to
<input type="text" class="ui-customSelect-max" placeholder="max" />',' <div style="display:none" class="ui-customSelect-error"></div>','</div>' ];
list.after($(customRangeHtml.join('')));
minInput = root.find('.ui-customSelect-min');
maxInput = root.find('.ui-customSelect-max');
errorDiv = root;
function customRangeHandler(event){
var min = minInput.val(),max = maxInput.val(),rangeChangeData ={
min:min,max:max,widget:self}
,formattingResult,option;
if (isNaN(min) || isNaN(max)){
self.setCustomValueError("Please enter only numbers.");
}
else{
if (min && max && min > max){
self.setCustomValueError("Min cannot be bigger than max.");
}
else{
if (self._trigger('rangechange',event,rangeChangeData)){
$('.ui-customSelect-error').hide();
setCustomUIValues.call(self,event,[min,max]);
self._trigger('blur');
}
}
}
}
if (options.customRanges){
minInput.val(options.customRanges.min);
maxInput.val(options.customRanges.max);
customRangeHandler();
}
minInput.add(maxInput).keydown(function (event){
if (event.which === 13){
customRangeHandler(event);
}
}
);
}
;
}
(jQuery));
CSS代码(jquery.customSelect.css):
/*! customSelect:a jQuery UI widget to select items and ranges http://github.com/rixth/customSelect*/
.ui-customSelect{border:1px solid #ccc;position:relative;box-shadow:0px 0px 3px rgba(0,0,0,0.1);background:white;-moz-user-select:none;-webkit-user-select:none;}
.ui-customSelect-window{height:1.9em;cursor:pointer;}
.ui-customSelect-window span{display:block;float:left;margin:0.45em 0 0 0.5em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:88%;}
.ui-customSelect-arrow{float:right;color:#555;width:10px;margin:.35em .5em 0 0;}
.ui-customSelect-upArrow{display:none;}
.ui-customSelect-open .ui-customSelect-downArrow{display:none;}
.ui-customSelect-open .ui-customSelect-upArrow{display:block;}
.ui-customSelect-dropdown{background:white;position:absolute;border:1px solid #ccc;width:100%;margin:0 -1px;box-shadow:0px 0px 3px rgba(0,0,0,0.1);display:none;z-index:1000;}
.ui-customSelect-open .ui-customSelect-dropdown{display:block;}
.ui-customSelect-dropdown input{vertical-align:middle;display:inline-block;margin:0 3px 0 0;}
.ui-customSelect-dropdown ul{list-style:none;padding:0;margin:5px 0;}
.ui-customSelect-dropdown ul li{line-height:1.1em;padding:0.3em;}
.ui-customSelect-rangeContainer,.ui-customSelect-customValueContainer{background:#ECE9E9;padding:5px;text-align:center;border-top:1px solid #ccc;}
.ui-customSelect-customValueContainer{border-top:none;border-bottom:1px solid #ccc;}
.ui-customSelect-rangeContainer input,.ui-customSelect-customValueContainer input{border:1px solid #ccc;display:inline-block;vertical-align:middle;text-align:left;}
.ui-customSelect-rangeContainer input{width:39%;}
.ui-customSelect-customValueContainer input{width:95%;}
.ui-customSelect-error{color:#900;text-align:left;margin-top:5px;}
CSS代码(style.css):
body{font-family:"Helvetica Neue","Lucida Grande","Arial";background:#F8F8F8;background:#ECE9E9 -webkit-gradient(linear,0% 0%,0% 100%,from(#fff),to(#ECE9E9)) no-repeat;background:#ECE9E9 -moz-linear-gradient(top,#fff,#ECE9E9) no-repeat;color:#555;margin:0;text-align:justify;-webkit-text-stroke:1px rgba(255,255,255,0.1);}
#container{margin:0 auto;width:730px;}
h1{font-size:3.8em;color:#121621;margin-bottom:3px;text-shadow:1px 1px 0px #ccc;}
h1 a{color:#121621;text-decoration:none;}
h2{font-size:1.35em;color:#3a8e11;}
a{color:#3a8e11;}
.example-container{width:190px;margin:0 20px 20px 20px;float:left;font-size:12px;}
.download{float:right;}
pre{background:#000;color:#fff;padding:15px;}
.footer{text-align:center;padding-top:10px;font-style:italic;color:#888;}
#debug_log{clear:both;}