最近用到contenteditable实现输入框,遇到了一些坑,记录一下
点击某个位置,触发插入a标签的点击事件,就会在输入框插入一个a标签,需求就是希望该a标签不可编辑,并且删除的时候(比如按Backspace键)需要将一整个a标签删除。
我一开始是按照下面代码来写的,外面的div设置了contenteditable="true"就是输入框,然后将a标签设置成contenteditable=“false”,这样设置之后a标签就变成不可编辑的了。此处有一个坑:a标签虽然不可编辑了,但是用鼠标点击a标签时,会发现鼠标的光标不见了,此时如果点击了输入框中的a标签之后再点击触发插入a标签的事件,会发现原本输入框中的a标签被嵌套了一个新的a标签,这个其实是和window.getSelection()有关系,所以我就给输入框添加了一个鼠标点击事件,只要点击这个不可编辑的标签,就把光标对焦到该标签最后。
<div contenteditable="true">
<a contenteditable="false">@1234</a>
</div>
但是这样还有一个兼容性的坑:火狐浏览器设置了contenteditable="false"的标签,用Backspace键是删不掉的,而在谷歌浏览器是可以把a标签整个删除的。
解决方法就是在a标签后面加​,这个是看不见的(不知到什么原理)
总结一下使用contenteditable实现输入框遇到过的坑:
- 在contenteditable=“true” 中插入 contenteditable=“false” 的元素的坑:
会导致光标不可见。解决:如果内容后面有空格或者其他内容、标签则光标显示正常;输入内容后光标显示也正确,故可以在内容末尾插入一个 br 标签或
。 - 鼠标点击contenteditable=false的标签,光标消失(实际上在该标签内),此时输入内容,输入内容会直接插入该标签的问题。解决:点击contenteditable=false的标签时,利用鼠标点击事件和getSelection将光标定位到输入框最后。
- -div 可编辑时按回车键会出现
<div><br></div>
的问题。解决:让 contenteditable 元素粘贴时自动过滤样式:
给div的css添加 (这行代码还可以使得该contenteditable的div获取innerText时保留换行),但该方法只适用于webkit内核浏览器,比如chrome浏览器
-webkit-user-modify: read-write-plaintext-only;
火狐存在的问题:
- 设置了contenteditable=true的输入框不会自动换行。解决:css添加word-break: break-all;
- 在contenteditable=“true” 中插入 contenteditable=“false” 的元素,火狐使用Backspace键无法删除该contenteditable=“false” 的元素(不触发keydown事件),解决:在contenteditable="false"标签文本最后加​
补充相关的知识点
1、添加contenteditable属性让文本处于可编辑状态,<p contenteditable="true">这里可以编辑</p>
contenteditable: "inherit"; (默认)
contenteditable: "plaintext-only";(输入纯文本)
contenteditable: "true";
contenteditable: "false";
contenteditable: "caret";(符号)
contenteditable: "events";(不知道搞啥用的)
2、css的user-modify
user-modify: read-only;
user-modify: read-write;
user-modify: write-only; /*暂不支持*/
user-modify: read-write-plaintext-only; /*输入纯文本,暂时只有谷歌支持*/
-webkit-user-modify: read-write-plaintext-only)