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


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 相关文章推荐
JQuery SELECT单选模拟jQuery.select.js
Nov 12 Javascript
一些经常会用到的Javascript检测函数
May 31 Javascript
jquery插件开发之实现md5插件
Mar 17 Javascript
JS常用字符串处理方法应用总结
May 22 Javascript
jQuery的Scrollify插件实现滑动到页面下一节点
Jul 05 Javascript
ES6中的数组扩展方法
Aug 26 Javascript
深入理解vue路由的使用
Mar 24 Javascript
9种使用Chrome Firefox 自带调试工具调试javascript技巧
Dec 22 Javascript
详解react-native WebView 返回处理(非回调方法可解决)
Feb 27 Javascript
vue 监听某个div垂直滚动条下拉到底部的方法
Sep 15 Javascript
JavaScript使用表单元素验证表单的示例代码
Aug 20 Javascript
LayUI数据接口返回实体封装的例子
Sep 12 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
浅析php header 跳转
2013/06/17 PHP
PHP中shuffle数组值随便排序函数用法
2014/11/21 PHP
jquery实现select下拉框美化特效代码分享
2015/08/18 Javascript
jquery实现简单的遮罩层
2016/01/08 Javascript
JS平滑无缝滚动效果的实现代码
2016/05/06 Javascript
详细探究ES6之Proxy代理
2016/07/22 Javascript
用AngularJS的指令实现tabs切换效果
2016/08/31 Javascript
Javascript 实现全屏滚动实例代码
2016/12/31 Javascript
微信小程序 图片宽高自适应详解
2017/05/11 Javascript
Three.js实现绘制字体模型示例代码
2017/09/26 Javascript
Django中使用jquery的ajax进行数据交互的实例代码
2017/10/15 jQuery
webpack3之loader全解析
2017/10/26 Javascript
vue2.0 computed 计算list循环后累加值的实例
2018/03/07 Javascript
JavaScript实现读取与输出XML文件数据的方法示例
2018/06/05 Javascript
从vue源码看props的用法
2019/01/09 Javascript
vue-cli中vue本地实现跨域调试接口
2019/01/16 Javascript
深入分析element ScrollBar滚动组件源码
2019/01/22 Javascript
jquery操作checkbox的常用方法总结【附测试源码下载】
2019/06/10 jQuery
vue-socket.io接收不到数据问题的解决方法
2020/05/13 Javascript
[59:48]DOTA2-DPC中国联赛 正赛 VG vs Magma BO3 第一场 1月26日
2021/03/11 DOTA
linux系统使用python获取内存使用信息脚本分享
2014/01/15 Python
详解python里的命名规范
2018/07/16 Python
Python3.4学习笔记之类型判断,异常处理,终止程序操作小结
2019/03/01 Python
jupyter lab文件导出/下载方式
2020/04/22 Python
利用matplotlib为图片上添加触发事件进行交互
2020/04/23 Python
python爬虫---requests库的用法详解
2020/09/28 Python
HTML5 input placeholder 颜色修改示例
2014/05/30 HTML / CSS
详解移动端html5页面长按实现高亮全选文本内容的兼容解决方案
2016/12/03 HTML / CSS
植村秀美国官网:Shu Uemura美国
2019/03/19 全球购物
秋季运动会加油稿200字
2014/01/11 职场文书
学校出纳员岗位职责
2014/03/18 职场文书
给校长的建议书500字
2014/05/15 职场文书
党员三严三实心得体会
2014/10/13 职场文书
2014年高校辅导员工作总结
2014/12/09 职场文书
MySQL库表名大小写的选择
2021/06/05 MySQL