You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现点击text_area单词弹出拼写纠错候选菜单?求文档示例或插件

实现文本域拼写错误单词点击弹出修正菜单的方案

一、原生实现思路

如果不想依赖第三方插件,可以通过以下步骤自行实现:

  1. 开启/集成拼写检查
    • 利用浏览器原生的spellcheck属性(给textarea添加spellcheck="true")开启基础拼写检查,浏览器会自动标记拼写错误的单词;
    • 若需要更定制化的检查逻辑,可集成前端拼写检查库(如基于Hunspell的前端实现)来识别错误单词并标记。
  2. 定位点击的单词
    通过Selection API获取textarea中点击位置的文本范围,提取出被点击的单词。可以通过计算光标偏移量,向前/向后匹配单词边界来实现。
  3. 获取修正候选词
    • 部分现代浏览器支持navigator.spellcheck.getSpellingSuggestions() API,可直接获取错误单词的候选修正词;
    • 若使用第三方拼写库,直接调用库的方法获取候选词列表。
  4. 弹出自定义操作菜单
    创建浮动的DOM元素作为菜单,将候选词填充到菜单中,监听菜单选项的点击事件,替换textarea中的错误单词。

二、现成工具/插件推荐

如果希望快速实现功能,这些成熟工具内置了所需的拼写检查与修正菜单功能:

  • CKEditor:主流富文本编辑器,内置拼写检查模块,点击标记为错误的单词时自动弹出修正候选菜单,支持自定义拼写检查服务。
  • TinyMCE:另一个常用富文本编辑器,自带拼写检查插件,可配置为点击错误单词显示修正选项。
  • SpellChecker.js:轻量级前端拼写检查库,可配合自定义菜单逻辑,实现点击错误单词弹出修正列表的功能。

三、简单原生实现示例

HTML

<textarea id="spell-check-textarea" spellcheck="true" rows="5" cols="50">Ths is a test with speling erors.</textarea>

JavaScript

const textarea = document.getElementById('spell-check-textarea');

// 监听点击事件
textarea.addEventListener('click', async (e) => {
  const selection = window.getSelection();
  if (!selection.rangeCount) return;

  const word = getClickedWord(textarea);
  if (!word) return;

  // 尝试获取浏览器原生拼写建议(兼容性:Chrome、Edge等部分浏览器支持)
  if (navigator.spellcheck?.getSpellingSuggestions) {
    const suggestions = await navigator.spellcheck.getSpellingSuggestions(word);
    if (suggestions.length) {
      showSuggestionMenu(e.clientX, e.clientY, suggestions, (selected) => {
        replaceWordInTextarea(textarea, word, selected);
      });
    }
  }
});

// 提取点击位置的单词
function getClickedWord(textarea) {
  const text = textarea.value;
  const offset = textarea.selectionStart;
  if (offset < 0 || offset >= text.length) return null;

  // 找单词起始位置
  let start = offset;
  while (start > 0 && /[a-zA-Z]/.test(text[start - 1])) start--;
  // 找单词结束位置
  let end = offset;
  while (end < text.length && /[a-zA-Z]/.test(text[end])) end++;

  return text.slice(start, end);
}

// 显示修正菜单
function showSuggestionMenu(x, y, suggestions, onSelect) {
  // 移除已有菜单
  const oldMenu = document.getElementById('spell-suggest-menu');
  if (oldMenu) oldMenu.remove();

  const menu = document.createElement('div');
  menu.id = 'spell-suggest-menu';
  Object.assign(menu.style, {
    position: 'absolute',
    left: `${x}px`,
    top: `${y + 15}px`,
    backgroundColor: '#fff',
    border: '1px solid #ddd',
    borderRadius: '4px',
    padding: '6px 0',
    boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
    zIndex: '9999',
    fontSize: '14px'
  });

  suggestions.forEach(suggest => {
    const item = document.createElement('div');
    item.textContent = suggest;
    Object.assign(item.style, {
      padding: '6px 16px',
      cursor: 'pointer',
      whiteSpace: 'nowrap'
    });
    item.addEventListener('mouseover', () => item.style.backgroundColor = '#f5f5f5');
    item.addEventListener('mouseout', () => item.style.backgroundColor = '#fff');
    item.addEventListener('click', () => {
      onSelect(suggest);
      menu.remove();
    });
    menu.appendChild(item);
  });

  document.body.appendChild(menu);

  // 点击外部关闭菜单
  document.addEventListener('click', (e) => {
    if (!menu.contains(e.target)) menu.remove();
  }, { once: true });
}

// 替换文本域中的单词
function replaceWordInTextarea(textarea, oldWord, newWord) {
  const text = textarea.value;
  const offset = textarea.selectionStart;
  let start = offset;
  while (start > 0 && /[a-zA-Z]/.test(text[start - 1])) start--;
  let end = offset;
  while (end < text.length && /[a-zA-Z]/.test(text[end])) end++;

  textarea.value = text.slice(0, start) + newWord + text.slice(end);
  // 光标定位到替换后的位置
  textarea.selectionStart = start + newWord.length;
  textarea.selectionEnd = start + newWord.length;
}

CSS(可选)

#spell-suggest-menu div:hover {
  background-color: #f5f5f5;
}

内容的提问来源于stack exchange,提问作者ИНДУС Геймдев

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 17:55:53