在 contenteditable 中向下移动一行
Move down a line in contenteditable
我有一个内容可编辑元素,我正在尝试引入一些键命令以在其中移动光标(vim 键绑定)。不过,我正在努力添加基本的上下移动 (j & k),这相当于按 ArrowUp 和 ArrowDown。
我试过模拟箭头键事件,但还没有成功:
function fireKey(editor: EditorView, key: String) {
let keyName = '';
switch (key) {
case "left":
keyName = 'ArrowLeft';
break;
case "up":
keyName = 'ArrowUp';
break;
case "right":
keyName = 'ArrowRight';
break;
case "down":
keyName = 'ArrowDown';
break;
}
let evt = new KeyboardEvent("keydown", {
"bubbles": true,
"key": keyName,
"code": keyName,
});
editor.dom.dispatchEvent(evt);
}
(编辑器是 prosemirror 编辑器)
我也试过只用一个标准的内容可编辑但运气不好:
function fireKey(el, key) {
let keyName = '';
switch (key) {
case "left":
keyName = 'ArrowLeft';
break;
case "up":
keyName = 'ArrowUp';
break;
case "right":
keyName = 'ArrowRight';
break;
case "down":
keyName = 'ArrowDown';
break;
}
let evt = new KeyboardEvent("keydown", {
"bubbles": true,
"key": keyName,
"code": keyName,
});
el.dispatchEvent(evt);
}
let $editor = document.getElementById("editor");
$editor.addEventListener('keydown', function(evt) {
console.log("Key down", evt.key);
if (evt.key == 'j') {
fireKey($editor, 'down');
evt.preventDefault(true);
}
else if (evt.key == 'k') {
fireKey($editor, 'up');
evt.preventDefault(true);
}
});
<div id="editor" contenteditable="true">
<p>Test</p>
<p>Test 2</p>
<p>Test 3</p>
</div>
有没有更好的方法来解决这个问题,或者有没有简单的方法来解决我上面的尝试?
在本机控件上触发您自己的事件不会触发对它们的任何操作。这些事件是交互发生的通知,而不是交互的原因。
我认为没有任何简单的方法可以做到这一点,除非您完全控制 contenteditable 的内容并为自己建立索引。 Contenteditables 似乎没有为 execCommand 映射任何命令来移动光标,所以也没有运气。
DOM-wise 有大量的配置会导致换行,所以如果你想手动处理它,你将不得不考虑很多情况。您将不断遍历 DOM,同时获取每个元素的计算样式以确定是否换行。我认为这可能比它的价值更麻烦,坚持使用原生箭头键可能是最明智的。
我希望我有更好的消息,但我很确定目前没有好的解决方案。
我有一个内容可编辑元素,我正在尝试引入一些键命令以在其中移动光标(vim 键绑定)。不过,我正在努力添加基本的上下移动 (j & k),这相当于按 ArrowUp 和 ArrowDown。
我试过模拟箭头键事件,但还没有成功:
function fireKey(editor: EditorView, key: String) {
let keyName = '';
switch (key) {
case "left":
keyName = 'ArrowLeft';
break;
case "up":
keyName = 'ArrowUp';
break;
case "right":
keyName = 'ArrowRight';
break;
case "down":
keyName = 'ArrowDown';
break;
}
let evt = new KeyboardEvent("keydown", {
"bubbles": true,
"key": keyName,
"code": keyName,
});
editor.dom.dispatchEvent(evt);
}
(编辑器是 prosemirror 编辑器)
我也试过只用一个标准的内容可编辑但运气不好:
function fireKey(el, key) {
let keyName = '';
switch (key) {
case "left":
keyName = 'ArrowLeft';
break;
case "up":
keyName = 'ArrowUp';
break;
case "right":
keyName = 'ArrowRight';
break;
case "down":
keyName = 'ArrowDown';
break;
}
let evt = new KeyboardEvent("keydown", {
"bubbles": true,
"key": keyName,
"code": keyName,
});
el.dispatchEvent(evt);
}
let $editor = document.getElementById("editor");
$editor.addEventListener('keydown', function(evt) {
console.log("Key down", evt.key);
if (evt.key == 'j') {
fireKey($editor, 'down');
evt.preventDefault(true);
}
else if (evt.key == 'k') {
fireKey($editor, 'up');
evt.preventDefault(true);
}
});
<div id="editor" contenteditable="true">
<p>Test</p>
<p>Test 2</p>
<p>Test 3</p>
</div>
有没有更好的方法来解决这个问题,或者有没有简单的方法来解决我上面的尝试?
在本机控件上触发您自己的事件不会触发对它们的任何操作。这些事件是交互发生的通知,而不是交互的原因。
我认为没有任何简单的方法可以做到这一点,除非您完全控制 contenteditable 的内容并为自己建立索引。 Contenteditables 似乎没有为 execCommand 映射任何命令来移动光标,所以也没有运气。
DOM-wise 有大量的配置会导致换行,所以如果你想手动处理它,你将不得不考虑很多情况。您将不断遍历 DOM,同时获取每个元素的计算样式以确定是否换行。我认为这可能比它的价值更麻烦,坚持使用原生箭头键可能是最明智的。
我希望我有更好的消息,但我很确定目前没有好的解决方案。