实现富文本编辑框的一些小收获~

1,292 阅读2分钟

最近需要实现一个简单的富文本框,主要功能有:

  • 表情的插入
  • 发送公告,获取发送框中的纯文本内容

实现的一些细节

可以使用div+contenteditable模拟textarea
设置spellcheck属性关闭拼写检查,红色波浪线就不再显示了

<div contenteditable="true" spellcheck="false">这是可编辑的段落。请试着编辑文本。</div>

注意: Internet Explorer 9 及更早IE版本不支持 spellcheck 属性。

统一插入文本的样式

当我在可编辑的div中换行的时候,发现会插入<div><br></div>,继续输入内容,会把<br>替换成我们输入的内容。

所以,从网页或者word复制的内容也可以统一成这种形式。(我参考了下qq空间发说说的编辑框,也是这么实现的)

思路如下:

  • 1.监听paste事件
  • 2.然后从clipboardData中通过getData('text')方法获取内容
  • 3.将拿到的纯文本中的换行和空格用正则匹配
  • 4.用event.preventDefault()取消默认粘贴操作,手动插入我们format后的数据
target.addEventListener('paste', (event) => {
    //在ie下要使用`window.clipboardData`而不是`event.clipboardData`
    let paste = (event.clipboardData || window.clipboardData).getData('text');
    //格式化获取的数据并手动插入
    //...
    event.preventDefault();
});

补充: 一开始有过另一种思路,在getData('text.html')获取html字符串,然后再通过正则匹配去掉属性和样式,替换标签,不过始终匹配得不够完美,再加上我的需求比较简单,所以选了上面那种实现方式。

神奇的空格

我一直以为空格就是&nbsp;,结果在正则匹配xxx.replace('/\s/g', '&nbsp;')后,发现页面直接把&nbsp;显示了出来。
查阅资料,发现了原来有两种空格。

Unicode 十进制值 描述 拉丁字母
U+0020 160 空格 基本拉丁字母
U+00A0 32 不换行空格 拉丁字母-1 辅助

我们通过键盘点击空格键输入的空格,就是U+0020,普通半角空格,显示为空白字符。

另外一种U+00A0称之为不换行空格。用途是禁止换行。 在 HTML 网页显示中,会自动合并多个连续的空白字符;但是如果使用不换行空格,就会禁止合并,因此也称之为硬空格。在网页显示中其转义字符为&nbsp;

// 举个栗子
let dom = document.querySelector('div')
// 自动合并空格
dom.innerText = 'y  u'
dom.innerText = 'y\u0020\u0020u'
dom.innerText.length // 3
// 禁止合并
dom.innerText = 'u\u00a0\u00a0i'
// 或者使用空格的转义字符 &nbsp; ,此时需要用 innerHTML
// or dom.innerHTML = 'u&nbsp;&nbsp;i'
dom.innerText.length // 4

tips: 用 &nbsp;只有设置为innerHTML有效,用\u00a0设置textContent, innerHTML, innerText都有效。