Перейти на строку вниз в 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);
  }

(Где редактор - это редактор зеркала)

Я также пробовал использовать только стандартный контент, редактируемый без везения:

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>

Есть ли лучшие подходы к этой проблеме или есть простой способ исправить мою попытку выше?

1 ответ

Решение

Запуск ваших собственных событий в собственных элементах управления не вызывает никаких действий с ними. События - это уведомления о произошедших взаимодействиях, а не их причины.

Я не думаю, что есть какой-либо простой способ сделать это, если вы полностью не контролируете содержимое contenteditable и не создаете для себя индекс. В Contenteditables, похоже, нет команд, отображаемых для execCommand для перемещения курсора, так что и здесь не повезло.

С точки зрения DOM существует множество конфигураций, которые приводят к новым строкам, поэтому, если вы хотите справиться с этим вручную, вам придется рассмотреть множество случаев. Вы бы постоянно ходили по DOM, получая вычисленные стили для каждого элемента для определения новой строки. Я думаю, что это, вероятно, больше проблем, чем оно того стоит, и придерживаться родных клавиш со стрелками, вероятно, наиболее разумно.

Хотел бы я получить лучшие новости, но я почти уверен, что на данный момент хорошего решения нет.

Другие вопросы по тегам