<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>微博@功能实现demo</title>
<style>
.hide {
display:none;
}
.atLayer {
width:500px;
height:300px;
font-size:12px;
font-family: Tahoma, 宋体;
}
.who {
border:1px solid #ccc;
position:absolute;
z-index:9999999;
background:#fff;
padding:1px;
float:left;
}
.who li {
display:block;
overflow:visible
}
.who li a, .who li span {
display:block;
color:#666;
padding:0 10px;
display:block;
line-height:22px;
height:22px;
*width:150px;}
.who li a.hover_a{
text-decoration:none;
background:#eee;
}.copyText {
position: absolute;
padding:3px;
font-family: Tahoma, 宋体;
word-wrap: break-word;
outline: medium none;
z-index:-999999999;
overflow-x: hidden;
overflow-y: auto;
}
</style>
<script src="http://www.jq22.com/demo/qqFace/js/jquery.min.js"></script>
<script type="text/javascript">
(function($){
$.fn.selection = function(){//获取光标的精确位置
var s,e,range,stored_range;
if(this[0].selectionStart == undefined){
var selection=document.selection;
if (this[0].tagName.toLowerCase() != "textarea") {
var val = this.val();
range = selection.createRangecreateRange().duplicate();
range.moveEnd("character", val.length);
s = (range.text == "" ? val.length:val.lastIndexOf(range.text));
range = selection.createRange().duplicate();
range.moveStart("character", -val.length);
e = range.text.length;
}else {
range = selection.createRange(),
stored_range = range.duplicate();
stored_range.moveToElementText(this[0]);
stored_range.setEndPoint('EndToEnd', range);
s = stored_range.text.length - range.text.length;
e = s + range.text.length;
}
}else{
s=this[0].selectionStart,
e=this[0].selectionEnd;
}
var te=this[0].value.substring(s,e);
return {start:s,end:e,text:te}
};
})(jQuery);
function moveEnd(obj){//将光标移动到末尾
obj.focus();//obj获焦
var len = obj.val().length;//obj的值的个数
//创建选择区域
if(obj.createTextRange){//IE浏览器
var range = obj.createTextRange();
range.moveEnd("character",-len)
range.moveEnd("character",len-1);
range.moveStart("character", len-1);
range.select();
}else if (typeof obj.selectionStart == 'number' && typeof obj.selectionEnd == 'number'){
obj.selectionStart = obj.selectionEnd = len;
obj.focus();
}
}function insertVal(obj){//将值插入TESTAREA
$(".before").data("before",areaVal.substring(0,selection));//将光标之前的内容保存
$(".after").data("after",areaVal.substring(selection));//将光标之后的内容保存
moveEnd($(".atLayer"))
var before=$(".before").data("before");
var after=$(".after").data("after");
$(obj).parents(".who").hide();
$(".atLayer").val(before.substring(0,selection-selectNum)+$(obj).text()+" "+after)
$(".atLayer").focus();
}//start
$(function(){
if($(".atLayer").length>0){//如果有atLayer就插入基本结构//这里是@用户列表的弹窗,样式也可以在这里修改等等 2017/0/23
var str = '<ul class="who hide"><li><span>你想@谁?</span></li><li class="testLI">'
+'</li></ul><div class="wrapDiv hide"> </div><div class="copyText"> </div>'
+'<div class="before"></div><div class="after"></div>';//end
$("body").append(str);
$(".copyText").css({//设置COPY文本框的基本CSS
width:$('.atLayer').width(),
height:$('.atLayer').height(),
left:$('.atLayer').offset().left,
top:$('.atLayer').offset().top+15
})
}$(".atLayer").keyup(function(){//键盘事件
countWorld()
})$(".who .testLI a").live('hover',function(){//给每一个LI A绑定HOVER添加CLASS事件
$(this).addClass("hover_a").siblings("a").removeClass("hover_a")
})$(".atLayer").keydown(function(event){
var $hover_a=$(".who .testLI a.hover_a");
if($(".who:visible").length>0 && event.keyCode==40){//如果按下键
$(".who .testLI a").eq($hover_a.index()+1)
.addClass("hover_a").siblings("a").removeClass("hover_a");
event.keyCode==0;
return false;
}if($(".who:visible").length>0 && event.keyCode==38){//如果按上键
if($hover_a.index()!=0){
$(".who .testLI a").eq($hover_a.index()-1)
.addClass("hover_a").siblings("a").removeClass("hover_a");
}
event.keyCode==0;
return false;
}if($(".who:visible").length>0 && event.keyCode==13){//如果按回车
event.keyCode==0;
insertVal($hover_a)
return false;
}})
if($(".who:visible").length>0){
alert($(".who .testLI").children().eq(0).text());
}//if($.browser.msie){//如果是IE就用鼠标键盘事件去调用
$(".atLayer").click(function(){//点击testarea的时候触发
countWorld()
})
//}else{
// $(".atLayer").focus(function(){//获焦时触发
// setInterval(countWorld,200);
// })
//}
$(".who .testLI a").live('click',function(e){
insertVal(this)
})})
//end
function countWorld(){selection=$(".atLayer").selection().start;//光标的位置
areaVal=$(".atLayer").val();//testarea的值
$num=0;if(selection < 20){//如果值的个数小于20那就等于他本身
$num=selection;
}else{
$num=21;
}select10=areaVal.substring(selection-$num,selection);
selectNum=$num-1-(select10.lastIndexOf("@"));//取得离光标最近的@之间的字符数量
textINt=areaVal.substring(selection-selectNum,selection);//取得离光标最近的@之间的字符
var ifVal=$(".wrapDiv").text()//取得值下面会对比$(".copyText").html(areaVal.replace(/@/g,"<span>@</span>").replace(/\n/g,"<br/>").replace(/\s/g,"<i style='padding:0 3px'></i>"))
//if(/@/.test(select10) && textINt.indexOf(" ")==-1 && textINt!='' && $(".atLayer:visible").length>0){ //如果字符串里有@并且没空格的话
if(/@/.test(select10) && $(".atLayer:visible").length>0){$atStr=areaVal.indexOf(areaVal.substring(selection-selectNum-1,selection-selectNum));
$atNum=areaVal.substring(0,selection).match(/@/g).length;//获取坐标位置
var $spanLeft=$(".copyText span").eq($atNum-1).offset().left;//span的LEFT位置
var $spanTop=$(".copyText span").eq($atNum-1).offset().top;//span的top位置
//end
$(".who").show().css({left:$spanLeft,top:$spanTop});if(ifVal!=textINt && textINt!=''){
//正式环境使用这里
//正式的情况下数据时ajax从后台获取的,这里为了测试方便先注释掉了,正式环境返回的json格式如下
// data = [{nickname:22},{nickname:333},{nickname:444}]/* $.post('index.php?c=user&c=getUsers',{'at':textINt},function(data){
$(".who .testLI").html('');
$(data).each(function(i,n){
$(".who .testLI").append("<a href='javascript:;'>"+n.nickname+"</a>");
})$(".who .testLI a").first().addClass("hover_a");//给第一个添加选中状态
},'json')*/
//测试使用 2017/02/23
data = [{nickname:'小强'},{nickname:'小明'},{nickname:'姐姐'}];
//每次追加前清空testLI标签里的数据
$(".who .testLI").html("");
$.each(data,function(i,n){
$(".who .testLI").append("<a href='javascript:;'>"+n.nickname+"</a>");
});
$(".who .testLI a").first().addClass("hover_a");//给第一个添加选中状态
//end
}}else{
$(".who").hide();
}$(".wrapDiv").text(textINt)
}
</script>
</head>
<body>
<textarea class="atLayer" style="margin-top: 300px;margin-left:200px;"></textarea>
</body>
</html>
转载于:https://my.oschina.net/yonghan/blog/844376