1、在web应用中,常用的多行文本输入<textarea>,满足了我们绝大部分的需求,唯一不足之处就是文本高度不能随内容自适应,如果需要高度自适应需要通过js脚本实现
2、div有天然的高度自适应,在加上个contenteditable属性,就可以变成一个文本内容自适应的多行文本输入框
<div contenteditable="true"></div>
2.1添加双向绑定功能:
<div contenteditable="true" v-text="contentText"></div>
//页面加载时,将接收到的value设置到innerText
this.$nextTick(function(){
if($this.value){
$this.contentText=$this.value
}
})
//用户输入时,页面的的值变化需要回传给绑定的属性,增加个input事件来处理,完成基本视图和数据的双向绑定
<div contenteditable="true" v-text="contentText" @input="handleInput"></div>
handleInput:function(e){
var $this=this;
if(e&&e.target&&e.target.textContent){
if(e.target.textContent<=this.maxLength){
this.$emit('change',e.target.textContent)
}
}
}
2.2为空提示
当输入框内容为空时,一般都要求有一个输入提示,div不支持设置placeholder属性,这时,可借助css的empty伪类来实现
<div contenteditable="true" v-text="contentText" @input="handleInput" :placeholder=placeholder class="edit-font edit-content" id="edit-content"></div>
.edit-content:empty:before{
content:attr(placeholder)
color:#A5A5A9
}
.edit-content:focus:before{
content:none;
}
2.3字数限制
<textarea>通过maxlength来达到效果,这里如果使用input事件来触发,截断多余的输入,这样会带来一个比较大的问题,光标会移动到文本最前面,如果使用keypress事件,当用户输入的字数超过最大字符数时,阻止默认事件。对于粘贴事件,同样需要控制
<div contenteditable="true" v-text="contentText" @input="handleInput" :placeholder=placeholder class="edit-font edit-content" id="edit-content" @keypress="checkSize" @paste="checkSize"></div>
checkSize:function(e){
if(e.which!=8&&this.$el.textContent.length>=this.maxLength){e.preventDefault();}
}
这时英文和数字输入是可以根据maxLength来限制了,但是 中文却还是可以输入的,这就需要用到DOM提供的composition事件api,规范规定,输入 开始时触发compositionstart,选择字词开始时触发compositionend,使用这两个事件来判断用户有没有完成一次 中文输入,当compositionstart触发时,标记为false,当compositionend时,标记为true,然后在input事件触发,判断用户已经完成了输入,则 将字数截断,并失焦,避免光标移到最前面,导致输入混乱
<div contenteditable="true" v-text="contentText" @input="handleInput" :placeholder=placeholder class="edit-font edit-content" id="edit-content" @keypress="checkSize" @paste="checkSize" @compositionStart="handleStart" @compositionend
="handleEnd"></div>
handleStart:function(){
this.finish=false;
},
handleEnd:function(){
this.finish=true;
},
handleInput:function(e){
var $this=this;
if(e&&e.target&&e.target.textContent){
if(e.target.textContent<=this.maxLength){
this.$emit('change',e.target.textContent)
}else{
setTimeout(function(){
if($this.finish){
$this.$el.textContent=$this.$el.textContent.substring(0,$this.maxLength);
$this.$el.blur();
}
},500)
}
}
}
如果业务中还需要什么功能,也可以基于此进行扩展