利用contenteditable实现textarea即支持tags标签也支持文本的实现方式
前言
最近接到了一个新的需求,需要做一个textarea的文本框,即支持tags标签的输入,也要支持普通文本的输入,在github上找了很多插件,都没能找到合适的,具体需求如下:
利用contenteditable属性
这是html5中的属性,富文本编辑器的底层实现原理就是基于此属性
浏览器兼容性问题
可以适配市面上大多数的浏览器,即便是ie浏览器
使用方法
直接写在dom元素中即可
<div id="contentEdit" contenteditable="true"></div>
此时便可以编辑这个div,往里面输入文字等,最终都会转化为此dom元素的innerText和innerHTML。对于数据处理,只需要拿取innerText中的值就可以了。
伪造成一个文本框
利用这个属性就可以伪造成一个文本框了,设置它的样式即可。
#contentEdit {
outline: 0;
border: 1px solid #a0b3d6;
border-top: 0px;
padding: 10px 10px;
height: 200px;
}
#contentEdit:empty:before {
content: '请在此处进行公式编辑';
color: gray;
}
效果如下图所示:
取值和传递值
我们可以在div中增加一个失去焦点事件,从而拿取此dom元素的innerText,进行取值。
取值没问题了,但是一个textarea文框,或者是一个成熟的业务模块,还需要支持修改值和传递值,这个时候我们就需要定位光标所在的地方,以此进行在光标所在的位置插入值。getSelection方法可以帮助我们拿到页面上的光标信息。
Window.getSelection
返回一个 Selection 对象,表示用户选择的文本范围或光标的当前位置。
语法
const selection = window.getSelection() ;
selection 是一个 Selection 对象。如果想要将 selection 转换为字符串,可通过连接一个空字符串(“”)或使用 String.toString() 方法。
示例
function foo() {
let selObj = window.getSelection();
console.log(selObj);
let selRange = selObj.getRangeAt(0);
// 其他代码
}
拿到光标之后,我们就可以进行插入的动作了,此时,插入的html可以任意编辑标签元素,来达到tags的效果。
function foo() {
let selObj = window.getSelection();
console.log(selObj);
let selRange = selObj.getRangeAt(0);
// 其他代码
}
这里就可以写html,可以进行css的编写。
至此,通过contenteditable定制一个可以自定义功能的textarea便完成了。
最终效果:
括号的匹配问题
因为我这里的需求是拿到数据后转化一层,转正逻辑表达式,所以就涉及到了括号的匹配问题,可以用数据结构栈的思想去解决,大家可以看我的下一篇博客。