contentEditable属性
Posted 前端码农小王
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了contentEditable属性相关的知识,希望对你有一定的参考价值。
前言
我们最常用的输入文本内容便是input与textarea,但是有一个属性,可以让我们在很多标签中,如div,table,p,span,body等,可以像input输入框一样,实现文本编辑,这便是contentEditable属性
contentEditable属性
微软开发,被其他浏览器反编译并且投入应用的一个全局属性
该属性的功能是允许用户编辑元素中的内容//所以这个元素必须是可以获得鼠标焦点的元素,并且在点击鼠标后要向用户提供一个插入符号,提示可编辑
contenteditable=“true” #开启文本编辑
contenteditable=“false” #关闭文本编辑,该字段的值缺失时,效果和这个是一样的
contenteditable=“inherit” #(默认)表明该元素继承了其父元素的可编辑状态
下图属性一览,部分属性值存在兼容性 developer.mozilla.org/zh-CN/docs/…
兼容性
基本上完美支持市面上浏览器,即使刚刚退役的IE浏览器
使用
1、只需要在标签上contentEditable为true,即可实现编辑
这是一个段落。是可编辑的。尝试修改文本。
2、contenteditable="inherit"的使用
<div contenteditable="true">
<p>这是一个子段落</p>
<p>这是一个子段落</p>
</div>
项目中
在项目中,总是需要文本显示与文本编辑,通常的做法是文本标签+input
如:在vue中
如果我们使用contenteditable,就不再需要input输入框
[代码片段](https://code.juejin.cn/pen/7111225356530483236)
那么,问题来了,如何保存数据?
通过失焦事件blur
<div id="divInput" class="txt" contenteditable="true">
<p>这是一个子段落</p>
<p>这是一个子段落</p>
</div>
JS
var divInput = document.getElementById("divInput");
divInput.addEventListener("blur", function (event)
console.log("div失去焦点2222---", event, event.target);
);
如果是在vue项目中,对标签设置了contenteditable为true,相应的添加失焦事件,然后再用$set改变就可以
<div class="count">
<div contenteditable="true"
v-for="(n, index) in list" :key="n"
@blur="handleBlur(index, $event)">n</div>
</div>
export default
data()
return
list: ['这是1', '这是2', '这是3']
;
,
methods:
handleBlur(index, event)
this.$set(this.list, index, event.target.innerText);
console.log(this.list);
,
,
;
代码片段
使用div 的 contenteditable属性,实现输入编辑,输入 "#" 出现下拉选择
文章原文: https://www.cnblogs.com/yalong/p/11883585.html
演示效果如下:
具体代码可以看 https://github.com/YalongYan/edit-by-contenteditable , 下面分析实现的大概过程
代码实现过程
1.把div容器变成可编辑的,用 contenteditable="true"
2.div容器里面的内容都用 v-html
渲染
3.输入 #
出现下拉选择,监听 keyup
事件即可
4.下拉框的位置,即 left
值 通过查询容器里面的内容计算出来(要区分汉字,字母的宽度)
5.按上下按钮,下拉框数据也移动,通过给document 添加keydown事件,但是记得在组件销毁的时候,把事件去掉,代码如下:
created () { // 全局监听键盘事件
document.addEventListener("keydown", this.documentKeyMethod)
},
beforeDestroy () { // 组件销毁之前 把全局的事件解除了
document.removeEventListener("keydown", this.documentKeyMethod)
}
6.每次在容器里点击,或者按左右键的时候,记录下光标位置(lastSelection
是全局变量)
let selection = window.getSelection ? window.getSelection() : document.selection
let range = selection.createRange ? selection.createRange() : selection.getRangeAt(0)
lastSelection = selection
7.把选中的数据回显到容器里面,只需给光标处插入节点即可
8.插入节点后,光标自动插入到新数据的后面
lastSelection.collapse(childNode, index)
-
在蓝色数据里面输入内容的时候,需要把这个数据直接删除,但是如果用户就是想在后面输入内容的话就需要特殊处理了,第十条为解决办法
10.在蓝色数据的直接后面(没有空格)输入内容的时候,需要让光标自动往后移动一位,监听kedDown
事件即可,移动光标的时候需要判断后面是否有空格,没有的话还的插入一个空格
遇到的问题
1.必须加上这个 user-select: none
,不加的话,点击下拉框的时候,会导selection变化,无法记录在contenteditable="true"
div里面的位置, 兼容写法如下:
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Chrome/Safari/Opera */
-khtml-user-select: none; /* Konqueror */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none;
2.需要设置字体,不然有些浏览器(比如uc浏览器)空格宽度不一致,我设置的字体css如下:
.editContentCtn{
// 不设置字体的话 空格的宽度会很宽
font-family: ‘Avenir‘, ‘Helvetica‘, ‘Arial‘, ‘sans-serif‘;
}
代码地址:
https://github.com/YalongYan/edit-by-contenteditable
参考链接:
https://segmentfault.com/a/1190000005869372
http://cn.voidcc.com/question/p-dchxjkvr-ye.html
以上是关于contentEditable属性的主要内容,如果未能解决你的问题,请参考以下文章
Vue.js 删除渲染函数中的 contenteditable 属性
如何在我的angularjs指令中切换属性的值,如contenteditable?
HTML DIV contentEditable属性支持Demo