JS输入框邮箱自动提示(带有demo和源码)(转载)
今天在javascriptQQ群里面 有童鞋问到 有没有 "JS输入框邮箱自动提示"插件,即说都找遍了github上源码 都没有看到这样类似的插件,然后我想了下 "JS输入框邮箱自动提示" 和我前几次写的编写简易的JS输入框模糊查询 插件 功能类似了!也google了下 到底是个什么样的效果,看了下也没有什么特别之处,所以趁着今天没有什么事情做的话 写一个这样的出来 给大家分享下 也可以自己积累下,以后如果项目中碰到类似的效果可以直接拿来用。
说了这么多!我们先来看看效果 看看到底是个什么样的,其实有时候我看别人的博客或者代码时候 也是希望先看看什么效果 然后看看他们的代码能不能运行,然后顺着这个思路去研究他们内部代码,所以我底部提供了 "demo下载链接" 大家有空的话 也可以研究下我写的代码 如有不足之处 请大家多多指教!好了 先瞎聊到这里!先看看下面效果!如下图:
原理是:一个输入框 当我输入任何字的时候 自动下拉相应的邮箱提示,在输入框输入11的时候 下拉框有所有11的邮箱 输入其他的时候 有其他文案对应的邮箱。
同理 此插件不需要任何html标签,只需要一个输入框 有相对应的class类名就ok 且父级有个class类名,其他的都不需要。内部的HTML代码都是自动生成的。
HTML代码如下:
<div class="parentCls">
<input type="text" class="inputElem">
</div>
其实上面的div标签都可以不需要 只需要在input输入框 且父级元素添加一个如上class(自定义也可以,只是在JS初始化的时候要传入class就ok 我默认情况下 父级class叫parentCls,当前输入框class叫inputElem,隐藏域的class叫hiddenCls,在初始化的时候 直接初始化 传入空对象即可!)。因为页面上可能有多个输入框 所以需要一个父级class 来区分是那个输入框,当然要个隐藏域 存值给开发后台。
其中在配置项里面 有个邮箱数组参数 mailArr : ["@qq.com","@qq2.com","@gmail.com","@126.com","@163.com","@hotmail.com","@yahoo.com","@yahoo.com.cn","@live.com","@sohu.com","@sina.com"] 。就是要告诉我们默认邮箱有这么多,不管我输入什么 下拉框初始化时候有这么多邮箱提示,当我精确到某一项的时候 在给个提示 精确到某一项下拉。当然由于需求的变更 邮箱这个参数可以自己初始化时候 自己根据需求配置。
代码风格还是和以前一样。
实现的功能如下:
1. 支持键盘上下移键盘操作,支持鼠标点击及按回车操作。
2. 点击document时候 除当前input输入框之外 下拉框隐藏。当接着输入时候 实现自动匹配等等操作。
具体不多说 就是类似于网上注册时候 邮箱自动提示功能一样 ,如果有任何bug的话 可以给我留言,时间也不早了 不罗嗦了!直接贴代码:
CSS代码如下:
<style>
*{margin:;padding:;}
ul,li{list-style:none;}
.inputElem {width:198px;height:22px;line-height:22px;border:1px solid #ff4455;}
.parentCls{width:200px;}
.auto-tip li{width:100%;height:22px;line-height:22px;font-size:14px;}
.auto-tip li.hoverBg{background:#ddd;cursor:pointer;}
.red{color:red;}
.hidden {display:none;}
</style>
JS代码如下:
/**
* 邮箱自动提示插件
* @constructor EmailAutoComplete
* @ options {object} 可配置项
*/ 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('<input type="hidden" class="hiddenCls"/>');
var wrap = '<ul class="auto-tip">'; for(var i = 0; i < _config.mailArr.length; i++) { wrap += '<li class="p-index'+i+'">'+'<span class="output-num"></span><em class="em" data-html="'+_config.mailArr[i]+'">'+_config.mailArr[i]+'</em></li>';
}
wrap += '</ul>';
_cache.onlyFlag = false;
$(cfg.parentNode).append(wrap);
$('.auto-tip',cfg.parentNode).css({'position':'absolute','top':cfg.height,'width':cfg.width - 2 + 'px','left':0,
'border':'1px solid #ccc','z-index':10000});
} // 给所有li添加属性 data-html
$('.auto-tip li',cfg.parentNode).each(function(index,item){
$('.output-num',item).html(curVal);
!$('.output-num',item).hasClass(_config.inputValColor) &&
$('.output-num',item).addClass(_config.inputValColor);
var emVal = $.trim($('.em',item).attr('data-html'));
$(item).attr({'data-html':curVal + '' +emVal});
}); // 精确匹配内容
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 += '<li class="p-index'+j+'">'+'<span class="output-num"></span><em class="em" data-html="'+newArrs[j]+'">'+newArrs[j]+'</em></li>';
}
$('.auto-tip',cfg.parentNode).html(html); // 给所有li添加属性 data-html
$('.auto-tip li',cfg.parentNode).each(function(index,item){
$('.output-num',item).html(prefix);
!$('.output-num',item).hasClass(_config.inputValColor) &&
$('.output-num',item).addClass(_config.inputValColor); 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({});
});
转载链接:http://www.cnblogs.com/tugenhua0707/p/3466712.html
JS输入框邮箱自动提示(带有demo和源码)(转载)的更多相关文章
- JS输入框邮箱自动提示(带有demo和源码)
今天在javascriptQQ群里面 有童鞋问到 有没有 "JS输入框邮箱自动提示"插件,即说都找遍了github上源码 都没有看到这样类似的插件,然后我想了下 "JS输 ...
- [模仿微软Live.cn]JavaScript输入邮箱自动提示
原理是:在一个输入框 中,当我输入任何字的时候 自动下拉相应的邮箱提示,在输入框输入123的时候 下拉框有所有123的邮箱 输入其他的时候 有其他文案对应的邮箱. 同理 此插件不需要任何html标签, ...
- 编写简易的JS输入框模糊查询匹配(附有源码和demo)
前言:JS输入框模糊匹配插件以前在工作写过一个类似的 所以这次写轻松很多,这次写优化了几个方面: 1. 添加动态加载css文件 不需要引入css css全部在JS动态生成. 2. 不需要额外的标签 只 ...
- JS编写简单的弹窗插件(含有demo和源码)
最近项目做完了 事情不是很多,今天正好也在调休,所以趁着这个时间研究了一下简易的JS弹窗功能,当然网上这块插件非常多,本人也没有仔细看网上的插件源码 只是凭着日常使用过的弹窗插件有这么多功能 来实现自 ...
- 关于超链接自动提示的demo
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
- JS模拟滚动条(有demo和源码下载,支持拖动 滚轮 点击事件)
由于游览器自带的滚动条在美观方面并不是很好看,所以很多设计师希望通过自己设计出来的滚动条来做这样的效果,JS模拟滚动条其实很早看到jQuery有这样的插件或者KISSY有这样的组件,一直想着自己什么时 ...
- eclipse/myeclipse中js/java的自动提示只有4个字符怎么解决
https://blog.csdn.net/LinBM123/article/details/80450690
- 图片上传5-多个图片上传,独立项目Demo和源码
图片上传,一次性可以上传多个图片,每个图片可以有名字.URL.排序.备注等字段.这是区别于使用百度WebUploader等多图上传工具的地方. 项目相关图片 Jar包管理:Maven用到的框架:Spr ...
- jquery 实现邮箱输入自动提示功能:(二)
上篇文章写到了一个不错的jquery实现邮箱输入自动提示功能,发现还有一个不错的自动提示插件: 先展示结果如图: html代码: <center> <h1>输入邮箱试试!< ...
随机推荐
- VS2010+OpenCV2.4.6永久性配置方法
1. 配置OpenCV环境变量 计算机->(右键)属性,出现如图1所示界面 单击“高级系统设置”,选中高级(标签)出现如图2所示界面 单击右下方的“环境变量”,弹出如图3所示界面,注意这里最好用 ...
- C# 获取时间差(几天前,几小时前,几分钟前,几秒前)
#region 获取时间差string GetTime(BsonString getTime) /// <summary> /// 获取时间差 /// </summary> / ...
- javascript模板方法模式
一:什么是模板方法模式: 模板方法模式由二部分组成,第一部分是抽象父类,第二部分是具体实现的子类,一般的情况下是抽象父类封装了子类的算法框架,包括实现一些公共方法及封装子类中所有方法的执行顺序,子类可 ...
- dedecms文章标题是在哪个数据库表?要批量替换关键词
一位小MM刚接触dedecms没多久还不熟悉后台的操作,她说改dedecms文章中的品牌名改到手酸,问ytkah是否有批量替换关键词的方法,教了她dedecms后台批量替换文章中的关键词方法,她高兴坏 ...
- 淘宝(阿里百川)手机客户端开发日记第五篇 SharedPreferences使用详解
我们知道,Android中数据存储技术由于如下几种 1 使用SharedPreferences存储数据 2 文件存储数据 3 SQLite数据库存储数据 4 使用ContentProvider存储数据 ...
- POJ 1062 昂贵的聘礼
C - 昂贵的聘礼 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit St ...
- HDU 1231 最大连续子序列 &&HDU 1003Max Sum (区间dp问题)
C - 最大连续子序列 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit ...
- GAE初探-一鼻子灰
考虑到GAE可以一定条件下免费发布app,再加上之前有潜在客户需要用到GAE. 遂决定了解一番. 以比较熟悉的django作为切入点, 1. 首先安装 GAE-launcher,似乎没有太大问题 2. ...
- simple_html_dom使用小结
simple_html_dom使用小结 分类: PHP2012-08-31 14:24 3094人阅读 评论(0) 收藏 举报 htmlcallbackstringdivfunctionfile 1 ...
- [转]sql语句中出现笛卡尔乘积 SQL查询入门篇
本篇文章中,主要说明SQL中的各种连接以及使用范围,以及更进一步的解释关系代数法和关系演算法对在同一条查询的不同思路. 多表连接简介 在关系数据库中,一个查询往往会涉及多个表,因为很少有数据库只有一个 ...