模仿下拉框datalist的jquery插件的一点小经验

时间:2024-01-01 14:24:57

原本项目里是用h5的新属性data-list,但是这个下拉框的数据太多,而data-list似乎没有设置高度的地方,所以写了个小插件,期间也发现了一些bug,目前这个版本算是可以一用的版本,故写一下这个插件碰到的奇怪问题。

一点简单的CSS(因为项目原因,暂时只写了webkit内核)。

.datalist_ul {
background: #fff;
display: none;
list-style: none;
padding: 0;
margin: 0;
overflow: auto;
position: absolute;
} .datalist_ul .datalist_li {
background: transparent;
color: #000;
padding: 0.5em 0.5em;
text-align: left;
font-size: 1.2em;
border-bottom: 0.1em dashed cornflowerblue;
box-sizing: border-box;
} .datalist_ul .datalist_li_hover {
background: rgba(100, 149, 237,0.8);
color: #fff;
} .detalist_ul .datalist_li_hide {
display: none;
} body {
margin: 0;
padding: 0;
} input {
height: 2em;
padding:0 0.5em;
box-sizing: border-box;
width:180px;
} ::-webkit-scrollbar {
width: 0.5em;
}
/*
::-webkit-scrollbar-button{
height:0.5em;
width:0.5em;
background:#ccc;
}*/ ::-webkit-scrollbar:horizontal {
height: 0.2em;
} ::-webkit-scrollbar-track {
-webkit-border-radius: 10px;
border-radius: 10px;
} ::-webkit-scrollbar-thumb {
-webkit-border-radius: 10px;
border-radius: 10px;
background: rgba(255, 0, 0, 0.6);
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
} ::-webkit-scrollbar-thumb:window-inactive {
background: rgba(169, 169, 169, 0.4);
}

js代码

(function ($) {
$.fn.extend({
datalist: function (options, func) {
var ul, cur, count = 0, css, hover, visible, scroll;
$(".datalist_li").hover(
function () {
$(".datalist_li").removeClass("datalist_li_hover");
$(this).addClass("datalist_li_hover");
count = $(this).index();
}, function () {
$(this).removeClass("datalist_li_hover");
}
);
$("[data-list]").on({
"click focus": function () {
cur = $(this);
ul = $("[data-list-id='" + cur.attr("id") + "']").eq(0);
console.log(ul);
if (!!ul) {
css = {
"top": cur.css("height"),
"left": cur.position().left + "px",
"display": "block",
"width": cur.css("width")
};
!!options && (css = $.extend(css, options));
//ul.show().css(css);
for (var i in css) {
ul[0].style[i] = css[i];
}
}
},
"keyup": function (e) {
ul.show();
hover = ul.find(".datalist_li_hover");
visible = ul.find(".datalist_li:visible");
switch (e.keyCode) {
case 13:
if (hover.length > 0) {
cur.val(hover.text());
ul.hide().find(".datalist_li").removeClass("datalist_li_hover");
}
!!func && func();
break;
case 38:
if (hover.index() == 0) {
count = visible.length;
}
if (hover.length > 0) {
count--;
visible.removeClass("datalist_li_hover");
visible.eq(count).addClass("datalist_li_hover");
} else {
count = visible.length - 1;
visible.eq(count).addClass("datalist_li_hover");
}
break;
case 40:
if (count == visible.length - 1) {
count = -1;
}
if (hover.length > 0) {
count++;
visible.removeClass("datalist_li_hover");
visible.eq(count).addClass("datalist_li_hover");
} else {
count = 0;
visible.eq(0).addClass("datalist_li_hover");
}
break;
default:
ul.find(".datalist_li").hide().removeClass("datalist_li_hover").each(function () {
if ($(this).text().indexOf(cur.val()) >= 0 || $(this).text() == cur.val()) {
$(this).show();
}
});
}
},
"blur": function () {
hover = ul.find(".datalist_li_hover");
if (hover.length != 0) {
cur.val(hover.text());
cur.attr("value", hover.text());
ul.find(".datalist_li").each(function () {
$(this).removeClass("datalist_li_hover");
});
ul.hide();
count = 0;
!!func && func(hover);
} else {
ul.hide();
}
}
});
}
})
})(jQuery);

总体来说代码难度不大,碰到最奇怪的问题就是 //ul.show().css(css);这一行被注释的代码,原本也是用这一行代码的,但是在项目里碰到这样一个问题,页面第一次加载页面时,这一行代码是不会报错的,选择完之后提交数据,后台java render一个新页面把body内容替换(也把datalist替换了),再次给这个框绑定data-list方法,然后点击这个datalist框时这一句话就报了cannot read property ' style' of undefined,我之前怀疑这不是一个jquery对象,但是用$()把ul包起来也不行,而且console.log时它确实是一个jquery对象,而且length也为1并没用重复的对象,但是jquery内部似乎就是识别不了,亦或者这个对象和真正的jquery对象有区别?反正最后换成了原生JS才可以解决,各位大神如果有解决方法或是知道问题原因请务必在评论下方指导小弟一二。

html代码 调用代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="css/datalist.css">
<script src="js/jquery1.8.js"></script>
<script src="js/datalist.js"></script>
<script type="text/javascript">
$(function () {
$('[data-list-id="datalist"]').datalist({
"max-height": "15em"
}, function () {
console.log("callback function");
});
});
</script>
</head>
<body>
<div>
<label for="datalist">select url</label>
<input id="datalist" type="text" data-list>
<ul class="datalist_ul" data-list-id="datalist">
<li class="datalist_li">google</li>
<li class="datalist_li">facebook</li>
<li class="datalist_li">twitch</li>
<li class="datalist_li">baidu</li>
<li class="datalist_li">youtube</li>
<li class="datalist_li">twitter</li>
</ul>
</div>
</body>
</html>