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

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

  已经解决 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