Задача: разработать проверку орфографии для пользовательского словаря (в моем случае это был словарь медицинских терминов).
Prelude: конечно, Google Chrome имеет встроенную в браузер проверку орфографии, но проблема в том, что нельзя настроить правила проверки и добавить в нее внешние словари. И это индивидуально для каждого пользователя.
Еще одна проблема заключается в том, что вы не можете стилизовать входной контент, чтобы добавить волнистое подчеркивание под неправильным словом.
Решение: создайте теневой div позади ввода с прозрачным текстом, но с красным подчеркиванием под ним.
<div id=”spellCheckerContainer” style=”position: relative; display: inline-block; width: 100%;”> @Html.TextBoxFor(m => m.DiseaseName, new { @class = “k-input k-textbox”, spellcheck = “false”, style = “width: 100%;text-align:left;position: absolute;outline: 0;z-index: 1;background: transparent;top: -1.8em;” }) <div id=”diseaseNameSpellChecker” spellcheck=”false” style=”width: 100%;position: absolute;top: -1.8em;z-index: 0;padding-left: 0.7em;color:transparent”> </div> </div>
Вот MVC с Razor, поэтому @Html.TextBoxFor — это просто ввод.
И CSS:
.err { display: inline-block; position: relative; } .err:before { content: “~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~”; font-size: 0.6em; color: red; width: 100%; position: absolute; top: 2.4em; overflow: hidden; }
И джаваскрипт:
$(“input#DiseaseName”).keyup(function (event) { spellCheck(event.currentTarget.value); }); function spellCheck(source) { var shadowDiv = $(“div#diseaseNameSpellChecker”); var index = 0; shadowDiv.empty(); while (index < source.length) { if (source[index] === “ “) { shadowDiv.append(“<span> </span>”); index++; } else { var wordEndIndex = source.substring(index).indexOf(“ “); if (wordEndIndex === -1) { wordEndIndex = source.length — index; } var word = source.substring(index, index + wordEndIndex); var wordSpan = $(“<span>” + word + “</span>”); checkIsWordHasTypos(word, wordSpan); shadowDiv.append(wordSpan); index += wordEndIndex; } } } function checkIsWordHasTypos(word, wordContainer) { var resultInLocalStorageIsHasTypo = localStorage.getItem(word); if (resultInLocalStorageIsHasTypo !== null) { setContainerIfItHasTypo(wordContainer, resultInLocalStorageIsHasTypo === “true”); return; } $.ajax({ url: “api/SpellChecking/CheckIsWordInDictionary”, data: {word: word}, success: function (msg) { var isHasTypo = !msg; setContainerIfItHasTypo(wordContainer, isHasTypo); localStorage.setItem(word, isHasTypo); }, error: function(e) { console.log(“error” + e); } });} function setContainerIfItHasTypo(wordContainer, isHasTypo) { if (isHasTypo) { wordContainer.addClass(“err”); } }
Здесь используется localStarage для хранения результатов проверки, я не хочу бомбить сервер каждым словом после каждого нажатия клавиши. Мы предполагаем, что правила проверки никогда не изменятся.