首先需要綁定兩個事件compositionstart、compositionend兩個事件分別是輸入法喚起輸入法關閉
setup: (ed) => { const vm = this ed.on('keyup', function (e) { vm.wordLimit(e) }); ed.on('input', function (e) { vm.wordLimit(e) }) ed.on('compositionstart', function (e) { vm.isChinese = false }); ed.on('compositionend', function (e) { vm.isChinese = true }) }
在keyup和keyinput事件里調用核心字數控制函數並且代入event,輸入法輸入時innerText有可能跳過1000所以要兼容下輸入跳過問題
//字數限制 wordLimit (e) { const vm = this let last = '' let lastIndex = '' let startVal = '' let endVal = '' if (e.target.innerText.length === 1000) { vm.htmlText = e.target.innerHTML //兼容輸入法有可能會跳過1000 } else if ((!vm.isChinese && e.target.innerText.length === 1001)) { last = e.target.innerText.substr(e.target.innerText.length - 1, 1) lastIndex = e.target.innerHTML.lastIndexOf(last) startVal = e.target.innerHTML.substring(0, lastIndex) endVal = e.target.innerHTML.substring(lastIndex + 1, e.target.innerHTML.length) vm.htmlText = startVal + endVal } if (e.target.innerText.length > 1000) { e.target.innerHTML = vm.htmlText var ifra = document.getElementById("tinymces_ifr"); this.keepLastIndex(ifra.contentWindow.document.getElementById('tinymce'), ifra.contentWindow) if (!this.limitNum) { this.$message.error('長度限制為1000個字符') this.limitNum++ } } },
整體的核心思路判斷富文本編輯器的innerText的字符數量,如果到達了指定文字那么我們就記錄下當前的innerHTML,當超過了指定數量我們就把之前記錄的innerHTML賦值給e.target.innerHTML,防止用戶繼續輸入,要注意的是發往后端的是innerHTML是帶有HTML標簽的所以后端不要進行字符攔截,純前端攔截。
只做了這些可以解決正常輸入限制字數,這里還有一個問題是粘貼的時候這部分的思路是粘貼時候過濾掉所有的標簽然后用限制字數減去輸入框現有字數可以知道距離輸入框限制字數還有多數個字符,然后在插入的時候用限制字數減去輸入框內容字數就可以啦,這里有個this.limitNum參數,這個是我項目的需求,主要作用是超過1000字符長度彈框只彈一次,有這個需求自行添加
init_instance_callback: (editor) => { // 注冊事件 editor.on('paste', (e) => { var ifra = document.getElementById("tinymces_ifr"); e.preventDefault(); var contentOnBlur = (e.originalEvent || e).clipboardData.getData('text/plain'); contentOnBlur = contentOnBlur.replace(/(<([^>]+)>)/ig, ''); if (!(1000 - e.target.innerText.length) && !this.limitNum) { this.$message.error('長度限制為1000個字符') this.limitNum++ } ifra.contentWindow.document.execCommand('insertText', true, contentOnBlur.slice(0, 1000 - e.target.innerText.length)); }); },
本人前端小白一昧,有更好的方案希望大佬指點。