参考的代码来自这里:
http://www.jb51.net/article/28075.htm
不过说实话,这个网站太烂了,不适合看代码,另外写代码的人是个大牛,但是却没有模块化思想,所以朕不高兴直接用,索性是周末就花时间写一个吧。
明确一下需求:
需要一个输入框,在用户输入之后(keyup事件),将用户输入返回给外部,并从外部获取提示信息,显示到输入框下方
另外:
1、在失去焦点时,需要消去提示框
2、需要屏蔽浏览器原有的提示功能
3、监听键盘上下键,循环选择提示项
4、当窗口位置变化时,重新定位提示框
模块结构:
function AutoCompleteInput(Input,callBack){ this.Input = Input; this.callBack = callBack; } /** * 设置提示内容 * @param txt {String}提示内容,以","隔开 */ AutoCompleteInput.prototype.setAutoText = function(obj,txt){ };
足够简单吧?哈,下面就看实现了,请期待吧,估计晚上能写完。
晚了点,不过有原因的,中间做了个ppt
/** * Created by william on 2015/1/16. */ define(function(){ function AutoCompleteInput(Input, callBack) { this.$Input = $(Input);//输入框对象 this.callBack = callBack; this.$autocomplete; //提示框对象 this.Init(); this.selectedIndex = -1; } /** * 设置提示内容 * @param txt {String}提示内容,以","隔开 */ AutoCompleteInput.prototype.setAutoText = function (txt) { var self = this; if(txt.length==0||txt =="") return; var str = txt.split(','); $.each(str,function(index,term){ $('<li style="list-style-type: none;cursor: default;"></li>').text(term).appendTo(self.$autocomplete) .hover(function () { //下拉列表每一项的事件,鼠标移进去的操作 $(this).siblings().css("background-color","white"); $(this).css("background-color","#9ACCFB"); self.selectedIndex = index; }, function () { //下拉列表每一项的事件,鼠标离开的操作 $(this).css("background-color","white"); //当鼠标离开时索引置-1,当作标记 self.selectedIndex = -1; }) .click(function () { //鼠标单击下拉列表的这一项的话,就将这一项的值添加到输入框中 self.$Input.val(term); //清空并隐藏下拉列表 self.$autocomplete.empty().hide(); }); }); this.$autocomplete.show(); }; AutoCompleteInput.prototype.Init = function () { var self = this; this.$Input.attr("autocomplete", "off"); var position = this.$Input.position(); var w = this.$Input.width()+2; this.$autocomplete = $('<div style="position: absolute;left: '+position.left+'px;top:'+position.bottom+'px;' +w+'px;border: 1px solid #9ACCFB;background-color: white;text-align: left;"></div>') .hide().insertAfter(this.$Input); //设置键盘事件 this.$Input.keyup(function (event) { //字母数字,退格,空格 if (event.keyCode > 40 || event.keyCode == 8 || event.keyCode == 32) { //首先删除下拉列表中的信息 self.clear(); self.callBack(self,self.$Input.val()); return; } //方向键 上 if (event.keyCode == 38) { //selectedIndex = -1 代表鼠标离开 if (self.selectedIndex == -1) { self.setSelectedItem(self.$autocomplete.find('li').length - 1); } else { //索引减1 self.setSelectedItem(self.selectedIndex - 1); } event.preventDefault(); return; } //方向键 下 if (event.keyCode == 40) { //this.selectedIndex = -1 代表鼠标离开 if (self.selectedIndex == -1) { self.setSelectedItem(0); } else { //索引加1 self.setSelectedItem(self.selectedIndex + 1); } event.preventDefault(); return; } //enter键 if (event.keyCode == 13) { //列表为空或者鼠标离开导致当前没有索引值 if (self.$autocomplete.find('li').length == 0 || self.selectedIndex == -1) { return; } self.$Input.val(self.$autocomplete.find('li').eq(self.selectedIndex).text()); self.$autocomplete.empty().hide(); event.preventDefault(); return; } //esc键 if (event.keyCode == 27) { self.$autocomplete.empty().hide(); event.preventDefault(); } }); //设置当输入框失去焦点时,消去 this.$Input.blur(function () { setTimeout(function(){self.$autocomplete.empty().hide();},100);//这个地方名空间和复杂,不要修改 }); }; AutoCompleteInput.prototype.clear = function(){ //if(this.$autocomplete) this.$autocomplete.empty().hide(); }; AutoCompleteInput.prototype.setSelectedItem = function (index) { //更新索引变量 this.selectedIndex = index; //按上下键是循环显示的,小于0就置成最大的值,大于最大值就置成0 if (this.selectedIndex < 0) { this.selectedIndex = this.$autocomplete.find('li').length - 1; } else if (this.selectedIndex > this.$autocomplete.find('li').length - 1) { this.selectedIndex = 0; } //首先移除其他列表项的高亮背景,然后再高亮当前索引的背景 this.$autocomplete.find('li').css("background-color","white") .eq(this.selectedIndex).css("background-color","#9ACCFB"); }; return AutoCompleteInput; });
测试代码:
var f = function(obj,txt){ if(txt=="a"){ obj.setAutoText("a,aa,aaa"); } if(txt=="b"){ obj.setAutoText("b,bb,bbb"); } }; var p = new inp(document.getElementById("input"),f); var p2 = new inp(document.getElementById("i2"),f);