Key 1: Once the contents of the assignment, the cursor will lose, causing the cursor to the first
Solution sets a status bit isChange, when editing not watch updated because emit will automatically change the value of the outer layer, watch trigger
Solution 2 to retrieve the last value to be replaced
Key 2: div editable contenteditable = "true"
Priority 3: Do not text within a div only html
-webkit-user-modify: read-write-plaintext-only;
user-modify: read-write-plaintext-only;
Key 4: up and down the height of the center (multi-line)
display: table-cell; vertical-align: middle;
Priority 5: Move the cursor
// offset position cursor to the beginning (see the specific context code)
document.getSelection().collapse(_this.firstChild, txtAnchorOffset)
Priority 5: calculate the length of the input of Chinese
Priority 6: Copy treatment (maximum length) adhesive events cursor how to restore the original position, how to deal exceeds the maximum length
The last place is fail
1, could not find Chinese pinyin input multiple-word, press the space bar, etc. What are the key words are confirmed, is not found how to obtain
2. What text before Chinese input is not found
3. The text in multiple lines for processing, I remember array node
4. did not return to the state before the input
Subtotal:
Iview found the textarea, in this state there is no accurate calculation of the position of the cursor, it is deleted from the text, before the restoration, but the cursor position is not restored.
reference
-webkit-user-modify
Editable after DIV, and the cursor entanglements limit input offset
https://www.cnblogs.com/echon-cw/p/9809524.html
Restrictions can only enter plain text editor div
https://www.cnblogs.com/libo0125ok/p/8143642.html
<!-- * @description text !--> <template> <div ref="textareaCenter" id="textareaCenter" @focus="isChange = false" @blur="isChange = true" class="textareaCenter" contenteditable="true" v-text="innerValue"> </div> </template> <script> // import privateZenMixins from '@/view/biz/input/components/privateZenMixins.js' export default { name: 'textareaCenter', // mixins: [privateZenMixins], components: {}, props: { maxlength: { type: Number, default: 0 }, value: { type: String, default: '' } }, data () { return { isChange: true, innerValue: this.value } }, watch: { value (val) { if (this.isChange) { this.innerValue = val } }, innerValue (val) { console.info('innerValue', val) } // value (val) { // console.info('this.$refs.textareaCenterRef.target.innerText', this.$refs.textareaCenterRef.innerText) // // console.info('watch value', val) // // this.$nextTick(() => { // // this.valueInner = this.getMaxText(val) // // }) // // // this.$emit('input', this.valueInner) // // console.info('watch this.valueInner', this.valueInner) // if (!this.lock) { // console.info('watch lock val', val) // this.valueInner = this.getMaxText(val) // this.$refs.textareaCenterRef.innerText = this.getMaxText(val) // } // } }, computed: {}, methods: { // oEmit (event, oldtxt, firstChild, txtAnchorOffset) oEmit (event) { if (this.$refs.textareaCenter.innerText.replace(/\n/g, 'n').length >= this.maxlength) { event.preventDefault() } console.info('oEmit', this.$refs.textareaCenter.innerText.replace(/\n/g, 'n').length) this.$emit('input', this.$refs.textareaCenter.innerText) }, init () { let _this let oldDate let noteMax = this.maxlength let oThis = this // let that = oThis.$refs.textareaCenter.innerText let content = document.getElementById('textareaCenter') // 注册中文的输入事件, let isCN = false content.addEventListener('compositionstart', function (event) { oThis.oEmit(event) console.info('compositionstart') isCN = true console.info('kkk3', the this.textContent.replace (/ \ the n-/ G, ' the n- ' ) .length) // the revocation input, otherwise it will have to replace the last character of IF ( the this .textContent.replace (/ \ the n-/ G, ' the n- ' ). length> = noteMax) { Event .preventDefault () } }) content.addEventListener ( ' compositionend ' , function ( Event ) { oThis.oEmit ( Event ) console.info ( ' compositionend ' ) ISCN = to false console.info ( ' olddate ' , olddate, ' event.clipboardData.getData (\' the Text \ '). length ' ) oThis. $ refs.textareaCenter.innerText = oThis. refs.textareaCenter.innerText.slice $ ( 0 , noteMax ) document.getSelection (). Collapse (_this.firstChild, txtAnchorOffset) }) // Register event text input, cursor start and end offset data acquisition, and if the input exceeds the length of the non-Chinese, the undo this operation let txtAnchorOffset, txtFocusOffset content.addEventListener ( ' the textInput ' , function ( Event ) { oThis.oEmit ( Event ) console.info (' The textInput ' , oThis.innerValue, ' 11jj ' , content.textContent) the let _SEL = document.getSelection () txtAnchorOffset = _sel.anchorOffset txtFocusOffset = _sel.focusOffset console.info ( ' kkk2 ' , the this .textContent.replace (/ \ n-/ G, ' n- ' ) .length) // must be added ISCN judgment or not obtain the correct cursor data IF (! && ISCN the this .textContent.replace (/ \ n-/ G, ' n- ' ). length> =noteMax) { Event .preventDefault () } }) // registration event paste, get the length data pasted the let pastedLength content.addEventListener ( ' Paste ' , function ( Event ) { oThis.oEmit ( Event ) console.info ( ' Paste ' ) IF (! Event .clipboardData) return pastedLength = Event .clipboardData.getData ( ' the Text ' ) .length the let txtLengthOThis =. $ Refs.textareaCenter.innerText.replace (/ \ n-/ G, ' n- ' ) .length IF ((+ pastedLength txtLength)> = noteMax) { Event .preventDefault () } }) // register input event, the data inputted content.addEventListener ( ' iNPUT ' , function ( Event ) { oThis.oEmit ( Event ) console.info ( ' iNPUT ' ) the setTimeout (function () { oThis.oEmit ( Event ) console.info ( 'input setTimeout') // oldDate if (!isCN) { _this = content console.info('kkk1', _this.textContent.replace('\n', '3333333n').length) if (_this.textContent.replace(/\n/g, 'n').length > noteMax) { let data = _this.textContent if (pastedLength > 1) { oldDate Data.slice = ( 0 , txtAnchorOffset) + data.slice (txtFocusOffset + pastedLength, data.length) // paste string length is set to 0, so as not to affect the next determination. = pastedLength 0 } the else { olddate = data.slice ( 0 , txtAnchorOffset) + data.slice (txtFocusOffset, data.length) } // taken again to the maximum length of the string, to prevent the overflow of _this.textContent oldDate.slice = ( 0 , noteMax ) // mThis. $ EMIT ( 'the INPUT', _this.textContent) // oThis.oEmit(event, oldDate.slice(0, noteMax), _this.firstChild, txtAnchorOffset) oThis.oEmit(event) console.info('_this.textContent', _this.textContent) // console.info('mThis', mThis) // 光标移动到起始偏移位置 document.getSelection().collapse(_this.firstChild, txtAnchorOffset) } } }, 0) }) } // getMaxText (txt) { // let ret // if (this.maxlength === 0) { // ret = txt // } else { // if (txt.length > this.maxlength) { // ret = txt.substr(0, this.maxlength) // } else { // ret = txt // } // } // console.info('ret', ret) // return ret // }, // textareaCenterInput (item) { // // this[attr] = api.getStrByteLen(this[attr], length) // // console.info('textareaCenterInput', item) // // innerText innerHTML // // item.target.innerText = this.getMaxText(item.target.innerText) // this.$emit('input', item.target.innerText) // } }, created () {}, mounted () { this.init() console.info('value', this.value) } } </script> <style lang="less"> /*.textareaCenterWrap {*/ /*display: table;*/ /*width: 100%;*/ /*}*/ .textareaCenter { background-color: #CCCCCC; -webkit-user-modify: read-write-plaintext-only; user-modify: read-write-plaintext-only; width: 100%; height: 100%; margin: 0; /*!*display: inline-block;*!*/ display: table-cell; text-align: left; padding: 10px; /*!*padding-left: 10px;*!*/ vertical-align: middle; white-space: pre-wrap; font-size: 0.14rem; font-family: "微软雅黑 regular"; &:focus { outline: #d5e8fc auto 0px !important; } } </style>