背景:在首次应用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>