现在的位置: 首页 > 综合 > 正文

浅谈微博输入框一些小功能– @基于光标的定位问题(续集)

2013年05月17日 ⁄ 综合 ⁄ 共 3888字 ⁄ 字号 评论关闭

本来上一篇比较偷懒,多谢“ ”指出问题。

那个想法之前我也想过,当时考虑到很多东西,觉得很麻烦。所以就放弃了,再加上当时是基于新浪微博的,翻了两次没看到要的东西,索性就写了出来,现在想想这种思想着实是不可取。写出来是与各位共勉.

所以我抽时间写了这版,比我想像的简单的多了...

*由于本人写作基于chrome浏览器 ,所以如果你们发现任何问题可留言告诉我

思路:

很多雷同于上篇。不同的是计算定位的方式

当文本域输入,取得光标位置,判断当前输入的是否@,然后判断显示弹出层。

如果是@则截取到光标位置的字符串,并将他替换后赋给span标签

然后在其后插入行内元素b标签, 通过b的位置就知道需要的定位了(left)。

然后是top,这个需要判断滚动调高度,因为如果有滚动应该计算入内..使其定位在正确的位置

原理很简单但是有几个需要注意的地方:

一个是:css中word-wrap: break-word;word-break: break-all;

另一个是注意替换textarea中的\n,如果不替换在html中将做空格显示:

接下来放上代码 这回注释的比较详尽,因为变量命名没有丝毫规则 只去了一个首字母;

/*
* date:2012-9-27
* blog:http://www.cnblogs.com/businessdiv/
*/
function txtRange (b, s, h, bi) {
    //整体盒子
    var oBox = document.getElementById(b);
    //弹出层
    var oAlert = document.getElementById(s);
    //隐藏层
    var oClone = document.getElementById(h);
    //文本域
    var oText = oBox.getElementsByTagName('textarea')[0];
    //定义left top变量
    var oLeft = 0;
    var oTop = 0;
    //替换文本域\r\n的正则
    var reg = new RegExp("[\r\n]", "g");
    //向隐藏层中插入span b;
    oClone.innerHTML = "<span></span><b>|</b>";
    //获得oClone中 span/b标签的引用
    var span = oClone.getElementsByTagName("span");

    var o = oClone.getElementsByTagName("b")[0];
    //绑定keyup
    oText.onkeyup = function (e) {
        keyFun(e)
    };
    //绑定click
    oText.onclick = function (e) {
        keyFun(e)
    }
    function keyFun(e){
        var e = e || event;
        var t = e.srcElement || e.target;
        var v = t.value;
        var l = v.length;
        var b = range(t);
        //截取到光标位置的字符串
        var s = v.substring(0, b);
        //将文本域中的\n替换成br
        var p = s.replace(reg, "<br>");
        //将内容插进去
        span[0].innerHTML = p;
        //判断光标位置-1的字符,判断是否显示执行之后的步骤
        if(v.charAt(b-1) == "@"){
            //如果是@ oAlert层显示 并且获取到b的offsetLeft 
            oAlert.style.display = "block";
            oLeft = o.offsetLeft;
            //减去文本域滚动高度是为了实现click定位的问题
            var oT = Math.floor(o.offsetTop) + 21 - t.scrollTop;//计算oTop 最大高度不得大于文本域高度
            oTop = oT > 100 ? 100 : oT;
            oAlert.style.left = oLeft + "px";
            oAlert.style.top = oTop + "px";
        }else{
            //非@时的ajax操作 就不详尽了 写个大概思路
            /*
            //得出光标之前最近的一个@到光标之间的字符位置并保存到ti
            //这步的计算可以在之前判断是否是@的时候 把位置记录下来 避免下面的循环。就不一一阐述了
            var ti = 0;
            for(var i = b;i--;){
                if(s.charAt(i) == "@"){
                    ti = i;
                    break;
                }
            }
            //然后取出ti到b中间的字符ajax
            //其中分:默认列表 和 请求列表;然后就是具体的操作了
            //oClone中还需要绑定个click 方便把选中的文字插入到@后并替换 
            //然后oAlert隐藏
            */
            oAlert.style.display = "none";
        }    
    }
};

txtRange("txt", "show", "hide", 100);

function range(obj, curr) {
    if (typeof(obj.selectionStart) == "number") {
        start = obj.selectionStart;
        end = obj.selectionEnd;
    //判断是否支持doucment.selection
    } else if (document.selection) {
        var range = document.selection.createRange();
        if (range.parentElement().id == obj.id) {
            var range_all = document.body.createTextRange();
            range_all.moveToElementText(obj);
            //range_all.compareEndPoints()比较两个端点
            //控制start相同。
            for (start = 0; range_all.compareEndPoints("StartToStart", range) < 0; start++){
                range_all.moveStart('character', 1);
            }
            //判断value中'\n'存在 && start就++
            for (var i = 0; i <= start; i++) {
                if (obj.value.charAt(i) == '\n') {
                    start++
                };
            }
            var range_all = document.body.createTextRange();
            range_all.moveToElementText(obj);
            //同上理
            for (end = 0; range_all.compareEndPoints('StartToEnd', range) < 0; end++){
                range_all.moveStart('character', 1);
            }
            for (var i = 0; i <= end; i++) {
                if (obj.value.charAt(i) == '\n') {
                    end++
                };
            }
        }
    }
    if(curr){
        return [start, end]
    }else{
        return end
    }
}

 

接下来是html代码还有css:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>标题</title>
<style type="text/css">
    #txt{width:500px;margin:50px auto;position:relative;background:#ccc;font: normal 14px/21px Tahoma,Arial;}
    #txt textarea{height:100px;display:block;line-height:21px;overflow-y:scroll;width:500px;padding:0;}
    .txtBox{position:absolute;width:50px;height:50px;background:#ccc;left:0;top:0;display:none;}
    #hide, #txt textarea{font: normal 14px/21px Tahoma,Arial;}
    #hide{height:100px;line-height:21px;overflow-y:scroll;width:500px;position:absolute;left:0;top:0;z-index:-1;border:1px solid #fff;font-style:normal;word-wrap: break-word;word-break: break-all;}
    #hide b{width: 0;overflow: hidden;line-height:21px;}
    #hide span{}
    *{margin:0;padding:0;}
</style>
</head>
<body>
    <div id="txt">
        <textarea name="" id=""></textarea>
        <div class="txtBox" style="width:50px;" id="show">1</div>
        <div id="hide"></div>
    </div>
    <script type="text/javascript" src="order.js"></script>
</body>
</html>

抱歉!评论已关闭.