contenteditable
修改元素的可编辑性,使之可以编辑,html就给我们提供了这么个属性,要知道在一个普通元素内插入一个标签要比在textarea中要容易多了。
contenteditable 属性是 HTML5 中的新属性。规定是否可编辑元素的内容。比如将它设置在 div 上面将变为可以编辑的元素,类似文本输入框。
-webkit-user-modify
- read-only: 默认值,元素只读,不可编辑;
- read-write: 可以编辑,支持富文本;
- read-write-plaintext-only: 可以编辑,不支持富文本;
- write-only: 使元素仅用于编辑(几乎没有浏览器支持)
<template>
<div class="tag-textarea">
<div
contenteditable="true"
class="myTextArea"
@input="handleInput"
ref="inputTag"
:id=contentId
@focus="setDisabled(false)"
></div>
<el-button size="small" :disabled="disabled" @click="addfactor">插入参数</el-button>
</div>
</template>
<script>
export default {
props: {
paramsLength: {
type: Number,
default: 0
}
},
name: "App",
data() {
return {
Range: null,
contentId: `content${this.getGuid()}`,
disabled: true,
};
},
mounted() {
document.addEventListener("selectionchange", this.selecthandler);
},
beforeDestroy() {
document.removeEventListener("selectionchange", this.selecthandler);
},
methods: {
callBack(html) {
// 执行回调函数
this.$emit("callBack", html.replace(/<[^>]*>/g, ''));
console.log(html.replace(/<[^>]*>/g, ''));
},
handleInput() {
this.callBack(this.$refs.inputTag.innerHTML);
},
getGuid() {
// 生成随机ID
return `r${new Date().getTime()}d${Math.ceil(Math.random() * 1000)}`;
},
selecthandler() {
const sel = window.getSelection();
const range = sel ? (sel.rangeCount > 0 ? sel.getRangeAt(0) : null) : null;
if (range && range.commonAncestorContainer.ownerDocument?.activeElement?.id === this.contentId) {
this.saveRange(range);
}
},
saveRange(range) {
this.Range = range;
},
insertNode(node) {
// 删掉选中的内容(如有)
if (this.Range) {
this.Range.deleteContents();
this.Range.insertNode(node);
this.callBack(this.$refs.inputTag.innerHTML);
}
},
addTag(text) {
const node = document.createElement("div");
node.className = 'textarea-tag'
node.innerText = text;
// const cancelNode = document.createElement("span");
// cancelNode.innerText = "✕";
// cancelNode.style.color = "black";
// cancelNode.onclick = (event) => {
// const parentElement = event.target.parentElement;
// if (parentElement && parentElement.parentNode) {
// parentElement.parentNode.removeChild(parentElement);
// }
// this.callBack(this.$refs.inputTag.innerHTML);
// };
// node.appendChild(cancelNode);
this.insertNode(node);
this.setDisabled(true);
},
addfactor() {
this.addTag("${test}");
},
setDisabled(value) {
this.disabled = value;
},
},
};
</script>
<style lang="scss">
.tag-textarea {
.myTextArea {
-webkit-user-modify: read-write-plaintext-only !important;
border:1px solid #c0ccda;
padding: 0px 15px;
border-radius: 4px;
overflow: hidden;
box-sizing: border-box;
word-break: break-word;
height: 200px;
width: 100%;
transition: border-color 0.2s;
}
.myTextArea:focus {
border-color: #409eff;
}
.myTextArea.is-disabled {
background-color: #f5f7fa;
cursor: not-allowed;
}
.textarea-tag {
color: #c41d7f;
background: #fff0f6;
border-color: #ffadd2;
-webkit-user-modify: read-only;
display: inline;
margin: 0 6px;
font-size: 12px;
padding-inline: 7px;
border: 1px solid #d9d9d9;
border-radius: 4px;
}
.el-button {
margin-top: 10px;
}
}
</style>