微博@符号的用户名提示效果。(想@到谁?)


Posted in Javascript onNovember 05, 2010

在下面的文本框输入“@” 看一下效果吧!

已经解决 IE,FF ,CHORME 主流浏览器的兼容问题。有需要这个JS的朋友可以直接拿去用。

由于我实在无法把这个效果插入到这遍文章里。所以只能让大家下载我演示的文件了。

下载演示文件

微博@符号的用户名提示效果。(想@到谁?) 
思路

我们可以用onkeyup事件监测文本框是否输入了一个@符号,如果输入了,就找到@符号在页面上的绝对位置,弹出提示。(实际制作过程中会遇到各种各样的问题)
问题: textarea 里的光标位置无法直接获取。
所以我们只能迂回前进了。
解决弹出框的位置

首先你是针对网页里面的textarea(这是一个很麻烦的标签) 这个标签的一些操作。

所以关于他的一些API你必须收集到。(下面会有提供)

  微博@符号的用户名提示效果。(想@到谁?)
  A:是一个textarea 

  B:当前光标位置

 

 我们的方案是 首先在页面创建一个(C)具有 visibility:hidden;(占位但是不显示) 属性的DIV。

 他的位置,宽度,高度与A文本框一样(这意味着C现在与A已经重叠了)。 

 然后我们获取到B位置前面的所有文本(可以用js获取到),写入C 里面,在追加一个<span id='FFF'></span>;

 那么ID为FFF 的span标签的位置就是 B的位置。

 HTML页面会多了一些这样的标签
 <div id="c">这你是一个textarea @<span id='FFF'></span><div>

 可以获取到@符号的位置,其他问题都只是调试的问题了,就不多说了。你可以直接下载源码
textarea 的一些操作

/* 
* TT textarea 操作函数 
* info(t) 基本信息 
* getCursorPosition(t) 光标位置 
* setCursorPosition(t, p) 设置光标位置 
* add(t,txt) 添加内容到光标处 
*/ 
var TT = { 
info:function(t){ 
var o = t.getBoundingClientRect(); 
var w = t.offsetWidth; 
var h = t.offsetHeight; 
return {top:o.top, left:o.left, width:w, height:h}; 
}, 
getCursorPosition: function(t){ 
if (document.selection) { 
t.focus(); 
var ds = document.selection; 
var range = null; 
range = ds.createRange(); 
var stored_range = range.duplicate(); 
stored_range.moveToElementText(t); 
stored_range.setEndPoint("EndToEnd", range); 
t.selectionStart = stored_range.text.length - range.text.length; 
t.selectionEnd = t.selectionStart + range.text.length; 
return t.selectionStart; 
} else return t.selectionStart 
}, 
setCursorPosition:function(t, p){ 
var n = p == 'end' ? t.value.length : p; 
if(document.selection){ 
var range = t.createTextRange(); 
range.moveEnd('character', -t.value.length); 
range.moveEnd('character', n); 
range.moveStart('character', n); 
range.select(); 
}else{ 
t.setSelectionRange(n,n); 
t.focus(); 
} 
}, 
add:function (t, txt){ 
var val = t.value; 
var wrap = wrap || '' ; 
if(document.selection){ 
document.selection.createRange().text = txt; 
} else { 
var cp = t.selectionStart; 
var ubbLength = t.value.length; 
t.value = t.value.slice(0,t.selectionStart) + txt + t.value.slice(t.selectionStart, ubbLength); 
this.setCursorPosition(t, cp + txt.length); 
}; 
}, 
del:function(t, n){ 
var p = this.getCursorPosition(t); 
var s = t.scrollTop; 
t.value = t.value.slice(0,p - n) + t.value.slice(p); 
this.setCursorPosition(t ,p - n); 
D.FF && setTimeout(function(){t.scrollTop = s},10); 
} 
}

主要的一些JS
var AutoTips = function(A){ 
var elem = A.id ? D.$(A.id) : A.elem; 
var checkLength = 5; 
var _this = {}; 
var key = ''; 
_this.start = function(){ 
if(!D.$(config.boxID)){ 
var h = html.slice(); 
var info = TT.info(elem); 
var div = D.DC('DIV'); 
var bs = D.BS(); 
h = h.replace('$top$',(info.top + bs.top)). 
replace('$left$',(info.left + bs.left)). 
replace('$width$',info.width). 
replace('$height$',info.height). 
replace('$SCTOP$','0'); 
div.innerHTML = h; 
document.body.appendChild(div); 
}else{ 
_this.updatePosstion(); 
} 
} 
_this.keyupFn = function(e){ 
var e = e || window.event; 
var code = e.keyCode; 
if(code == 38 || code == 40 || code == 13) { 
if(code==13 && D.$(config.wrap).style.display != 'none'){ 
_this.enter(); 
} 
return false; 
} 
var cp = TT.getCursorPosition(elem); 
if(!cp) return _this.hide(); 
var valuep = elem.value.slice(0, cp); 
var val = valuep.slice(-checkLength); 
var chars = val.match(/(\w+)?@(\w+)$|@$/); 
if(chars == null) return _this.hide(); 
var char = chars[2] ? chars[2] : ''; 
D.$(config.valuepWrap).innerHTML = valuep.slice(0,valuep.length - char.length).replace(/\n/g,'<br/>'). 
replace(/\s/g,' ') + config.positionHTML; 
_this.showList(char); 
} 
_this.showList = function(char){ 
key = char; 
var data = DS.inquiry(friendsData, char, 5); 
var html = listHTML.slice(); 
var h = ''; 
var len = data.length; 
if(len == 0){_this.hide();return;} 
var reg = new RegExp(char); 
var em = '<em>'+ char +'</em>'; 
for(var i=0; i<len; i++){ 
var hm = data[i]['user'].replace(reg,em); 
h += html.replace(/\$ACCOUNT\$|\$NAME\$/g,data[i]['name']). 
replace('$SACCOUNT$',hm).replace('$ID$',data[i]['user']); 
} 
_this.updatePosstion(); 
var p = D.$(config.position).getBoundingClientRect(); 
var bs = D.BS(); 
var d = D.$(config.wrap).style; 
d.top = p.top + 20 + bs.top + 'px'; 
d.left = p.left - 5 + 'px'; 
D.$(config.listWrap).innerHTML = h; 
_this.show(); 
} _this.KeyDown = function(e){ 
var e = e || window.event; 
var code = e.keyCode; 
if(code == 38 || code == 40 || code == 13){ 
return selectList.selectIndex(code); 
} 
return true; 
} 
_this.updatePosstion = function(){ 
var p = TT.info(elem); 
var bs = D.BS(); 
var d = D.$(config.boxID).style; 
d.top = p.top + bs.top +'px'; 
d.left = p.left + bs.left + 'px'; 
d.width = p.width+'px'; 
d.height = p.height+'px'; 
D.$(config.boxID).scrollTop = elem.scrollTop; 
} 
_this.show = function(){ 
selectList.list = D.$(config.listWrap).getElementsByTagName('li'); 
selectList.index = -1; 
selectList._this = _this; 
_this.cursorSelect(selectList.list); 
elem.onkeydown = _this.KeyDown; 
D.$(config.wrap).style.display = 'block'; 
} 
_this.cursorSelect = function(list){ 
for(var i=0; i<list.length; i++){ 
list[i].onmouseover = (function(i){ 
return function(){selectList.setSelected(i)}; 
})(i); 
list[i].onclick = _this.enter; 
} 
} 
_this.hide = function(){ 
selectList.list = null; 
selectList.index = -1; 
selectList._this = null; 
D.ER(elem, 'keydown', _this.KeyDown); 
D.$(config.wrap).style.display = 'none'; 
} 
_this.bind = function(){ 
elem.onkeyup = _this.keyupFn; 
elem.onclick = _this.keyupFn; 
elem.onblur = function(){setTimeout(_this.hide, 100)} 
//elem.onkeyup= fn; 
//D.EA(elem, 'keyup', _this.keyupFn, false) 
//D.EA(elem, 'keyup', fn, false) 
//D.EA(elem, 'click', _this.keyupFn, false); 
//D.EA(elem, 'blur', function(){setTimeout(_this.hide, 100)}, false); 
} 
_this.enter = function(){ 
TT.del(elem, key.length, key); 
TT.add(elem, selectList.list[selectList.index].getElementsByTagName('A')[0].rel+' '); 
_this.hide(); 
return false; 
} 
return _this; 
}

作者:idche
Javascript 相关文章推荐
javascript 面向对象全新理练之数据的封装
Dec 03 Javascript
返回对象在当前级别中是第几个元素的实现代码
Jan 20 Javascript
五段实用的js高级技巧
Dec 20 Javascript
node.js中使用socket.io制作命名空间
Dec 15 Javascript
使用JQuery实现Ctrl+Enter提交表单的方法
Oct 22 Javascript
在NPM发布自己造的轮子的方法步骤
Mar 09 Javascript
jquery简单实现纵向的无缝滚动代码实例
Apr 01 jQuery
深入学习JavaScript 高阶函数
Jun 11 Javascript
详解Element-UI中上传的文件前端处理
Aug 07 Javascript
微信小程序全局变量的设置、使用、修改过程解析
Sep 24 Javascript
有趣的JavaScript隐式类型转换操作实例分析
May 02 Javascript
JS删除对象中某一属性案例详解
Sep 08 Javascript
js focus不起作用的解决方法(主要是因为dom元素是否加载完成)
Nov 05 #Javascript
细说浏览器特性检测(2)-通用事件检测
Nov 05 #Javascript
需要做特殊处理的DOM元素属性的访问
Nov 05 #Javascript
基于jQuery的仿flash的广告轮播
Nov 05 #Javascript
jquery实现文本框鼠标右击无效以及不能输入的代码
Nov 05 #Javascript
基于jquery的loading效果实现代码
Nov 05 #Javascript
解决jQuery插件tipswindown与hintbox冲突
Nov 05 #Javascript
You might like
利用PHP创建动态图像
2006/10/09 PHP
WHOIS类的修改版
2006/10/09 PHP
PHP面向对象分析设计的经验原则
2008/09/20 PHP
PHPWind与Discuz截取字符函数substrs与cutstr性能比较
2011/12/05 PHP
PHP HTML JavaScript MySQL代码如何互相传值的方法分享
2012/09/30 PHP
symfony表单与页面实现技巧
2015/01/26 PHP
php运行时动态创建函数的方法
2015/03/16 PHP
thinkPHP3.2.2框架行为扩展及demo示例
2018/06/19 PHP
关于使用 jBox 对话框的提交不能弹出问题解决方法
2012/11/07 Javascript
深入理解JavaScript系列(29):设计模式之装饰者模式详解
2015/03/03 Javascript
jquery图片切换插件
2015/03/16 Javascript
JavaScript实现给按钮加上双重动作的方法
2015/08/14 Javascript
Javascript 字符串模板的简单实现
2016/02/13 Javascript
jQuery双向列表选择器DIV模拟版
2016/11/01 Javascript
vue2.0父子组件间通信的实现方法
2017/04/19 Javascript
Node.js自定义实现文件路由功能
2017/09/22 Javascript
vue-cli项目中使用Mockjs详解
2018/05/14 Javascript
javascript 对象 与 prototype 原型用法实例分析
2019/11/11 Javascript
javascript解析json格式的数据方法详解
2020/08/07 Javascript
用Python实现一个简单的多线程TCP服务器的教程
2015/05/05 Python
Python实现单词翻译功能
2017/06/06 Python
关于反爬虫的一些简单总结
2017/12/13 Python
python爬虫获取京东手机图片的图文教程
2017/12/29 Python
使用Python第三方库pygame写个贪吃蛇小游戏
2020/03/06 Python
Tensorflow之梯度裁剪的实现示例
2020/03/08 Python
TensorFlow Autodiff自动微分详解
2020/07/06 Python
详解python datetime模块
2020/08/17 Python
Python tkinter界面实现历史天气查询的示例代码
2020/08/23 Python
Python爬虫实现selenium处理iframe作用域问题
2021/01/27 Python
html+css3实现的登录界面
2020/12/09 HTML / CSS
主持人演讲稿范文
2013/12/28 职场文书
机械个人求职信范文
2014/01/24 职场文书
《云房子》教学反思
2014/04/20 职场文书
南京青奥会口号
2014/06/12 职场文书
2014年村委会工作总结
2014/11/24 职场文书
2016年元旦主持词
2015/07/06 职场文书