function SpellCheckMain(app: App, options: any) { const SpellCheckAttribute = "spell-check-el"; let SpellCheckTimer: Map<string, number> = new Map(); let checkerId = 0; function checkElement(el: HTMLElement) { let attr = el.getAttribute(SpellCheckAttribute); if (attr) { clearTimeout(SpellCheckTimer.get(attr)); let timer = setTimeout(() => { checkElementAsync(el) }, 500); SpellCheckTimer.set(attr, timer) } } function checkText(words?: string | null): [string?] { if (!words) { return []; } let errorWordList: [string?] = []; try { let wordsList = words.match(/[a-zA-Z]+/ig); wordsList?.forEach((word) => { if (!checkWord(word)) { errorWordList.push(word); } }) } catch { } return errorWordList; } function checkWord(text: string) { //模拟拼写检查,这里使用其他检查库 return text.length > 6 ? false : true; } function checkElementAsync(el: HTMLElement) { let text = (el as HTMLInputElement).value || el.innerText; let result = checkText(text); let attr = el.getAttribute(SpellCheckAttribute); if (!attr) { return; } if (result && result.length) { el.style.background = "pink" let div = document.getElementById(attr); if (!div) { div = document.createElement("div"); div.id = attr; div.style.position = "absolute" div.style.top = "0px" div.style.left = el.clientWidth + "px" if (el.parentElement) { el.parentElement.style.position = "relative" if (el.parentElement.lastChild === el) { el.parentElement.appendChild(div); } else { el.parentElement.insertBefore(div, el.nextSibling); } } } div.innerHTML = result.length.toString() + " - " + result.join(","); } else { el.style.background = ""; let div = document.getElementById(attr); if (div) { div.innerHTML = "" } } console.log(result) } app.directive('spell-check', { created() { console.log("created", arguments) }, mounted: function (el, binding, vnode, oldVnode) { console.log("mounted", arguments) //set checker id for parent let attr = "spellcheck-" + (checkerId++); el.setAttribute(SpellCheckAttribute, attr); console.log("attr", attr) if (el.tagName.toUpperCase() === "DIV") { el.addEventListener("blur", function () { checkElement(el) }, false); } if (el.tagName.toUpperCase() === "INPUT") { el.addEventListener("keyup", function () { checkElement(el) }, false); } // el.addEventListener("focus", function () { // checkElement(el) // }, false); }, updated: function (el) { console.log("componentUpdated", arguments) checkElement(el); }, unmounted: function (el) { console.log("unmounted", arguments) let attr = el.getAttribute(SpellCheckAttribute); if (attr) { let div = document.getElementById(attr); if (div) { div.remove(); } } } }) }
main.ts中使用插件