资讯专栏INFORMATION COLUMN

输入框插入表情的实现

TwIStOy / 465人阅读

摘要:还没结束上述例子中,在输入框中表情只能以文本的形式呈现。如果想在输入框中呈现输入的表情,该怎么办呢使用属性为的容器代替是必须的,因为中只能显示文本。

在普通的 textarea 中,只能显示普通的文本。如果简单的输入文本,textarea 便足以胜任。但是实际情况往往要复杂得多。

简单版本的插入表情

常见的版本一般都是使用 textarea,然后表情使用某种约定的文本格式代替,比如“你好啊[微笑]”。在呈现的时候,通过固定的文本解析方法将内容中的表情文本替换成图片。新浪微博中发微博的输入框就是如此。但是,在这有一点需要注意,如果只是简单的在文本的最后插入表情之类的预定好的文本格式,只需获取到到 textarea 的 value 然后做加法即可。

let editor = document.querySelect("#editor");
editor.value += "[微笑]";
没你想的这么简单

但实际情况却没有这么简单,因为用户可以自己选择光标的位置。当用户在某一段文本中间插入光标之后,可不是简单的加法了。在这种情况下,需要获取到光标所在位置,在这个位置上插入用来代替表情的文本,然后将光标设置到表情文本的后面。在这需要两个额外的方法:getCaretPositionsetCaretPosition

getCaretPosition/setCaretPosition

浏览器并没有提供直接获取光标位置的方法,需要我们变通的处理。浏览器基本上都支持文本框的select()方法,这个方法用于选中文本框中所有的文本,但是只能乖乖的拿到返回的所有文本。HTML5 添加了两个属性:selectionStart 和 selectionEnd 帮助我们更加顺利地获取选择的文本。这两个属性中保存的是基于0的数值,表示所选择的文本的范围,分别表示文本选区(选中的文本)开头和结尾相对整个文本内容的偏移量(在整个文本内容中的位置)。例如:

let editor = document.querySelector("#editor");
// 从第一个字符开始,选中三个字符
editor.selectionStart = 0;
editor.selectionEnd = 1;

// 从第三个字符开始选中三个字符
editor.selectionStart = 2;
editor.selectionEnd = 5;

说到这你可能要问了,这个光标有啥关系啊?别急,听我慢慢说。既然上述两个设置不同数字可以选择文本,那如果两个值设置成相同的数字,会怎么样呢?

// 从第三个字符开始选中零个字符
editor.selectionStart = 2;
editor.selectionEnd = 2;

起点和终点重合了!那么换个角度来描述就是:当我们在获取光标位置的时候,其实就是选中的文本范围起点和重点重合,相当于文本范围的起点偏移量其实就是光标所在的位置偏移量,所以此时selectionStart的返回值就是我们需要的结果。

更关键的是,当 End 和 Start 设置成相同值时,选区也是空的,起点和重点充电,就好像是设置了光标的位置。其实有一个简便的方法 setSelectionRange(start, end),原理相同。

当然有兴趣你也可以试试 End小于 Start的情况。上述这些在现代浏览器和 IE9+ 上都支持。

前端向来麻烦的还是浏览器的兼容问题。在低版本的 IE 中只能使用 document.selection 对象来模拟光标定位了。document.selection 只存在于 IE8 及更早的版本(可以使用 window.getSelection 代替),保存着用户在整个文档范围内选择的文本信息,但是无法确定用户选择的是页面中哪个部位的文本。要想取得选择的文本,首先需要创建一个范围(Range,IE9+ 支持 DOM Range API,但是 IE8及之前的版本不支持,但是有类似的概念,text range。这是 IE 专有的特性)。可使用 document.selection.createTextRange 来创建我们所需要的 text range。然后利用moveStart().aspx)将文本的范围的起点从当前位置(当前位置起点和重点是重合的)移动到文本的开头,然后计算选中文本的长度,这个长度值可以用来代替当前光标的位置。

let range = document.selection.createRange();
range.moveStart("character", editor.value.length);
cursurPosition = range.text.length;

设置光标位置思路类似,但是代码稍有不同:

let range = editor.createTextRange();
range.collapse(true);
range.moveEnd("character", pos);
range.moveStart("character", pos);
range.select();

总的来说,在 textarea 中获取和设置光标位置还是蛮简单的。讲到这里了,我想插入表情应该是很轻松的一件事情了

获取光标位置(文本范围前后重叠) -> 修改文本范围(或者手动拼接) -> 重新设置光标位置 

至此,表情插入功能的基本实现。

还没结束

上述例子中,在输入框中表情只能以文本的形式呈现。如果想在输入框中呈现输入的表情,该怎么办呢?使用 contenteditable 属性为 true 的容器代替 textarea 是必须的,因为 textarea 中只能显示文本。但是这就足够了吗?不,显然不够。没有了 textarea 则以为这没有了 setSelectionRange, selectionStart 和 selectionEnd。但是好在原理也是类似,依旧使用 Range API 或者 Text Range(IE8及其更低版本)。具体的可以参考这篇:html元素contenteditable属性如何定位光标和设置光标和这篇在可编辑的div中插入图片。 具体实现代码我就不贴了,大家可以自己思考捋一捋。举一反三,如果你真真正正地知道如何正确插入图片,那么插入复杂的 DOM 结构对你来说也是轻而易举。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/87840.html

相关文章

  • Web聊天工具富文本输入

    摘要:由于我们的富文本输入框比较简单,所以只需要处理两类数据即可,其一是普通的文本类型数据,包括表情其二则是图片类型数据。 最近折腾 Websocket,打算开发一个聊天室应用练练手。在应用开发的过程中发现可以插入 emoji ,粘贴图片的富文本输入框其实蕴含着许多有趣的知识,于是便打算记录下来和大家分享。 仓库地址:chat-input-box预览地址:https://codepen.io...

    iKcamp 评论0 收藏0
  • 基于uiwebview富文本编辑器实践

    摘要:背景最近我们微信读书将写想法换成了基于的富文本编辑器,遇到了不少问题,这里我将简单的介绍一下我们在开发过程中踩到的坑。 背景 最近我们微信读书将写想法换成了基于webview的富文本编辑器,遇到了不少问题,这里我将简单的介绍一下我们在开发过程中踩到的坑。 实现富文本编辑器有两个基本思路: 基于native实现:比如coretext或者textkit 基于uiwebview实现 第一...

    luzhuqun 评论0 收藏0
  • 用NodeJS打造多人在线聊天室(NodeJS & SocketIO & Expre

    摘要:技术栈项目背景这个项目主要是为了玩玩,项目的方向大概是做出类似的在线聊天系统。项目使用进行部署和管理,功能在不断的迭代开发中。首页用户列表用户中心注册登陆注销用户资料指定聊天室开始安装使用之前,请在中修改的安装路径。 技术栈:NodeJS & SocketIO & Express & EJS & MongoDB & Gulp 项目背景 这个项目主要是为了玩玩NodeJS,项目的方向大概...

    codecook 评论0 收藏0
  • 用NodeJS打造多人在线聊天室(NodeJS & SocketIO & Expre

    摘要:技术栈项目背景这个项目主要是为了玩玩,项目的方向大概是做出类似的在线聊天系统。项目使用进行部署和管理,功能在不断的迭代开发中。首页用户列表用户中心注册登陆注销用户资料指定聊天室开始安装使用之前,请在中修改的安装路径。 技术栈:NodeJS & SocketIO & Express & EJS & MongoDB & Gulp 项目背景 这个项目主要是为了玩玩NodeJS,项目的方向大概...

    Astrian 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<