IM输入框 技术实现思路 Web版 日常水帖前奏 不知道现在对于你这边还有没有用, 正好我们最近在做一个Web版的IM即时通讯工具.其中就有涉及到输入框的处理... 主要的有一些小困难的可能是对于文本和图片已经文件的混排.例如: 在文本中插Emoji 插入图片 插入文件 或者是输入link的时候需要自动解析等等 主要技术点 对于这样的需求其实是很合理的, 毕竟谁都不喜欢选择个文件都不确定一下就自动发送出去了; 要是一不小心发错了那不是很尴尬.. 来说说技术技术点吧:对于传统 Input 和 Textarea 那是不能这样的满足了, 那看样子我们现在需要做的是实现一个可编辑的输入框了, 要做到这一点有两种方式. 实现一个输入框 CSS实现给元素加上user-modify属性就可以对元素内容进行编辑了, 参考MDN地址 user-modify, 不过MDN也标注很清楚了This property has been replaced by the contenteditable attribute. 这种方式已经被contenteditable所替代了, 所以就不推荐了...当然如果你想了解, 可以查看 张鑫旭博客 contenteditable实现这是一个全局的枚举属性, 只需要你在想编辑的元素上加上 contenteditable=true 就可以了.就像这样 <div contenteditable></div> 那么你就可以在这个div上随意编写内容了, 就感觉很神奇...参考文档: MDN Contenteditable 看样子输入框是可以搞定了, 那么接下来就应该像输入框里面插入东西了~~~~ 怎么像输入框插入Emoji或者是图片 这里也需要用到两个东西, 第一个是document.execCommand 第二个是 Window.getSelection() document.execCommand这个东西允许运行命令来操纵可编辑内容区域的元素, 就意味着你如果是一个可编辑内容区域, 他就可以进行一些像 加粗 插入节点/文本 创建链接 包括 缩进等操作, 看样子这是我们需要的东西哈...参考链接: MDN execCommand 比如粘贴的时候我只需要纯文本, 你可以这样... // 粘贴事件 const handleOnPaste = (e) => { e.preventDefault(); const text = e.clipboardData.getData('text'); document.execCommand('insertText', false, text); }; 当然你也可以使用他来插入一些节点, 具体可以查看 MDN,那么看起来好像一切都可以实现了...其实不然, 这家伙也是需要在 可以编辑 并 聚焦的时候 在可以插入的, 有什么问题呢? 插入图片和emoji我们知道, 如果我们需要选择文件时候可以使用 input 并将 type="file" 就可以实现文件上传.不过这家伙一般是张这样的 如果你喜欢这样的样式, 恭喜你可以使用上面 document.execCommand 插入, 不过我猜很多人是不喜欢的, 那我看样子我们处理自己实现 可输入区域 还需实现 文件上传 呀. 额, 这倒是不用...我们可以将这个原有的 input 隐藏了, 然后我们自己搞一个元素, 点击他的时候打开 input 的上传是不是就可以了呢? import React, { useRef } from 'react'; function test() { const imgUpload = useRef(''); const handleClickImage = () => { imgUpload.current.click(); }; const imgOnChange = () => { // 文件操作 }; return ( <div> <button type="button" onClick={handleClickImage}>image</button> <input type="file" hidden ref={imgUpload} onChange={imgOnChange} /> </div> ); } export default test; 但是你会发现上面那玩意不起作用了呀, 解决方案... Window.getSelection()MDN的说明是 该对象表示用户选择的文本范围或插入符号的当前位置.我们可以利用 Window.getSelection() 下面的 getRangeAt(0)来获取需要插入的位置. 并使用下面方式来插入一个节点 const img = document.createElement('img') img.src = 'xxx' const range = Window.getSelection().getRangeAt(0) ange.insertNode(img); 其他问题 如果你遇到点击失去焦点,插入错误的情况...很简单, 只需要取输入框的range对象就可以了
IM输入框 技术实现思路 Web版
日常水帖前奏
不知道现在对于你这边还有没有用, 正好我们最近在做一个Web版的IM即时通讯工具.其中就有涉及到输入框的处理...
主要的有一些小困难的可能是对于文本和图片已经文件的混排.
例如: 在文本中插Emoji 插入图片 插入文件 或者是输入link的时候需要自动解析等等
主要技术点
对于这样的需求其实是很合理的, 毕竟谁都不喜欢选择个文件都不确定一下就自动发送出去了; 要是一不小心发错了那不是很尴尬..
来说说技术技术点吧:
对于传统
Input
和Textarea
那是不能这样的满足了, 那看样子我们现在需要做的是实现一个可编辑的输入框了, 要做到这一点有两种方式.实现一个输入框
CSS实现
给元素加上user-modify属性就可以对元素内容进行编辑了, 参考MDN地址 user-modify, 不过MDN也标注很清楚了
This property has been replaced by the contenteditable attribute.
这种方式已经被contenteditable
所替代了, 所以就不推荐了...当然如果你想了解, 可以查看 张鑫旭博客
contenteditable实现
这是一个全局的枚举属性, 只需要你在想编辑的元素上加上 contenteditable=true 就可以了.就像这样
那么你就可以在这个div上随意编写内容了, 就感觉很神奇...
参考文档: MDN Contenteditable
看样子输入框是可以搞定了, 那么接下来就应该像输入框里面插入东西了~~~~
怎么像输入框插入Emoji或者是图片
这里也需要用到两个东西, 第一个是
document.execCommand
第二个是Window.getSelection()
document.execCommand
这个东西允许运行命令来操纵可编辑内容区域的元素, 就意味着你如果是一个可编辑内容区域, 他就可以进行一些像
加粗
插入节点/文本
创建链接
包括缩进
等操作, 看样子这是我们需要的东西哈...参考链接: MDN execCommand
比如粘贴的时候我只需要纯文本, 你可以这样...
当然你也可以使用他来插入一些节点, 具体可以查看 MDN,
那么看起来好像一切都可以实现了...
其实不然, 这家伙也是需要在
可以编辑 并 聚焦的时候
在可以插入的, 有什么问题呢?插入图片和emoji

我们知道, 如果我们需要选择文件时候可以使用
input
并将type="file"
就可以实现文件上传.不过这家伙一般是张这样的如果你喜欢这样的样式, 恭喜你可以使用上面
document.execCommand
插入, 不过我猜很多人是不喜欢的, 那我看样子我们处理自己实现可输入区域
还需实现文件上传
呀.额, 这倒是不用...
我们可以将这个原有的
input
隐藏了, 然后我们自己搞一个元素, 点击他的时候打开input
的上传是不是就可以了呢?但是你会发现上面那玩意不起作用了呀, 解决方案...
Window.getSelection()
MDN的说明是 该对象表示用户选择的文本范围或插入符号的当前位置.
我们可以利用
Window.getSelection()
下面的getRangeAt(0)
来获取需要插入的位置.并使用下面方式来插入一个节点
其他问题
如果你遇到点击失去焦点,插入错误的情况...
很简单, 只需要取输入框的
range
对象就可以了