项目需要使用类似comboBox的web控件.如今现存的相关控件非常好.而且参差不齐.extjs等大型控件有一定的实现.但是如果为了一个控件而依赖extjs等大型前端js是非常不好的.为此花了2天在前人的基础上写了一个龊劣的可以编辑并自动提示过滤的select控件.和大家共同探讨.
附件有完整的demo和源码.
在HTML页面中需要使用DIV里面依次嵌套input和select.
<div id='netdbzonesDiv' style="float:left;" class="ctrlHeight">
<input id="netdbzonesInput" name="netdbzonesInput" type="text" class="ufo-conbobox-input box_shadow" />
<select name="zones" id="netdbzonesSelect" class="ufo-combobox-select">
<option value="1">aroduction_levels</option>
<option value="2">free type regex</option>
<option value="1">production_levels</option>
<option value="2">free type regex</option>
<option value="1">ebay</option>
<option value="2">free type regex</option>
<option value="1">probbbb</option>
<option value="2">free type regex</option>
<option value="1">croduction_levelsdfsf</option>
<option value="2">free type regex</option>
<option value="1">brodueeee</option>
<option value="2">free type regex</option>
<option value="2">abcdefg</option>
<option value="2">abc</option>
<option value="2">free type regex</option>
</select>
</div>
然后使用下面的js传入input,select,div的各自ID.
var combo1 = new Combobox({
_inputId : "devicesValueInput",
_selectId : "devicesValueSelect",
_divId : "devicesValueDiv"
});
combo1.make();
OK.浏览页面控件会自动生成comboBox.在实际项目中如果需要填入相关的数据.可以自己把select里面的option数据进行替换即可!
附上核心代码以便查看批评:
/**
* @author UFO
*/
function log(a) {
console.log(a);
}
function Combobox(config) {
if(config) {
this.inputId = config._inputId || "";
this.selectId = config._selectId || "";
this.divId = config._divId || "";
}
this.divObj = $("#" + this.divId);
this.inputObj = $("#" + this.inputId);
this.selectObj = $("#" + this.selectId);
this.widthInit = 200;
this.inputWidth = this.widthInit - 20;
this.divHeigth = $("#" + this.divId).height() - 41;
this.make = function() {
this.setSelectEvent(this);
this.setInputEvent(this);
this.setMouseEvent(this);
};
this.setMouseEvent = function(_self) {
if($("body").data("comboDivs")) {
var comboDivs = $("body").data("comboDivs");
comboDivs.push(_self);
$("body").data("comboDivs", comboDivs);
} else {
var comboDivs = new Array();
comboDivs.push(_self);
$("body").data("comboDivs", comboDivs);
}
function mouseCoords(ev) {
if(ev.pageX || ev.pageY) {
return {
x : ev.pageX,
y : ev.pageY
};
};
return {
x : ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y : ev.clientY + document.body.scrollTop - document.body.clientTop
};
};
document.onmousedown = function(ev) {
var ev = ev || window.event;
var mousePos = mouseCoords(ev);
var comboDivs = $("body").data("comboDivs");
for(var i = 0; i < comboDivs.length; i++) {
var _self = comboDivs[i];
var selectDiv = $("#select_div_on_key" + _self.selectId);
if(selectDiv.get(0)) {
var osx = selectDiv.offset().left;
var oex = selectDiv.offset().left + selectDiv.width();
var osy = selectDiv.offset().top;
var oey = selectDiv.offset().top + selectDiv.height();
// $("#info").html(mousePos.x + " " + mousePos.y + "<br>" + "osx:" + osx + " oex:" + oex + "<br>" + "osy:" + osy + " oey:" + oey);
// $("#info").append((mousePos.x < osx) + " " + (mousePos.x > oex) + " " + (mousePos.y < osy) + " " + (mousePos.y > oey));
if((mousePos.x < osx || mousePos.x > oex) || (mousePos.y < osy || mousePos.y > oey)) {
_self.removeSelectDiv(_self.selectId);
}
}
};
}
};
this.setSelectEvent = function(_self) {
var _self = _self;
$("#" + _self.selectId).change(function() {
var newvar = $("#" + _self.selectId).find("option:selected").text();
$("#" + _self.inputId).val(newvar);
}).click(function() {
$("#select_div_on_key" + _self.selectId).remove();
}).css({
"display" : "block",
"width" : _self.widthInit + "px",
"z-index" : 1,
"clip" : "rect(0px " + _self.widt + "px 51px 151px)"
});
};
this.setInputEvent = function(_self) {
var _self = _self;
var aa = this;
//这里需要传入对象,这里需要强调.如果不传入,jquery的事件处理函数无法得到this.因为事件处理函数里面的this是那个DOM元素.而且事件处理函数里面只能访问到他所在函数里面的数据.这是闭包吗?
$("#" + _self.inputId).keyup(function() {
// _self.keyupFlag = 1;
_self.ShowSelectCombo(_self);
}).click(function() {
_self.ShowSelectCombo(_self);
}).css({
"z-index" : 2,
"width" : this.inputWidth + "px"
});
};
this.removeSelectDiv = function(selectId) {
var ulDIV = $("#select_div_on_key" + selectId);
ulDIV.remove();
};
this.hideSelectDiv = function(selectId) {
var ulDIV = $("#select_div_on_key" + selectId);
ulDIV.hide();
};
this.ShowSelectCombo = function(_self) {
console.log("---------------")
var _self = _self;
//这里为什么不能用this?因为在click事件里面的this是元素自己.所以先把context上下文_self又传进来处理.
var inputObjVal = _self.inputObj.val();
var inputObjOffset = _self.inputObj.offset();
var inputObjWidth = _self.inputObj.width() + 20;
var html = "";
if(inputObjVal == "") {
html = "<div class='select_div_list' id='select_div_on_key" + _self.selectId + "' style='display:none;position:absolute;width:" + inputObjWidth + "px;margin-top:" + _self.inputObj.outerHeight() + "px;z-index:1000;'><ul class='select_div_list_ul'>";
} else {
html = "<div class='select_div_list' id='select_div_on_key" + _self.selectId + "' style='position:absolute;width:" + inputObjWidth + "px;margin-top:" + _self.inputObj.outerHeight() + "px;z-index:1000;'><ul class='select_div_list_ul'>";
$("#" + _self.selectId).find("option").each(function() {
var tk = $(this);
if(tk.html().indexOf(inputObjVal) != -1) {
html += "<li val='" + tk.val() + "' ht='" + encodeURIComponent(tk.html()) + "'>" + tk.html() + "</li>";
}
});
}
html += "</ul></div>";
_self.removeSelectDiv(_self.selectId);
_self.divObj.append(html);
var ulDIV = $("#select_div_on_key" + _self.selectId);
var hei = ulDIV.find("ul").height();
var newHeight = hei > _self.divHeigth ? _self.divHeigth : hei;
ulDIV.css({
height : newHeight + "px"
});
ulDIV.find("li").hover(function() {
$(this).css({
"background-color" : "#079BD5"
});
}, function() {
$(this).css({
"background-color" : "white"
});
});
ulDIV.find("li").click(function() {
var _selfLi = $(this);
var va = _selfLi.attr("val");
var htm = _selfLi.attr("ht");
htm = decodeURIComponent(htm);
$("#" + _self.inputId).val(htm);
$("#" + _self.selectId).val(va);
ulDIV.remove();
});
};
}
因为OSCHINA我知道怎么上传附件.所以只能提供ITEYE的下载地址: