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


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新手语法小结
Jun 15 Javascript
关于URL中的特殊符号使用介绍
Nov 03 Javascript
js获取元素到文档区域document的(横向、纵向)坐标的两种方法
May 17 Javascript
jQuery中hide()方法用法实例
Dec 24 Javascript
jQuery实现的图文高亮滚动切换特效实例
Aug 10 Javascript
javascript表单事件处理方法详解
May 15 Javascript
原生js实现移动端触摸轮播的示例代码
Dec 22 Javascript
jQuery实现仿京东防抖动菜单效果示例
Jul 06 jQuery
自定义javascript验证框架示例【附源码下载】
May 31 Javascript
微信小程序image图片加载完成监听
Aug 31 Javascript
通过vue.extend实现消息提示弹框的方法记录
Jan 07 Vue.js
JavaScript使用canvas绘制坐标和线
Apr 28 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/11/25 PHP
php把大写命名转换成下划线分割命名
2015/04/27 PHP
php post大量数据时发现数据丢失问题解决方法
2015/06/20 PHP
举例详解PHP脚本的测试方法
2015/08/05 PHP
php二维码生成
2015/10/19 PHP
php结合md5实现的加密解密方法
2016/01/25 PHP
php读取torrent种子文件内容的方法(测试可用)
2016/05/03 PHP
ie 处理 gif动画 的onload 事件的一个 bug
2007/04/12 Javascript
JQuery在页面中添加和除移DOM示例代码
2013/06/24 Javascript
Jquery选择子控件&quot;大于号&quot;和&quot; &quot;区别介绍及使用示例
2013/06/25 Javascript
nodejs实现遍历文件夹并统计文件大小
2015/05/28 NodeJs
AngularJS中如何使用echart插件示例详解
2016/10/26 Javascript
微信公众号支付H5调用支付解析
2016/11/04 Javascript
JavaScript实现图片瀑布流和底部刷新
2017/01/02 Javascript
关于foreach循环中遇到的问题小结
2017/05/08 Javascript
Vue.js弹出模态框组件开发的示例代码
2017/07/26 Javascript
Bootstrap + AngularJS 实现简单的数据过滤字符查找功能
2017/07/27 Javascript
浅谈 Vue 项目优化的方法
2017/12/16 Javascript
JS实现判断数组是否包含某个元素示例
2019/05/24 Javascript
[49:27]LGD vs OG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python web框架学习笔记
2016/05/03 Python
在Python中居然可以定义两个同名通参数的函数
2019/01/31 Python
Python 窗体(tkinter)下拉列表框(Combobox)实例
2020/03/04 Python
Python实现爬取网页中动态加载的数据
2020/08/17 Python
html5 标签
2009/07/16 HTML / CSS
Mountain Warehouse澳大利亚官网:欧洲家庭户外品牌倡导者
2016/11/20 全球购物
德国古洛迷亚百货官网:GALERIA Kaufhof
2017/06/20 全球购物
维氏瑞士军刀英国网站:Victorinox英国
2019/07/04 全球购物
TCP/IP的分层模型
2013/10/27 面试题
override和overload的区别
2016/03/09 面试题
员工考核管理制度
2014/02/02 职场文书
机关工会开展学习雷锋活动总结
2014/03/01 职场文书
新闻专业毕业生英文求职信
2014/03/19 职场文书
领导干部廉政承诺书
2014/03/27 职场文书
2021年pycharm的最新安装教程及基本使用图文详解
2021/04/03 Python
python基础之类方法和静态方法
2021/10/24 Python