jQuery 获取前一个字符的值,直到文本区域内的某个字符

jQuery Get value of previous characters up till certain character within textarea

我使用 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>

有办法吗?

是的,有。

您可以将文本区域的值替换为:从 textarea 值的第一个位置到开始标记 > 结束位置的子字符串 添加 结束标记字符串 其余字符串如下所示。然后,使用 setSelectionRange 设置光标位置(进一步阅读 here). Also, you can get the caret position of a textarea using textarea.selectionStart. It is supported in most browsers (look here 以了解支持此 属性 的浏览器)。

这是一个非常基本的自动关闭标签插入(尝试插入 "Test Text",转到文本区域的开头,然后添加标签):

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 < 4)怎么办?
  • 如果一个人决定删除开头标签怎么办?
  • 如果有人在打开标签后移动插入符位置并在关闭标签前在别处使用大于号 > 怎么办?

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