本文共 2082 字,大约阅读时间需要 6 分钟。
需求分析:
最近需要制作一个简单的用户评论输入框,在网上找了一些富文本输入框,但是它们的功能太多,不适合自己的需求,于是决定自己动手实现一个简易的富文本输入框。
第一步:
想要实现富文本输入框并不是难事,在<div>标签内加入 contenteditable="true" ,这个div元素就可以编辑了,而且它的innerhtml 就是保留格式的html文本。
第二步:
只需要写一些css代码给div元素设计一些简单的样式,就可以让输入框变得美观。
实现按下tab键后增加四个空格的功能:
在不写额外代码的情况下,按下tab键,光标会离开编辑框,这是默认行为。所以需要监听按下tab的事件,在处理函数中取消浏览器的默认行为。
然后要想在光标处按下tab键,插入四个空格,就需要了解浏览器的光标对象。
在浏览器中,如果我们选中一片区域,就是看到的变蓝色的区域,这块区域是一个selection对象,selection在ff和chrome浏览器可以直接用 window.getSelection()获取,在HTML里面,selection只有一个的,它是有开始和结束的。现在在页面上随意选中一些元素,按F12,在console 中输入window.getSelection(); 就可以看到这个selection对象的全部成员。
其中anchorNode (baseNode)是选择区域的开始节点,focusNode (extendNode)是选择区域的结束节点,注意: 这里的开始表示按下鼠标的位置,结束指的是放开鼠标的位置,anchoNode不一定在focusNode的前面,因为有的区域可能是从后往前选的。
anchorOffset 返回一个数字,其表示的是选区起点在 anchorNode 中的位置偏移量。
focusOffset 返回一个数字,其表示的是选区终点在 focusNode 中的位置偏移量。
isCollapsed 返回一个布尔值,用于判断选区的起始点和终点是否在同一个位置。
rangeCount 返回该选区所包含的连续范围的数量。
从type可以看到selection的种类其实是range对象
具体的信息可以在 中查看,基本包含所有信息。
只得到selection对象是不能对选区进行操作的,很多属性都是只读权限,要对选区进行修改,就需要获得选取的range对象,range提供了很多的函数,可与对选取进行修改。
对选取的修改有两种方式:
1、获取 range对象 是通过 window.getselection().getRangeAt(0) 获取的,然后调用range的成员函数进行修改
2、直接创建一个新的range对象,如下:range = document.createRange();
然后对新建的range对象进行需要的修改,最后将selection的原有range删除,将新建的range对象加进去,替换掉原来的。
selection.removeAllRanges();selection.addRange(range);
再来补充range的知识:
commonAncestorContainer 是选中元素共同的祖先元素
endContainer是结束元素 endOffset是在endContainer中的结束位置
startContainer是开始元素的位置 startOffset是 startContainer 中的开始点位置。
collapsed 是表示起始和终止是否在同一个位置,如果不再,表现的是选中的区域,如果在同一个位置,显示的就是输入光标。
具体的成员函数和变量的使用方法详见
..........................................................................................................................................................................................................................................
我实现按下tab 增加4个空格的思路是 : 自己构造一个文本标签,里面的内容是4个   ,将这个元素插入到光标之后,就可以实现四个空格的缩进。(前提是这个文本框是富文本编辑框)
以下我附上自己实现的富文本编辑框的全部代码,使用的vue,可以直接放在vue的一个组件里, 我实现的文本框还带有一些收缩展开的css动画。
以下是js部分,有详细的注释
实现按下tab进行缩进的是tab()函数 ,event是监听的原生的tab按键对象
最后是css代码通过了解selection对象和range对象,以后想要给自己的编辑器添加定制的功能,都是比较类似的用法了。