我有一个<textarea>
元素,我监听某些按键,比如如果用户键入Tab键,我会阻止改变焦点的默认操作,并在正确的位置添加Tab字符。
问题是,当用户按下我监听的键之一时,撤销有点乱。我如何让撤销/重做功能工作?我想过监听ctrl/cmd-z和ctrl/cmd-shift-z键,记录所有内容,并处理撤销/重做,但然后编辑和上下文菜单选项将无法工作...
您可以通过键入带有制表符和回车符的字母,然后尝试撤消和重做:
const textarea = document.querySelector('textarea')
textarea.addEventListener('keydown', function (event) {
if (event.key == "Tab") {
event.preventDefault()
const cursor = textarea.selectionStart
textarea.value = textarea.value.slice(0, cursor) + '\t' + textarea.value.slice(textarea.selectionEnd)
textarea.selectionStart = textarea.selectionEnd = cursor + 1
} else if (event.key == "Enter") {
event.preventDefault()
const cursor = textarea.selectionStart
textarea.value = textarea.value.slice(0, cursor) + '\n' + textarea.value.slice(textarea.selectionEnd)
textarea.selectionStart = textarea.selectionEnd = cursor + 1
}
})
<textarea cols="50" rows="20"></textarea>
1条答案
按热度按时间wgx48brx1#
我认为问题的核心是JavaScript和浏览器默认的撤销方法之间缺乏交互。使用JavaScript将文本添加到文本区域并不会以任何方式告诉浏览器的“撤销”删除所添加的文本,因为浏览器的“撤销”只意味着删除用户输入的文本,而不是JavaScript输入的文本。
以你的代码为例,按下Enter键后,你告诉事件监听器
preventDefault
,这完全阻止了Enter键将用户输入附加到文本区域,然后你使用JavaScript合成输入,浏览器的“undo”不会跟踪。你可以通过使用
document.execCommand()
来克服这种缺乏交互的情况。你可以通过链接检查它的浏览器支持。