vue实现带样式的textarea输入框,contenteditable属性应用

时间:2025-02-16 19:38:43
<template> <div class="tctextarea_box"> <div id="tctextarea" class="tctextarea" contenteditable="plaintext-only" @focus="focusTxt" @input="inputTxt" @blur="blurTxt" v-html="txtHtml"></div> </div> </template> <script> export default { name: "TextareaComponent", computed: {}, props: { }, data(){ return{ tipData:['输入框第一条提示','输入框第二条提示','输入框第三条提示','输入框第四条提示','输入框第五条提示'], txtData:[], txtHtml:'', txtStr:'', } }, created(){ this.createTipHtml(); }, methods: { //textarea输入 inputTxt(e) { }, //获取焦点 focusTxt(e) { //获取焦点时,输入框文字为黑色 if(e.target.innerHTML){ if(e.target.innerHTML.indexOf('#FF4019')>-1){ let arr = e.target.innerHTML.split('#FF4019'); let str = ''; for(let i=0;i<arr.length;i++){ str+=arr[i]; if(i!==arr.length-1){ str+='#323D4D'; } } e.target.innerHTML = str; this.focusTextarea(); } } //输入框获得焦点时内容为初始提示,清空提示 if(this.txtHtml.indexOf(this.tipData[0])>-1){ this.txtHtml = ''; this.focusTextarea(); } }, //主动使textarea获取焦点 focusTextarea(){ let node = document.getElementById('tctextarea'); if(window.getSelection){ let range = window.getSelection(); range.selectAllChildren(node); // (); range.collapseToEnd(); }else{ let range = document.selection.createRange(); range.moveToElementText(node); range.collapse(false); range.select(); } }, //失去焦点 blurTxt(e) { //如果输入内容为'' 出现提示 let str = e.target.innerText?e.target.innerText.trim():''; if(str.length<1){ this.createTipHtml(); }else{ this.txtStr = e.target.innerText; this.createInputHtml(); } }, //创建提示文字 createTipHtml(){ let temp = ''; for(let i=0;i<this.tipData.length;i++){ temp+=`<div class="tctip_item" style="font-size: 14px; color: ${i==0?'#F77700':'#A2AEBF'} ;line-height: 24px; display: flex; box-sizing: border-box; padding-bottom:5px;margin-:0;"><div class="tctip_l" style="width: 20px;">${i+1}.</div><div class="tctip_r" style="flex-grow:1;">${this.tipData[i]}</div></div>` } this.txtHtml = temp; }, //创建输入内容 createInputHtml(str,colorType,splitStr){ let temp = ''; let splitTxt = splitStr||'\n'; let data= this.deleteSpace(str||this.txtStr).split(splitTxt); let newData = []; for(let i=0;i<data.length;i++){ if(data[i]!=''){ //输入内容文字默认为黑色 当输入内容查询不到时 显示为红色 temp+=`<div class="tctxt_item" style="font-size:14px;color:${colorType?'#FF4019':'#323D4D'};line-height:24px;">${data[i]}</div>`; newData.push(data[i]) } } this.txtHtml = temp; //触发父组件事件 this.$emit('changeTextareaValue',newData); }, //删除字符串中的空格 deleteSpace(str){ let data = []; if(str){ data = str.split(' '); }else{ data = this.txtStr.split(' '); } let newStr=''; for(let i=0;i<data.length;i++){ if(data[i]!=''){ newStr+=data[i]; } } return newStr }, }, }; </script> <style lang="less" scoped> .tctextarea_box{ width: 100%; height: 100%; } .tctextarea{ width: 100%; height: 100%; box-sizing: border-box; padding: 20px; // border: 1px solid #eee; overflow-y:auto; display: inline-block; outline: none; caret-color:red; font-size:14px; color:#323D4D; line-height:24px; } .tctextarea::-webkit-scrollbar-thumb{ display: block; cursor: pointer; } </style>