zoukankan      html  css  js  c++  java
  • 【分享】微博 @ 符号的用户名提示效果。(想@到谁?)

    想@到谁?   至少有3处BUG,建议不要使用这段程序

    相信你老早就在腾讯或者新浪的微博上体验到@符号的魅力了

    这里有一个简单的实现,浏览器兼容还好。

    下载演示文件


     
     
    实现思路
    我们可以用onkeyup事件监测文本框是否输入了一个@符号,如果输入了就找到@符号在页面上的绝对位置,弹出选择框。
     
    在操作textarea的时候光标的绝对位置是个麻烦事。
     
    如何获取textarea 里的光标的位置?
     
    请结合图片看下面的实现方法。

     
      A:是一个textarea 

      B:当前光标位置

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

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

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

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

     这样把获取光标位置转化为获取一个span元素的位置就好办很多了。

    简单吧!

     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, 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;
    }
    elsereturn 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();
    }
    returnfalse;
    }
    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();
    varchar= chars[2] ? chars[2] : '';
    D.$(config.valuepWrap).innerHTML
    = valuep.slice(0,valuep.length -char.length).replace(/\n/g,'<br/>').
    replace(
    /\s/g,'&nbsp;') + 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);
    }
    returntrue;
    }

    _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){
    returnfunction(){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();
    returnfalse;
    }

    return _this;

    }

    作者:idche

    原文地址:http://www.cnblogs.com/idche/archive/2010/10/30/1865085.html

  • 相关阅读:
    HearthBuddy投降插件2019-11-01的使用
    正则表达式在线分析 regex online analyzer
    Tips to write better Conditionals in JavaScript
    The fileSyncDll.ps1 is not digitally signed. You cannot run this script on the current system.
    Cannot capture jmeter traffic in fiddler
    JMETER + POST + anti-forgery token
    input type color
    HearthBuddy修改系统时间
    What are all the possible values for HTTP “Content-Type” header?
    UDK性能优化
  • 原文地址:https://www.cnblogs.com/idche/p/1865085.html
Copyright © 2011-2022 走看看