contenteditable及处理光标的问题

4,570 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 11 天,点击查看活动详情

关于contenteditable属性

它是一个全局的枚举属性.设置contenteditable意味着这个元素是否可以被编辑.如果可以,浏览器会修改元素的部件以允许被编辑. 属性值:

  • true:可以被编辑
  • false:不可以被编辑
<div contenteditable="true">这里可编辑</div>

tips:该属性是一个枚举属性,而非布尔属性。这意味着必须显式设置其值为 true、false 或空字符串中的一个,并且不允许简写为 Example Label正确的用法是 Example Label

为什么要有这个属性

刚开始需要实现一个可输入和实时预览基本上都是使用textarea来做,textarea支持多行文本输入,满足了我们大部分需要编辑的需求.但是,它的高度在初始化时就被限制了,一直固定在某个值,导致内容过多时会出现滚动条(但是这也是可以解决的,后面会说).同时textarea对数据格式也是有要求,只能输入文本格式.像图片或者一些高亮的文字就不能按照用户的想法去输入.

它怎么解决的

我们来个例子:(用一个块元素并使用contenteditable属性)

<div class="contain" contenteditable="true"></div>

同时设置css

.contain{
width:400px;
min-height:200px;
max-height:500px;
padding:3px;
border:1px solid #a0b3d6;
font-size:12px;
overflow-x:hidden;
overflow-y:auto;
}

但是使用下来却发现有个问题就是粘贴时光标总是恢复到初始位置.因此我们需要解决鼠标位置的问题


changeServiceContent(e) {
	//解决删除鼠标位置问题
    this.$refs["content-item"].focus();
    document.execCommand("selectAll", false, null);
    document.getSelection().collapseToEnd();
    //赋值双向绑定
    this.props.setting.serviceContentConfig.text = e.target.textContent;
}

注意:div中的内容如果不用span包裹,鼠标位置可能会有问题 使用contenteditable不能使用change事件,但是可以用input事件和blur事件等。