您的位置:首页 > Web前端 > JQuery

自定义带搜索框的下拉列表插件

2017-01-12 16:04 309 查看
最近项目所需,开发了一个附带搜索框的下拉列表插件,在搜索框中输入关键字的同时,捕捉键盘按键释放事件,更新下拉列表显示内容。

jquery插件开发参考:

http://blog.csdn.net/xyr05288/article/details/51094644

一. 插件源文件

css源文件:

.my-dropdownContainer{
position: relative;
height: 30px;
width: 200px;
background: #fff;
/* z-index:20; */
}
.my-dropdownDefault{
border:1px solid #ddd;
line-height: 28px;
text-indent: 0.5em;
border-radius:5px;
}
.my-dropdown-menu-div{
position: absolute;
top:100%;
/*width: 100%;*/
width:250px;
left: 0;
display:none;
border:1px solid #ddd;
border-radius:5px;
padding:5px;
background: #fff;
overflow: auto;
/*height: 150px;*/
max-height:150px;

z-index:20;

}
.my-dropdown-menu{
padding-left:0px;
background: #fff;
margin-top:5px;
}
.my-dropdown-menu li{
/*line-height: 24px;*/
list-style:none;
}

.my-dropdown-menu li div.li-div-class:hover{
background-color: #0078b6;
color: #fff;
}
/* .hoverClass div{
background-color: #0078b6;
color: #fff;
} */
.arrow{
width: 0;
height: 0;
display: inline-block;
cursor: pointer;
}
.downArrow{
position: absolute;
right: 5px;
top: 10px;
border-left: 3.5px solid transparent;
border-right: 3.5px solid transparent;
border-top: 7px solid #555;
}
.upArrow{
position: absolute;
right: 5px;
top: 10px;
border-left: 3.5px solid transparent;
border-right: 3.5px solid transparent;
border-bottom: 7px solid #555;
}

.li-div-class{
position: relative;
height:45px;
}

.user-image-class{
position: absolute;
left: 2px;
top: 5px;
height: 30px;
width: 30px;
}

.user-image-class img{
height: 30px;
width: 30px;
}
.user-name-class{
position: absolute;
left: 38px;
top: 5px;
font-size: 12px;
}
.user-depart-class{
position: absolute;
left: 38px;
top: 20px;
font-size: 12px;
/*div只显示一行*/
width:80%;
text-overflow: ellipsis;
white-space: nowrap;
overflow:hidden;
}


js源文件:

//20170111 自定义下拉列表插件
//20160406 构造对象
var defaultOptions  = {
listData: [], //直接设置原始数据
url:"",//通过url动态获取数据
keyword:"" //url只接受keyword参数
};

var $options = defaultOptions;

$.fn.customeDownList = function(){
var options = {};
if(arguments.length == 1){//一个参数
if(typeof(arguments[0]) == 'object'){//初始化options
initDownList(this[0],arguments[0]);
}
}else if(arguments.length == 2){
if(typeof(arguments[0]) == 'string' && typeof(arguments[1]) == 'object'){//调用方法
if(arguments[0] == 'setData'){
var ulObj = this.find('.my-dropdown-menu-div').find('.my-dropdown-menu').get(0);
setData(ulObj,arguments[1]);
}
}
}

};

function initDownList(obj,options){
//这里其实就是合并多个对象为一个。这里就是,如果你在调用的时候写了新的参数,就用你新的参数,如果没有写,就用默认的参数。
$options = $.extend(defaultOptions,options);
console.log(obj);

var dataStr = "";
var listData = $options.listData;
var url = $options.url;
if(url != ""){
var keyword = $options.keyword;
listData = getListDataByUrl(url,keyword);
}
if(listData != undefined && listData.length>0){
for(var i=0; i<listData.length; i++){
dataStr += '<li><div class="li-div-class">'+'<div class="user-image-class"><img src = "'+ listData[i].image  + '"/></div>'
+ '<div class="user-name-class">'+ listData[i].name + '</div>'
+ '<div class="user-depart-class" ' + 'title=' + listData[i].depart + '>'
+ listData[i].depart + '</div>'
+ '</div></li>';
}
}

//插件中动态添加的DOM元素统统用类标识  不要用ID 元素之间的获取借助DOM树结构
var htmlStr = "";
htmlStr += '<div class="my-dropdownContainer">';
htmlStr += '<div class="my-dropdownDefault"></div>';
htmlStr += '<span class="downArrow arrow"></span>';
htmlStr += '<div class="my-dropdown-menu-div">';
//下拉列表输入框的键盘释放事件
htmlStr += '<input onkeyup="javascript:onkeyupInput(this);" type="text" style="width:100%;height:27px;border:1px solid #ddd;border-radius:5px;" />';
htmlStr += '<ul class="my-dropdown-menu">';
htmlStr += dataStr;
htmlStr += '</ul>';
htmlStr += '</div>';
htmlStr += '</div>';

obj.innerHTML = htmlStr;

//箭头的点击事件
$(".my-dropdownContainer .arrow").unbind("click").click(function(){
console.log("click obj parent parent: ");
console.log($(this).parent().parent());
if($(this).hasClass("downArrow")){
$(this).siblings(".my-dropdown-menu-div").show();

//清空输入框 重新初始化下拉列表
var inputObj = $(this).siblings(".my-dropdown-menu-div").find('input').get(0);
inputObj.value = "";
onkeyupInput(inputObj);

$(this).removeClass("downArrow");
$(this).addClass("upArrow");
}else if($(this).hasClass("upArrow")){
$(this).siblings(".my-dropdown-menu-div").hide();
$(this).removeClass("upArrow");
$(this).addClass("downArrow");
}
});

//列表项的点击事件
$(".my-dropdown-menu li .li-div-class").unbind("click").click(function(){
var $nameObj = $(this).find('.user-name-class');
$(this).parent().parent().parent().siblings(".my-dropdownDefault").html($nameObj.html());
$(this).parent().parent().parent().hide();

var arrowObj = $(this).parent().parent().parent().siblings(".arrow");
if(arrowObj.hasClass("upArrow")){
arrowObj.siblings(".my-dropdown-menu-div").hide();
arrowObj.removeClass("upArrow");
arrowObj.addClass("downArrow");
}
});

}

function setData(ulObj, data){
//将选择的值重新拼接为html字符串  添加在ul中
var htmlStr = "";
for(var i=0; i<data.length; i++){
htmlStr += '<li><div class="li-div-class">'+'<div class="user-image-class"><img src = "'+ data[i].image  + '"/></div>'
+ '<div class="user-name-class">'+ data[i].name   + '</div>'
+ '<div class="user-depart-class" ' + 'title=' + data[i].depart + '>'
+ data[i].depart + '</div>'
+ '</div></li>';
}

ulObj.innerHTML = htmlStr;

/*$(".li-div-class").mouseover(function(){

if(!$(this).hasClass("hoverClass")){
$(this).addClass("hoverClass");
}
});
$(".li-div-class").mouseout(function(){

if($(this).hasClass("hoverClass")){
$(this).removeClass("hoverClass");
}
});*/
//动态生成的DOM元素click事件需重新绑定
$(".my-dropdown-menu li .li-div-class").unbind("click").click(function(){

var $nameObj = $(this).find('.user-name-class');
$(this).parent().parent().parent().siblings(".my-dropdownDefault").html($nameObj.html());
$(this).parent().parent().parent().hide();

var arrowObj = $(this).parent().parent().parent().siblings(".arrow");
if(arrowObj.hasClass("upArrow")){
arrowObj.siblings(".my-dropdown-menu-div").hide();
arrowObj.removeClass("upArrow");
arrowObj.addClass("downArrow");
}
});
}

//必须定义到外面 定义到闭包函数里面时  无法获取
function onkeyupInput(obj){
var value = obj.value;
console.log("value: " + value);
var ulObj = $(obj).siblings(".my-dropdown-menu").get(0);//jquery对象转DOM对象
console.log(ulObj);
var liElementArr = ulObj.getElementsByTagName("li");
console.log("liElementArr: " + liElementArr.length);

var newValues = [];
var url = $options.url;

if(url == ""){
var listData = $options.listData;
$.each(listData,function(index,tempValue){

if(tempValue.indexOf(value) >= 0){
newValues.push(tempValue);
}
});
}else{
keyword = value;
newValues = getListDataByUrl(url,keyword);
}

console.log("newValues: ");
console.log(newValues);

//将选择的值重新拼接为html字符串  添加在ul中
setData(ulObj,newValues);
}

function getListDataByUrl(url,keyword){
var listData = [];
$.ajax({
async: false,//同步
type:"POST",
url:url,
dataType:"json",
data:{
"keyword":keyword
},
error:function(){
alert("列表数据获取失败");
},
success:function(responseInfo){

if(responseInfo['status'] == 1){
alert("列表数据获取失败");
}
if(responseInfo["status"] == 0){
console.log(responseInfo.data);
listData = responseInfo.data.listData;

}
}//end success
});

return listData;
}


html中调用形式:

<!-- html -->
<div id="downListDIV">
</div>
<script text/type="javascript">
$("#downListDIV").customeDownList({url:'/common/getUserListData'});
</script>


获取选择数据:

var value = $("#downListDIV").find('.my-dropdownDefault').html();


二. 所遇问题

(1)在页面中增加了两个下拉列表组件时,点击第一个组件右边的箭头时,onclick事件会被触发两次,导致下拉列表选项内容无法显示出来。

原因:Click事件 进行了累加绑定,每当我调用一次时,他便增加一次绑定

解决方法: 每次绑定前先解绑

$('#sub').unbind('click').click(function () {
...
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jquery 插件