背景:在首次应用 contenteditable 写可输出的 div 模块,当需要要求输出限度字数,还要光标失常的状况来模仿 input
间接上 demo,用 vue 写的(框架不重要),demo 中用了 vant 的 toast,css 留神下是 sass
如果你理解 vue, 能够间接搭建一个 demo 我的项目,而后复制下上面的代码运行起来就能看到成果
搭建 demo 能够参考我之前的文章 https://segmentfault.com/a/11…
<template>
<div class="edit-content-wrap">
<div
class="edit-content thin-scroll"
contenteditable="true"
ref="edit-content"
placeholder="Ctrl+V 可粘贴文字"
@keydown="inputChecked"
@keyup="inputLength"
>{{comm_info}}</div>
<div class="edit-footer">
<div class="edit-footer-part-3">
<span>{{currentLength}}</span>
/
<span>10</span>
</div>
</div>
</div>
</template>
<script>
import Vue from 'vue';
import {Toast} from 'vant';
Vue.use(Toast);
export default {
name: 'Input',
components: {},
data() {
return {
comm_info: '',
currentLength: 0
};
},
mounted() {},
methods: {inputChecked(e) {
//Backspace 键 8 F5 键 116 37~40 方向箭头 Del 键 46
if (
e.target.innerText.length >= 10 &&
e.keyCode !== 8 &&
e.keyCode !== 116 &&
e.keyCode !== 37 &&
e.keyCode !== 38 &&
e.keyCode !== 39 &&
e.keyCode !== 40 &&
e.keyCode !== 46
) {e.preventDefault();
}
},
inputLength(e) {if (e.target.innerText.length > 10) {Toast.fail('最多可输出 10 字');
e.target.innerText = e.target.innerText.substring(0, 10);
this.getInputSelection(e.target);
}
this.currentLength = e.target.innerText.length;
},
/**
* 获取输出的光标到字符串最初一位
* @param {obj} obj
*/
getInputSelection(obj) {
// 解决光标问题
if (window.getSelection) { //ie11 10 9 ff safari
// obj.focus(); // 解决 ff 不获取焦点无奈定位问题
let range = window.getSelection(); // 创立 range
range.selectAllChildren(obj); //range 抉择 obj 下所有子内容
range.collapseToEnd(); // 光标移至最初} else if (document.selection) { //ie10 9 8 7 6 5
let range = document.selection.createRange(); // 创立选择对象
//var range = document.body.createTextRange();
range.moveToElementText(obj); //range 定位到 obj
range.collapse(false); // 光标移至最初
range.select();}
}
}
};
</script>
<style lang="scss" scoped>
.edit-content-wrap {
width: 100%;
border: 1px solid #dddddd;
.edit-content {
outline: none;
min-height: 124px;
width: 100%;
text-align: justify;
padding: 7px 10px;
word-wrap: break-word;
word-break: break-all;
overflow-y: auto;
&:empty::before {content: attr(placeholder);
color: gray;
}
}
.edit-footer {
height: 36px;
background: #f7f9fa;
border-top: 1px solid #dddddd;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
.edit-footer-part-3 {
.follow-small-height {width: 120px;}
}
}
}
</style>