html5给大多数元素都增加了contentEditable属性,如果给某元素设置属性 contentEditable = "true",那么该元素就会进入可编辑状态,即浏览器会允许用户直接编辑该元素内容。
html:
<div class="wraper">
<div contenteditable="true">
<p>这里的文字是可编辑的</p>
</div>
</div>
css:
div.wraper {
width: 240px;
height: 240px;
position: relative;
margin: 100px;
}
.wraper div {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 200px;
height: 200px;
background: #f0b921;
box-sizing: border-box;
border-radius: 4px;
margin: auto;
}
p {
color: #fff;
margin: 15px;
display: inline-block;
}
默认情况下,div是不可编辑的
当我们设置contenteditable="true"后,鼠标点击后,谷歌浏览器下,div多了一个蓝色的边框(outline),如下:
当我们按下删除键,节点会被清空
可是当我们按下回车键时,神奇的一幕出现了,产生两个div节点,节点内还有一个换行符!
也就是说,"一个回车" == "两个div节点"?
真真假假,试过便知。事实上是,之后不管按多少次回车,谷歌浏览器下都只产生一个节点。
在这里,咱把思路稍微拓宽一些,首先,抛出一个疑问:是不是其他浏览器下,都是这样呢?
作死测试1:Microsoft Edge (别问我为什么用这个测试,顺手...)
查看控制台:设置了contenteditable的div下面没有显示任何子节点(额外的元素作死测试我就不试了,不在本文讨论范围内)
结果:不论按删除还是多次回车,控制台雷打不动,没有任何改变
作死测试2:火狐
查看控制台:设置了contenteditable的div下面产生了两个p节点,节点内有一个换行符
结果:按下删除,生成一个p节点,节点内有一个换行符。按下回车,生成俩~
作死测试3:万恶的ie(IE11)
查看控制台:设置了contenteditable的div下面产生了两个p节点,节点内有一个换行符
结果:按下删除,真的清空了这个div。按下回车,生成俩p节点,但节点里面没有换行符
作死结束。
作死总结:经过一番折腾,缕清了不同浏览器对contenteditable属性的不同解释,而这却很有可能产生对用户体验有一定影响的bug。
作死外话:在测试的过程中发现,如果在设置了contenteditable属性的div元素内存在div元素(假设名为child),则里面的div元素child会出现以下情况(目前仅测试谷歌、火狐、IE11环境下):
- 谷歌、火狐、IE11下,完全覆盖其父元素
- 谷歌、火狐、IE11下,该child元素的内容不显示,但在控制台可见
- 火狐、IE11下,该child元素可被编辑,但在IE下,快速拉伸会导致“侧漏”现象,即拉伸过程中留下残影
- 谷歌下,该child不可编辑
作死发现:contenteditable属性其实是可继承的,如果父元素可编辑,则子元素也可以编辑,除非手动设置contenteditable="false"
除此之外,html5还给设置了contenteditable属性的元素提供了isContentEditable属性,当元素可编辑时,该属性返回true,否则返回false。
那么问题来了,咱是不是还可以通过isContentEditable属性对用户的操作做一些不可描述的骚操作呢?(手动滑稽)