html5 contenteditable 可编辑属性
今天在工作中遇到了这样的需求。如上gif显示。
于是就仔细的看下了 h5新增的这个可编辑属性 contenteditable
contenteditable 属性规定是否可编辑元素的内容。contenteditable 可以设置为true/false
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<style type="text/css">
ul{
margin: 0;
padding: 0;
}
ul li{
display: flex;
justify-content: space-between;
border-bottom: 1px solid #ddd;
list-style: none;
padding: 10px;
margin: 0;
}
li div{
width: 85%;
border: 1px solid #f0f0f0;
}
#name.placeholder:after{
content: "请输入姓名";
color: #ddd;
}
#address.placeholder:after{
content: "请输入地址";
color: #ddd;
}
</style>
</head>
<body>
<ul>
<li><span>姓名:</span><div contenteditable="true" id="name" class="placeholder"></div></li>
<li><span>地址:</span><div contenteditable="true" id="address" class="placeholder"></div></li>
</ul>
<script type="text/javascript">
// 开始编辑时触发
document.getElementById('name').oninput = function(){
var text = this.innerHTML;
if(text.length != 0){
this.classList.remove('placehold');
}
}
document.getElementById('address').oninput = function(){
var text = this.innerHTML;
if(text.length != 0){
this.classList.remove('placehold');
}
}
</script>
</body>
</html>
上面是一个使用的例子;
主要想说明下,
(1)contenteditable 在编辑时如果手动的按了换行键,这里会添加一个div。这个不论定义被编辑属性的标签是什么,这里换行后都会添加一个div包起来。
(2)给编辑框添加一个placeholder, 当编辑的时候会出发oninput事件。
这里顺便把编辑属性和input type = text的编辑触发事件给总结下
这两个里面还是有区别的、我测试中发现,具有编辑属性的标签不会触发onchange事件
1.onfocus 当input 获取到焦点时触发
2.onblur 当input失去焦点时触发,注意:这个事件触发的前提是已经获取了焦点再失去焦点的时候会触发相应的js
3.onchange 当input失去焦点并且它的value值发生变化时触发
4.onkeydown 在 input中有键按住的时候执行一些代码
5.onkeyup 在input中有键抬起的时候触发的事件,在此事件触发之前一定触发了onkeydown事件
6.onclick 点击输入框的时候就会触发,一般和获取焦点一起触发
7.onselect 当input里的内容文本被选中后执行一段,只要选择了就会触发,不是非得全部选中。这个在电脑上测试没有发现事件被触发。
8.oninput 当input的value值发生变化时就会触发,不用等到失去焦点(与onchange的区别)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<style type="text/css">
ul {
margin: 0;
padding: 0;
}
ul li {
display: flex;
justify-content: space-between;
border-bottom: 1px solid #ddd;
list-style: none;
padding: 10px;
margin: 0;
}
#name {
display: inline-block;
width: 85%;
border: 1px solid #f0f0f0;
}
#name.placehold:after {
content: "请输入姓名";
color: #ddd;
}
#address.placehold:after {
content: "请输入地址";
color: #ddd;
}
</style>
</head>
<body>
<ul>
<li><span>姓名:</span><span contenteditable="true" id="name" class="placehold"></span></li>
<li><span>地址:</span>
<div contenteditable="true" id="address" class="placehold"></div>
</li>
</ul>
<input type="text" id="inputclick" placeholder="我是一个input" />
<script type="text/javascript">
// 开始编辑时触发
document.getElementById('name').oninput = function() {
console.log('oninput');
var text = this.innerHTML;
if (text.length != 0) {
this.classList.remove('placehold');
}
}
// 这个方法没有触发 非input 其他的具有编辑属性的标签不能触发onchange
// document.getElementById('name').onchange = function() {
// console.log('onchange');
// }
// input
// inputclick 获取焦点时触发了onfocus/onclick
// 当name 失去焦点触发了onblur,onchange
// 当name 通过键盘输入时,一次触发 onkeydown,oninput,onkeyup
// oninput 事件,获取焦点后开始编辑就可以时时获取到输入的内容
//
document.getElementById('inputclick').onfocus = function() {
console.log('inputclick-onfocus');
}
document.getElementById('inputclick').onblur = function() {
console.log('inputclick-onblur');
}
document.getElementById('inputclick').onkeydown = function() {
console.log('inputclick-onkeydown');
}
document.getElementById('inputclick').onkeyup = function() {
console.log('inputclick-onkeyup');
}
document.getElementById('inputclick').onclick = function() {
console.log('inputclick-onclick');
}
document.getElementById('inputclick').onselect = function() {
console.log('inputclick-onselect');
}
document.getElementById('inputclick').oninput = function() {
console.log('inputclick-oninput');
}
document.getElementById('inputclick').onchange = function() {
console.log('inputclick-onchange');
}
document.getElementById('address').oninput = function() {
var text = this.innerHTML;
if (text.length != 0) {
this.classList.remove('placehold');
}
}
// 当name 获取焦点时触发了onfocus/onclick
// 当name 失去焦点触发了onblur
// 当name 通过键盘输入时,一次触发 onkeydown,oninput,onkeyup
// oninput 事件,获取焦点后开始编辑就可以时时获取到输入的内容
// 注意 onchange 没有被触发
document.getElementById('name').onfocus = function() {
console.log('onfocus');
}
document.getElementById('name').onblur = function() {
console.log('onblur');
}
document.getElementById('name').onkeydown = function() {
console.log('onkeydown');
}
document.getElementById('name').onkeyup = function() {
console.log('onkeyup');
}
document.getElementById('name').onclick = function() {
console.log('onclick');
}
document.getElementById('name').onselect = function() {
console.log('onselect');
}
document.getElementById('name').oninput = function() {
console.log('oninput');
}
document.getElementById('name').onchange = function() {
console.log('name-onchange');
}
</script>
</body>
</html>
引用了一篇文章
所有的现代浏览器支持oninput,其中包括IE9。对于那些老式浏览器,在不支持该事件时用keydown作为优雅降级。
不幸的是,检测浏览器对该oninput事件的支持性并不容易。假定浏览器支持oninput,那么以下这段js代码的返回值为true,否则为false。
'oninput'
in document.createElement('input')
这段代码在大多数浏览器中正常运行,除了Firefox(见bug
#414853)(我在这里测试是可以的 54.0.1 (64 位)),
someElement.oninput
=
function()
{ el.onkeydown
=
null;
// Your code goes here};someElement.onkeydown
=
function()
{
// Your code goes here}
keydown事件仅会被触发一次(在oninput事件触发前),之后再触发oninput。虽然并不完美,但总比写上一大堆oninput特性检测代码要好些吧。
IE 事件兼容 onpropertychange