vue环境下基于contenteditable实现高度自适应多行文本域(div模拟<textareaa>)

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)

          }

      }

    }

如果业务中还需要什么功能,也可以基于此进行扩展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值