Similarly, this plug-in does not require any html tags, it only needs an input box with a corresponding class name, and the parent has a class name, and nothing else is needed. The internal HTML code is automatically generated.
The HTML code is as follows:
In fact, the above div tag is not necessary. You only need to add a class as above in the input input box and parent element (you can also customize it, just pass in the class during JS initialization. By default, the parent The class is called parentCls, the current input box class is called inputElem, and the class of the hidden field is called hiddenCls. Just initialize and pass in the empty object directly during initialization!). Because there may be multiple input boxes on the page, a parent class is needed to distinguish which input box it is. Of course, a hidden field is needed to store the value in the development backend.
There is a mailbox array parameter mailArr in the configuration item: ["@qq.com", "@qq2.com", "@gmail.com", "@126.com", "@163.com" ,"@hotmail.com","@yahoo.com","@yahoo.com.cn","@live.com","@sohu.com","@sina.com"]. It is to tell us that there are so many default mailboxes. No matter what I enter, there are so many mailbox prompts when the drop-down box is initialized. When I pinpoint a certain item, I will give a prompt to pinpoint a certain item in the drop-down box. Of course, due to changes in requirements, the email parameter can be configured according to needs when initializing it.
The coding style is still the same as before.
The functions implemented are as follows:
1. Supports keyboard movement up and down, mouse click and enter operation.
2. When clicking the document, the drop-down box is hidden except for the current input box. When you continue to input, automatic matching and other operations are implemented.
I won’t go into details, it’s just like the automatic email prompt function when registering online. If you have any bugs, you can leave me a message. It’s not too early, so don’t be wordy! Paste the code directly:
The CSS code is as follows:
The JS code is as follows:
function EmailAutoComplete(options) {
this.config = {
targetCls : '.inputElem', // 目标input元素
parentCls : '.parentCls', // 当前input元素的父级类
hiddenCls : '.hiddenCls', // 当前input隐藏域
searchForm : '.jqtransformdone', //form表单
hoverBg : 'hoverBg', // 鼠标移上去的背景
inputValColor : 'red', // 输入框输入提示颜色
mailArr : ["@qq.com","@qq2.com","@gmail.com","@126.com","@163.com","@hotmail.com","@yahoo.com","@yahoo.com.cn","@live.com","@sohu.com","@sina.com"], //邮箱数组
isSelectHide : true, // 点击下拉框 是否隐藏 默认为true
callback : null // 点击某一项回调函数
};
this.cache = {
onlyFlag : true, // 只渲染一次
currentIndex : -1,
oldIndex : -1
};
this.init(options);
}
EmailAutoComplete.prototype = {
constructor: EmailAutoComplete,
init: function(options){
this.config = $.extend(this.config,options || {});
var self = this,
_config = self.config,
_cache = self.cache;
$(_config.targetCls).each(function(index,item){
$(item).keyup(function(e){
var target = e.target,
targetVal = $.trim($(this).val()),
keycode = e.keyCode,
elemHeight = $(this).outerHeight(),
elemWidth = $(this).outerWidth(),
parentNode = $(this).closest(_config.parentCls);
$(parentNode).css({'position':'relative'});
// 如果输入框值为空的话 那么下拉框隐藏
if(targetVal == '') {
$(item).attr({'data-html':''});
// 给隐藏域赋值
$(_config.hiddenCls,parentNode).val('');
_cache.currentIndex = -1;
_cache.oldIndex = -1;
$(".auto-tip",parentNode) && !$(".auto-tip",parentNode).hasClass('hidden') && $(".auto-tip",parentNode).addClass('hidden');
self._removeBg(parentNode);
}else {
$(item).attr({'data-html':targetVal});
// 给隐藏域赋值
$(_config.hiddenCls,parentNode).val(targetVal);
$(".auto-tip",parentNode) && $(".auto-tip",parentNode).hasClass('hidden') && $(".auto-tip",parentNode).removeClass('hidden');
// 渲染下拉框内容
self._renderHTML({keycode:keycode,e:e,target:target,targetVal:targetVal,height:elemHeight,width:elemWidth,parentNode:parentNode});
}
});
});
// 阻止form表单默认enter键提交
$(_config.searchForm).each(function(index,item) {
$(item).keydown(function(e){
var keyCode = e.keyCode;
if(keyCode == 13) {
return false;
}
});
});
// 点击文档document时候 下拉框隐藏掉
$(document).click(function(e){
e.stopPropagation();
var target = e.target,
tagCls = _config.targetCls.replace(/^\./,'');
if(!$(target).hasClass(tagCls)) {
$('.auto-tip') && $('.auto-tip').each(function(index,item){
!$(item).hasClass('hidden') && $(item).addClass('hidden');
});
}
});
},
/*
* 渲染下拉框提示内容
* @param cfg{object}
*/
_renderHTML: function(cfg) {
var self = this,
_config = self.config,
_cache = self.cache,
curVal;
var curIndex = self._keyCode(cfg.keycode);
$('.auto-tip',cfg.parentNode).hasClass('hidden') && $('.auto-tip',cfg.parentNode).removeClass('hidden');
if(curIndex > -1){
// 键盘上下操作
self._keyUpAndDown(cfg.targetVal,cfg.e,cfg.parentNode);
}else {
if(/@/.test(cfg.targetVal)) {
curVal = cfg.targetVal.replace(/@.*/,'');
}else {
curVal = cfg.targetVal;
}
if(_cache.onlyFlag) {
$(cfg.parentNode).append('');
var wrap = '
for(var i = 0; i < _config.mailArr.length; i++) {
wrap += '
// 精确匹配内容
self._accurateMate({target:cfg.target,parentNode:cfg.parentNode});
// 鼠标移到某一项li上面时候
self._itemHover(cfg.parentNode);
// 点击对应的项时
self._executeClick(cfg.parentNode);
}
},
/**
* 精确匹配某项内容
*/
_accurateMate: function(cfg) {
var self = this,
_config = self.config,
_cache = self.cache;
var curVal = $.trim($(cfg.target,cfg.parentNode).attr('data-html')),
newArrs = [];
if(/@/.test(curVal)) {
// 获得@ 前面 后面的值
var prefix = curVal.replace(/@.*/, ""),
suffix = curVal.replace(/.*@/, "");
$.map(_config.mailArr,function(n){
var reg = new RegExp(suffix);
if(reg.test(n)) {
newArrs.push(n);
}
});
if(newArrs.length > 0) {
$('.auto-tip',cfg.parentNode).html('');
$(".auto-tip",cfg.parentNode) && $(".auto-tip",cfg.parentNode).hasClass('hidden') &&
$(".auto-tip",cfg.parentNode).removeClass('hidden');
var html = '';
for(var j = 0, jlen = newArrs.length; j < jlen; j++) {
html += '
var emVal = $.trim($('.em',item).attr('data-html'));
$(item).attr('data-html','');
$(item).attr({'data-html':prefix + '' +emVal});
});
// 精确匹配到某项时候 让当前的索引等于初始值
_cache.currentIndex = -1;
_cache.oldIndex = -1;
$('.auto-tip .output-num',cfg.parentNode).html(prefix);
// 鼠标移到某一项li上面时候
self._itemHover(cfg.parentNode);
// 点击对应的项时
self._executeClick(cfg.parentNode);
}else {
$(".auto-tip",cfg.parentNode) && !$(".auto-tip",cfg.parentNode).hasClass('hidden') &&
$(".auto-tip",cfg.parentNode).addClass('hidden');
$('.auto-tip',cfg.parentNode).html('');
}
}
},
/*
* 鼠标移到某一项li上时
*/
_itemHover: function(parentNode) {
var self = this,
_config = self.config,
_cache = self.cache;
$('.auto-tip li',parentNode).hover(function(index,item) {
!$(this).hasClass(_config.hoverBg) && $(this).addClass(_config.hoverBg);
},function() {
$(this).hasClass(_config.hoverBg) && $(this).removeClass(_config.hoverBg);
});
},
/*
* 当输入框值为空时候 li项都删掉class hoverBg
*/
_removeBg: function(parentNode){
var self = this,
_config = self.config;
$(".auto-tip li",parentNode).each(function(index,item){
$(item).hasClass(_config.hoverBg) && $(item).removeClass(_config.hoverBg);
});
},
/**
* 键盘上下键操作
*/
_keyUpAndDown: function(targetVal,e,parentNode) {
var self = this,
_cache = self.cache,
_config = self.config;
// 如果请求成功后 返回了数据(根据元素的长度来判断) 执行以下操作
if($('.auto-tip' + ' li',parentNode) && $('.auto-tip' + ' li').length > 0) {
var plen = $('.auto-tip' + ' li',parentNode).length,
keyCode = e.keyCode;
_cache.oldIndex = _cache.currentIndex;
// 上移操作
if(keyCode == 38) {
if(_cache.currentIndex == -1) {
_cache.currentIndex = plen - 1;
}else {
_cache.currentIndex = _cache.currentIndex - 1;
if(_cache.currentIndex < 0) {
_cache.currentIndex = plen - 1;
}
}
if(_cache.currentIndex !== -1) {
!$('.auto-tip .p-index'+_cache.currentIndex,parentNode).hasClass(_config.hoverBg) &&
$('.auto-tip .p-index'+_cache.currentIndex,parentNode).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
var curAttr = $('.auto-tip' + ' .p-index'+_cache.currentIndex,parentNode).attr('data-html');
$(_config.targetCls,parentNode).val(curAttr);
// 给隐藏域赋值
$(_config.hiddenCls,parentNode).val(curAttr);
}
}else if(keyCode == 40) { //下移操作
if(_cache.currentIndex == plen - 1) {
_cache.currentIndex = 0;
}else {
_cache.currentIndex++;
if(_cache.currentIndex > plen - 1) {
_cache.currentIndex = 0;
}
}
if(_cache.currentIndex !== -1) {
!$('.auto-tip .p-index'+_cache.currentIndex,parentNode).hasClass(_config.hoverBg) &&
$('.auto-tip .p-index'+_cache.currentIndex,parentNode).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
var curAttr = $('.auto-tip' + ' .p-index'+_cache.currentIndex,parentNode).attr('data-html');
$(_config.targetCls,parentNode).val(curAttr);
// 给隐藏域赋值
$(_config.hiddenCls,parentNode).val(curAttr);
}
}else if(keyCode == 13) { //回车操作
var curVal = $('.auto-tip' + ' .p-index'+_cache.oldIndex,parentNode).attr('data-html');
$(_config.targetCls,parentNode).val(curVal);
// 给隐藏域赋值
$(_config.hiddenCls,parentNode).val(curVal);
if(_config.isSelectHide) {
!$(".auto-tip",parentNode).hasClass('hidden') && $(".auto-tip",parentNode).addClass('hidden');
}
_config.callback && $.isFunction(_config.callback) && _config.callback();
_cache.currentIndex = -1;
_cache.oldIndex = -1;
}
}
},
_keyCode: function(code) {
var arrs = ['17','18','38','40','37','39','33','34','35','46','36','13','45','44','145','19','20','9'];
for(var i = 0, ilen = arrs.length; i < ilen; i++) {
if(code == arrs[i]) {
return i;
}
}
return -1;
},
/**
* 当数据相同的时 点击对应的项时 返回数据
*/
_executeClick: function(parentNode) {
var _self = this,
_config = _self.config;
$('.auto-tip' + ' li',parentNode).unbind('click');
$('.auto-tip' + ' li',parentNode).bind('click',function(e){
var dataAttr = $(this).attr('data-html');
$(_config.targetCls,parentNode).val(dataAttr);
if(_config.isSelectHide) {
!$(".auto-tip",parentNode).hasClass('hidden') && $(".auto-tip",parentNode).addClass('hidden');
}
// 给隐藏域赋值
$(_config.hiddenCls,parentNode).val(dataAttr);
_config.callback && $.isFunction(_config.callback) && _config.callback();
});
}
};
// 初始化
$(function() {
new EmailAutoComplete({});
});