本来上一篇比较偷懒,多谢“ 弦”指出问题。
那个想法之前我也想过,当时考虑到很多东西,觉得很麻烦。所以就放弃了,再加上当时是基于新浪微博的,翻了两次没看到要的东西,索性就写了出来,现在想想这种思想着实是不可取。写出来是与各位共勉.
所以我抽时间写了这版,比我想像的简单的多了...
*由于本人写作基于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>