【问题标题】:jQuery Get value of previous characters up till certain character within textareajQuery获取先前字符的值直到textarea中的某个字符
【发布时间】:2020-06-15 12:15:33
【问题描述】:

我使用 jquery 和电子制作了一个文本编辑器。我希望能够让文本编辑器自动完成 HTML 标记。

我想要的是当用户键入一个标签时,例如 <tag> 一个结束 </tag> 被插入。我计划通过检测何时键入> 并将字符保存到< 作为变量来做到这一点。然后我会在</> 之间插入这些字符。但是我不确定如何执行此操作。

我有以下代码:

function setCaretPosition(elemId, caretPos) {
    var el = document.getElementById(elemId);
    el.value = el.value;
    if (el !== null) {
        if (el.createTextRange) {
            var range = el.createTextRange();
            range.move('character', caretPos);
            range.select();
            return true;
        } else {
            if (el.selectionStart || el.selectionStart === 0) {
                el.focus();
                el.setSelectionRange(caretPos, caretPos);
                return true;
            } else {
                el.focus();
                return false;
            }
        }
    }
}

$("#input").on("keydown", function(e) {
    if (e.key === ">") {
        $("#input").focus();
        document.execCommand('insertHTML', true, '></>');
        var cursorPosition = $('#input').prop("selectionStart");
        setCaretPosition('input', cursorPosition - 3);

    }
});

<textarea class="form-control" id="input" spellcheck="false" wrap="off" placeholder="Get Creative!"></textarea>

有没有办法做到这一点?

【问题讨论】:

    标签: javascript jquery html text textarea


    【解决方案1】:

    是的,有。

    您可以将 textarea 的值替换为:从textarea 值的第一个位置到结束&gt; 的开始标记位置的子字符串添加结束标记字符串 剩余的字符串,如下所示。然后,使用setSelectionRange 设置光标位置(进一步阅读here)。此外,您可以使用textarea.selectionStart 获取textarea 的插入符号位置。大多数浏览器都支持它(查看here 找出支持此属性的浏览器)。

    这是一个非常基本的自动结束标签插入(尝试插入“测试文本”,转到文本区域的开头,然后添加一个标签):

    const textarea = document.querySelector('#textarea')
    let tag = {
      opened: false,
      textStart: null,
      textEnd: null
    }
    
    textarea.addEventListener('keydown', e => {
      if (e.key === '<') {
        tag.opened = true
        tag.textStart = textarea.selectionStart + 1
      } else if (e.key === '>') {
        e.preventDefault()
        tag.textEnd = textarea.selectionStart
        const tagText = textarea.value.substring(tag.textStart, tag.textEnd)
        const closingTag = `</${tagText}>`
        const value = textarea.value
        const beforeClosingTagText = value.substring(0, textarea.selectionStart)
        const afterClosingTagText = value.substring(textarea.selectionStart)
        const endCaretPosition = beforeClosingTagText.length + 1
    
        textarea.value = `${beforeClosingTagText}>${closingTag}${afterClosingTagText}`
        textarea.setSelectionRange(endCaretPosition, endCaretPosition)
        tag = {
          opened: false,
          textStart: null,
          textEnd: null
        }
      }
    })
    * {
      box-sizing: border-box;
    }
    
    textarea {
      width: 100%;
      height: 200px;
      overflow: auto;
      border-radius: 5px;
      border: 1px solid #12121244;
      padding: 10px;
    }
    
    textarea:focus {
      border: 1px solid #8fdef7;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <textarea class="form-control" id="textarea" spellcheck="false" wrap="off" placeholder="Get Creative!"></textarea>

    请注意,上面的代码只回答了您的从文本区域中的某个位置获取值到另一个特定位置并将所述值作为结束标记插入的问题;它不处理在文本编辑器中至关重要的其他场景。您仍然需要自己处理的一些场景包括:

    • 如果有人想插入小于号而不是标签(例如3 &lt; 4)怎么办?
    • 如果有人决定删除开始标签的开头怎么办?
    • 如果一个人在打开标签后移动插入符号的位置,并在关闭该标签之前在其他地方使用大于号 &gt; 怎么办?

    此外,execCommand 已过时,its use is discouraged

    【讨论】:

    • 感谢您的回答,我明白您的意思是说这种方法不适合文本编辑器。您能否为我指出一个更适合文本区域的解决方案的方向,或者可能在您的答案中加入另一个解决方案?
    • @AlexHawking 我并不是说这不是一个合适的解决方案。它是。但是,您只需要考虑所有这些情况以及可能发生的其他情况。你知道 VS 代码吗?它还具有自动关闭标签功能(请参阅此处:marketplace.visualstudio.com/…)。您可以在此处访问他们的代码:github.com/formulahendry/vscode-auto-close-tag/blob/master/src/… 并查看他们为实现自动关闭标签功能所做的工作。
    • 好吧,我正在考虑创建一个函数来检查文档是否为 HTML,如果是则仅应用自动完成功能。这就是我现在开始的方式,并最终添加代码以检查用户是否在两个脚本标签之间键入。
    • @AlexHawking 道歉。我链接的 Github 存储库不直接包含来自 VS 的代码。是其他人模拟了 VSCode 和 Sublime Text 自动关闭 XML、JS 等中的标签。
    • @AlexHawking 太棒了!您是否考虑过赠送赏金?
    猜你喜欢
    • 2018-01-26
    • 2013-02-07
    • 2021-01-09
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    相关资源
    最近更新 更多