网上接html开发业务,业务开发情境之:实现一个@功能

最近接到了一个业务需求,让用户能够通过网页聊天框的方式在线完成交易,一个用户可能有多个业务群,其中一个功能就是要@人,@这个功能在现实的应用中经常可以遇到,比如微博、QQ都有@功能,今天我们就以前端的方式谈谈怎么一步步实现一个@功能。

@功能涉及到的原生API

obj.selectionStart获取光标位置

obj.setSelectionRange(n, n)设置光标位置

keyup事件和keydown事件

1.搭建我们的html文件

几个地方特别说明下:实际操作中,我们出现了@选框要实时更新列表数据,在这个dome中我们先用静态列表代替,效果是一样的。然后这个pre是用来定位@选框用的,注意pre大小,字体要和输入框一样,并将pre绝对定位到页面的左上角,并设置不可见。

@用户

  • 陆小凤
  • 西门吹雪
  • 百晓生
  • 张无忌
  • 赵敏
  • 段誉
  • 虚竹
  • 段德
  • 周杰伦
  • 张学友
 
 

2、实现@选框出现,并将@选框定位到当前光标右下角

具体实现思路:检测键盘的左边是否是@字符,如果有的话,将输入框光标前面的内容复制一份到pre,并在pre后面增加一个span,这个sapn用来协助定位@选框的。我们算出这个span相对于页面左上角的left和top,就是等下@选框相对于文本框的left和top的距离,因为我们@选框是绝对定位相对于body,所以在加上文本框相对于body的offsetLeft和offsetTop就是我们@选框所要定位的left和top了。

//全局定义一个变量为光标位置

var cursor;

//文本框绑定keyup事件,检测输入

textapp.addEventListener('keyup', function(e){

//获取光标

cursor = textapp.selectionStart;

// 当前光标所在位置的前一位为@字符,出现@选框

if(textapp.value.substring(0,cursor).charAt(cursor-1) === '@'){

// 判断最后一个字符是否为@

pre_text.innerHTML = textapp.value.substring(0,cursor);

pre_text.innerHTML += '';

var span = document.getElementById('proxy');

var conX = textapp.offsetLeft;

var conY = textapp.offsetTop;

var spanX = span.offsetLeft + conX;

var spanY = span.offsetTop + conY;

selectuser.style.left = spanX + 'px';

selectuser.style.top = spanY + 'px';

selectuser.style.display = 'block';

//设置@选框的默认样式

listSet();

}else{

selectuser.style.display = 'none';

}

})

// @框默认设置

function listSet() {

var list = $('#selectlist');

list.focus();

$('#selectlist').find('li').eq(0).addClass('hover').siblings('li').removeClass('hover');

$('#selectuser').scrollTop(0);

}

3.键盘直接操作@选框

当我们的@选框出现了,并且定位好了,出现在我们想要的位置了,我们直接用键盘上下去选择所要@的人了(鼠标点击选中情况等下介绍)。这里我们要考虑的点有两个:1.当我们光标在输入框最后,我们按上下左右光标就会变化位置。2.选择之后光标位置的变化。

1的解决办法是:我们光标位置的变化是在keydown的时候执行的,keydown是先于我们的keyup之前执行的,所以我们就要在keydown的时候就阻止默认,防止光标移动

textapp.addEventListener('keydown', function(e){

//建立在@选框出现的情况下

if(selectuser.style.display == 'block'){

var code = e.keyCode;

//左右回车时阻止默认,防止光标移动

if(code == 38 || code == 40 || code == 13){

e.preventDefault();

}

}

})

2.选中@人后,我们用setSelectionRange来设置光标的位置,将下面这段代码输入框keyup绑定事件里面,放在最前面

// 当@选框存在时,判断键盘上移,下移,以及回车选中事件

if(selectuser.style.display == 'block'){

var code = e.keyCode;

if(code == 38){

// 上移

preCode();

return;

}else if (code == 40){

// 下移

nextCode();

return;

}else if(code == 13){

//回车选中@人

var textname = '';

$('#selectlist').find('li').each(function(){

if($(this).hasClass('hover')){

textname = $(this).html();

}

});

//@完后文本框显示内容

$('#app').val(getText($('#app').val(), cursor, textname));

//添加后光标的位置

var n = textname.length + 1 + cursor;

//设置光标的位置

textapp.setSelectionRange(n, n);

//选中后隐藏@选框

$('#selectuser').hide();

return;

}

}

上面这段代码我们用到了三个函数

// 键盘上移

function preCode() {

var index = $('#selectlist').find('.hover').index();

if(index == 0){

return;

}else{

index--;

$('#selectuser').scrollTop(index * 26);

$('#selectlist').find('li').eq(index).addClass('hover').siblings('li').removeClass('hover');

}

}

// 键盘下移

function nextCode() {

var len = $('#selectlist').find('li').length;

var index = $('#selectlist').find('.hover').index();

if(index == len-1){

return;

}else{

index++;

$('#selectuser').scrollTop(index * 26);

$('#selectlist').find('li').eq(index).addClass('hover').siblings('li').removeClass('hover');

}

}

//@人的文本格式,为后面加一个空格,后面用到

function getText(app, cursor, textname) {

var text1 = app.substring(0, cursor);

var text2 = app.substring(cursor);

return text1 + textname + ' ' + text2;

}

4.提交操作时,取出有效的@人

当我们消息输入完成后,点击发送(我们这里用个提交按钮)。我们要检测这个消息中是否有@人,并把当前这条消息有效的@人取出来,这里注意并不是说我们之前选中了@某个人后就有效了,可能在这个人的名字中我又输入了其他的字符。所以我们要在发送消息的时候做一次检查,把有效的@人提取出来,并且以后台规定的数据格式。(我们暂且规定为数组吧)。

// 提交

$('#submit').on('click', function() {

var msg = $('#app').val();

//检测输入框是否为空

if(msg === ''){

alert('内容不能为空!');

return;

}

//返回有效@人列表

var arr = handleMsg(msg);

});

//操作信息提取有效@人

function handleMsg(msg) {

//存放有效@人id的数组

var At = [];

//正则验证吧以@开头空格结束的选出来已数组的形式

var arrAt = msg.match(/@{1}([\u4e00-\u9fa5]|\w)+\s{1}/g);

//说明没有@人,直接韩慧

if(arrAt === null){

console.log('没有选中@的人!');

return At;

}

// 对arrAt数组即当前信息@人的列表进行遍历

for (var i = 0; i < arrAt.length; i++) {

var username = arrAt[i].replace('@', '').trim();

// 对比当前群组人选

var grounpuser = $('#selectlist').find('li');

for (var j = 0; j < grounpuser.length; j++) {

//如果名字相同,则把id放进数组内容

if(username == grounpuser.eq(j).html()){

var uid = grounpuser.eq(j).attr('uid');

At.push(uid);

break;

}

};

};

return At;

}

完结

好了,一个@的功能已经基本实现了,剩下的就是通过ajax与后台的交互了。如果你觉得本篇文章对你有收获请赞下,也可以关注下我,分享工作,学习的前端个人感悟分享。github

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值