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


    想@到谁?   至少有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

  • 相关阅读:
    第3节:vue-router如何参数传递
    第2节:vue-router配置子路由
    Vue-router笔记 第1节:Vue-router入门
    vue-cli模版解读
    Vue-cli项目结构讲解
    vue-cli笔记
    实例属性
    实例方法-扩展器-生命zhou
    父子组件
    伪数组转为数组 Array.prototype.slice.call(arguments)
  • 原文地址:https://www.cnblogs.com/idche/p/1865085.html
Copyright © 2020-2023  润新知