需解决的问题:

  1. Enter发送,Ctrl+Enter换行
  2. 中文输入回车问题
  3. 消息格式的显示(换行、预格式富文本)
  4. 消息发送后的显示滚屏

针对以上问题,逐一解决如下:

一、发送和换行问题

textarea中默认Enter和Shift+Enter换行,若需要改成Enter发送,需要监听键盘事件修改Enter默认行为。其中,手动插入换行符需要获取光标位置,并在当前输入位置插入换行符后保持光标位置后移至换行符后。

javascriptCopy code
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
quickSendMsg(e: KeyboardEvent) { const key = e.key.toLowerCase(); const isCtrlPressed = e.altKey || e.ctrlKey || e.metaKey || e.shiftKey; const isShiftPressed = e.shiftKey; if (key === 'enter') { if (!isCtrlPressed) { e.preventDefault(); this.sendMsg(this.inputMsg); } else { if (!isShiftPressed) { textPosition(e.target, '\n', false); } } } }
quickSendMsg(e: KeyboardEvent) { const key = e.key.toLowerCase(); const isCtrlPressed = e.altKey || e.ctrlKey || e.metaKey || e.shiftKey; const isShiftPressed = e.shiftKey; if (key === 'enter') { if (!isCtrlPressed) { e.preventDefault(); this.sendMsg(this.inputMsg); } else { if (!isShiftPressed) { textPosition(e.target, '\n', false); } } } }

以上代码引用了光标位置控制插件的实现,参考:https://github.com/ifuyun/textposition

二、中文输入问题

在中文输入状态,输入Enter会直接转为输入英文,若不进行控制,将会发送消息且内容为当前中文输入法输入前的内容。

通过compositionstart和compositionend判断中文输入状态:

javascriptCopy code
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
document.getElementById('msgInput').addEventListener('compositionstart', (e) => { this.inputFlag = true; }, false); document.getElementById('msgInput').addEventListener('compositionend', (e) => { this.inputFlag = false; }, false);
document.getElementById('msgInput').addEventListener('compositionstart', (e) => { this.inputFlag = true; }, false); document.getElementById('msgInput').addEventListener('compositionend', (e) => { this.inputFlag = false; }, false);

在发送前判断是否中文输入状态:

javascriptCopy code
  • 1
  • 2
  • 3
if (!this.inputFlag) { this.sendMsg(this.inputMsg); }
if (!this.inputFlag) { this.sendMsg(this.inputMsg); }

三、消息格式显示问题

两方面,针对发出的消息,需要处理的仅有换行的显示(不考虑图片等多媒体内容),而针对收到的消息,需要进行富文本形式的展示。前者,通过pre标签原样显示文本;后者,通过safeHtml pipe显示预格式富文本,或引入类似markdown等指定格式的解析器。

四、消息滚屏

消息发送后,滚屏至消息展示区域底部,以展示最新的消息。

javascriptCopy code
  • 1
  • 2
  • 3
  • 4
const {scrollHeight, offsetHeight} = msgBoxEle; setTimeout(() => { msgBoxEle.scrollTop = scrollHeight - offsetHeight; }, 0);
const {scrollHeight, offsetHeight} = msgBoxEle; setTimeout(() => { msgBoxEle.scrollTop = scrollHeight - offsetHeight; }, 0);

至此,问题全部解决。