
<template>
<div class="home">
<div
id="sendMsg"
contenteditable="true"
class="textarea"
@input="input"
@compositionstart="compositStart"
@compositionend="compositEnd"
@paste="copyText"
v-html="content"
></div>
<div class="limit">{{ textSize }}/100</div>
</div>
</template>
<script>
export default {
data() {
return {
textSize: 0,
lock: true,
fullContent: '',
content: '', // 文本数据
}
},
methods: {
// 输入中文开始时
compositStart(e) {
this.lock = false;
document.querySelector("#sendMsg").focus();
document.execCommand("selectAll", false, null);
document.getSelection().collapseToEnd();
},
// 输入中文结束时
compositEnd(e) {
this.lock = true;
this.input(e);
},
input(e) {
if(this.lock) {
this.textSize = e.target.innerHTML.length
if(this.textSize >= 100) {
this.textSize = 100;
this.fullContent = e.target.innerHTML.substring(0, 100);
e.target.innerHTML = e.target.innerHTML.substring(0, 100);
} else {
this.fullContent = ''
}
this.content = e.target.innerHTML;
this.textFocus();
} else if (this.fullContent) {
// 目标对象:超过100字时候的中文输入法
// 原由:虽然不会输入成功,但是输入过程中字母依然会显现在输入框内
// 弊端:谷歌浏览器输入法的界面偶尔会闪现
e.target.innerHTML = this.fullContent;
this.lock = true;
this.textFocus();
}
},
// 粘贴富文本转为纯文本
copyText(e) {
e.stopPropagation();
e.preventDefault();
let text = '', event = (e.originalEvent || e);
if (event.clipboardData && event.clipboardData.getData) {
text = event.clipboardData.getData('text/plain');
} else if (window.clipboardData && window.clipboardData.getData) {
text = window.clipboardData.getData('Text');
}
if (document.queryCommandSupported('insertText')) {
document.execCommand('insertText', false, text);
} else {
document.execCommand('paste', false, text);
}
},
// 文本输入框聚焦,焦点在最后位置
textFocus() {
setTimeout(() => {
document.querySelector("#sendMsg").focus();
document.execCommand("selectAll", false, null);
document.getSelection().collapseToEnd();
}, 0);
},
}
}
</script>
<style scoped>
.home{
width: fit-content;
position: relative;
}
.textarea{
width: 600px;
height: 300px;
caret-color: auto;
outline-style: none;
border: 1px solid #D9D9D9;
background-color: #F6F8FA;
padding: 0 10px 20px;
line-height: 26px;
box-sizing: border-box;
overflow-y: auto;
}
.limit{
position: absolute;
bottom: 1px;
right: 1px;
background-color: #fff;
padding: 0 8px;
line-height: 20px;
}
</style>
tips:
开源项目地址:https://gitee.com/chenswei/editable-div
技术参考:https://blog.youkuaiyun.com/melodystars/article/details/103960259