首页 > 解决方案 > 在 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);
  }

(其中 editor 是prosemiror编辑器)

我也尝试过仅使用可编辑的标准内容而没有运气:

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>

有没有更好的方法来解决这个问题,或者有没有简单的方法来解决我上面的尝试?

标签: javascriptcontenteditableprose-mirror

解决方案


在本机控件上触发您自己的事件不会触发对它们的任何操作。这些事件是交互发生的通知,而不是它们的原因。

除非您完全控制 contenteditable 的内容并为自己建立索引,否则我认为没有任何简单的方法可以做到这一点。Contenteditables 似乎没有为 execCommand 映射任何命令来移动光标,所以那里也没有运气。

DOM-wise 有大量的配置会导致换行,所以如果你想手动处理这个,你必须考虑很多情况。您将不断地遍历 DOM,同时获取每个元素的计算样式以确定换行性。我认为这可能比它的价值更麻烦,坚持使用本地箭头键可能是最理智的。

我希望我有更好的消息,但我很确定目前没有好的解决方案。


推荐阅读