文本选择和替换在 textarea 中无法正常工作

Posted

技术标签:

【中文标题】文本选择和替换在 textarea 中无法正常工作【英文标题】:Text selection and replacement not working properly in textarea 【发布时间】:2021-07-01 05:18:36 【问题描述】:

我正在尝试使用 javascript 制作用于格式化 textarea 标记的选定文本(md 和/或 html)的按钮(如粗体、斜体等)。

有时有效,有时无效。

代码链接 https://jsfiddle.net/3gn75zLb

JS 代码

function formatText(style) 
    var textarea_editor = document.getElementById('md-code');

    //get Selection
    var index_start = textarea_editor.selectionStart;
    var index_end = textarea_editor.selectionEnd;
    var text = textarea_editor.value;
    var selectedText = text.substring(index_start, index_end);
    var formatedText = selectedText;

    
        //format
        switch(style.toLowerCase()) 
            case 'b':
                var formatedText = "**"+selectedText+"**";
                break;

            case 'i':
                var formatedText = "*"+selectedText+"*";
                break;

            case 'u':
                var formatedText = "<u>"+selectedText+"</u>";
                break;

            case 'sup':
                var formatedText = "<sup>"+selectedText+"</sup>";
                break;

            case 'sub':
                var formatedText = "<sub>"+selectedText+"</sub>";
                break;

            case 'img':
                var formatedText = "![]("+selectedText+")";
                break;

            default:
                var formatedText = selectedText;
                break;
        

        textarea_editor.innerHTML = text.substring(0, index_start)+formatedText+text.substring(index_end, text.length);
    

有与按钮相关的点击事件调用formatText()函数

喜欢

formatText('b') 用** 将所选文本括起来,使其在markdown 中变为粗体。

问题

代码有问题吗? 有没有更好/更简单的方法可以使用 jQuery 或其他方法来做到这一点?

【问题讨论】:

使用代码 sn-p 功能发布您的代码。调试起来会更容易。 索姆·谢卡尔·穆克吉!我已将 jsfiddle 链接添加到 html 和 JavaScript 【参考方案1】:

问题是你设置了textareainnerHTML,你需要设置文本区域的value属性。

innerHTML with text area 只能用于设置文本区域的初始内容,但只要在textarea 中输入内容,innerHTML 将不会执行任何操作,此时需要使用value 财产。

此外,目前如果没有选择文本,即使代码添加了样式,如果selectedText 为空,您可以简单地从函数中返回。

请看下面的代码:

function formatText(style) 
  var textarea_editor = document.getElementById('md-code');
  
  //get Selection
  var index_start = textarea_editor.selectionStart;
  var index_end = textarea_editor.selectionEnd;
  var text = textarea_editor.value;
  var selectedText = text.substring(index_start, index_end);
  var formatedText = selectedText;
  
  if (!selectedText) return;
  
  //format
  switch (style.toLowerCase()) 
    case 'b':
      var formatedText = "**" + selectedText + "**";
      break;

    case 'i':
      var formatedText = "*" + selectedText + "*";
      break;

    case 'u':
      var formatedText = "<u>" + selectedText + "</u>";
      break;

    case 'sup':
      var formatedText = "<sup>" + selectedText + "</sup>";
      break;

    case 'sub':
      var formatedText = "<sub>" + selectedText + "</sub>";
      break;

    case 'img':
      var formatedText = "![](" + selectedText + ")";
      break;

    default:
      var formatedText = selectedText;
      break;
  

  textarea_editor.value = text.substring(0, index_start) + formatedText + text.substring(index_end, text.length);
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">

<div class="jumbotron bg-white px-2 py-0 m-0">
  <div class="my-2">
    <button type="button" class="btn btn-outline-secondary" onclick="formatText('b')"><b>B</b></button>
    <button type="button" class="btn btn-outline-secondary" onclick="formatText('i')"><i>I</i></button>
    <button type="button" class="btn btn-outline-secondary" onclick="formatText('u')"><u>U</u></button>
    <button type="button" class="btn btn-outline-secondary" onclick="formatText('sup')">T<sup>abc</sup></button>
    <button type="button" class="btn btn-outline-secondary" onclick="formatText('sub')">T<sub>abc</sub></button>
    <button type="button" class="btn btn-outline-secondary" onclick="formatText('img')">Img</button>
  </div>
  <textarea id="md-code" class="form-control" rows="20" name="note_content" placeholder="Markdown and/or HTML text"></textarea>
</div>

【讨论】:

以上是关于文本选择和替换在 textarea 中无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

DOM onselect 无法正常工作

Java Swing TextArea“粘性文本”[重复]

没有 DIV 标记的 TextArea 无法正常工作

Slickgrid 单元格文本选择在 Chrome 或 Firefox 中无法正常工作

textarea保持文本样式

如何使用javascript替换textarea元素中的文本? [复制]