携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第25天,点击查看活动详情
前言
最近在项目中用到了一个输入框,原本就打算用input框了,但是内容是不限制的,又打算用textarea,但是产品说右下角有个小图标不太优雅。随后让我疯狂百度找到了contenteditable ,哈哈,这个不算是什么稀奇的属性,应该都知道,现在就看看前端的神奇之处,让产品大吃一惊。
## contenteditable 是什么
contenteditable 是一个枚举属性,表示元素是否可被编辑。如果可以。浏览器会修改元素的部件以允许编辑。同时该属性在标签中使用时不可以简写,必须显示表明为true或者false,就像这样:
怎么使用
再设置宽高和边框就会得到一个差不多的的输入框了。
.editor{
width: 842px;
min-height: 423px;
border: 1px solid #2a82e4;
margin-top: 10px;
}
此时的输入框就会拥有input的事件,但是没有change,但是可以使用input和blur,但是这样看起来光标和边框有点重合,来个内边距
padding: 19px 18px 29px 23px;
增加placeholder
input是内置了placeholder,会在输入的时候将提示词隐藏掉。既然这样,我们就在标签内加一个placeholder,并且设置提示词。同时使用伪元素接收。就像这样:
// html
<div
contenteditable="true"
placeholder="请输入文字..."
></div>
// css
.editor ::before {
content: attr(placeholder);
font-weight: 400px;
font-size: 16px;
color: rgba(64, 64, 64, 1);
}
}
看起来就是这样:
还是不错的,但是需要在有值是需要将提示词去掉的,上面说道是有input事件的,所以我们只需要监听input事件,拿到它的值,就能够控制placeholder了。
//VUE
<div
class="editor before"
contenteditable="true"
placeholder="请输入文字..."
@input="changeComment"
ref="editor"
></div>
//computed
computed: {
editor() {
return this.$refs.editor;
},
},
//methods
changeComment(e) {
this.note = e.target.textContent.trim();
const classList = e.target.classList;
if (this.note && classList.contains("before")) {
this.editor.classList.remove("before");
}
if (!this.note && classList.contains("before")) {
this.editor.classList.add("before");
}
},
//css
.before::before {
content: attr(placeholder);
font-weight: 400px;
font-size: 16px;
color: rgba(64, 64, 64, 1);
}
当输入值时,会触发input事件,拿到textContent去掉首尾空格的值,只要值不为空,就将before这个class加进去,反之去掉。
现在搞定。
去掉粘贴时的默认样式
现在需要去掉从别处复制来的内容的默认样式。现在是这样:
现在我们需要要将粘贴来的样式给去掉。
handlePasteStyle: {
bind(el) {
const pasteHandler = (e) => {
e.preventDefault();
// 粘贴事件有一个clipboardData的属性,提供了对剪贴板的访问,clipboardData的getData(fomat) 从剪贴板获取指定格式的数据
var text = (e.originalEvent || e).clipboardData.getData("text/plain");
// 插入
document.execCommand("insertText", false, text);
};
el.pasteHandler = pasteHandler;
el.addEventListener("paste", pasteHandler);
},
unbind(el) {
el.removeEventListener("paste", el.pasteHandler);
delete el.pasteHandler;
},
},
使用自定义指令来处理。
需要使用到两个钩子函数,bind和unbind,监听paste事件,首先阻止浏览器的默认行为。其次我们需要拿到粘贴的内容。粘贴事件有一个clipboardData的属性,提供了对剪贴板的访问,clipboardData的getData(format) 从剪贴板获取指定格式的数据 .最后使用 document.execCommand("insertText", false, text); 将内容插入到输入框中。现在就没有刚才的默认样式了。
注意:document.execCommand在mdn上显示已弃用,虽然一些浏览器仍然支持它。
但是目前还没有找到好一点的替代品,所以暂时就先用这个。
友友们,你们知道有什么好一点的替代品吗?