微博@功能实现

本文介绍了一种实现在网页中使用@功能的方法,通过JavaScript监听输入框内的@符号,并显示匹配用户名供用户选择。该方案适用于微博等社交平台。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<!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">&nbsp;</div><div class="copyText">&nbsp;</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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值