Курсор переходит на конец строки после удаления узла и нажатия Enter (Firefox contenteditable) - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть этот код, который удаляет узел из элемента contenteditable, но если после удаления узла я нажимаю Enter , курсор переходит на конец строки, а не на новую строку. В любом случае, я могу это исправить? (Работает так, как задумано в Chrome, но не в Firefox).

const button = document.getElementById('button');
const target = document.getElementById('target');

button.addEventListener('click', function() {
  const range = document.createRange();

  range.selectNode(target);
  range.deleteContents();
          
  const sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
});
<div class="wrapper" contenteditable="true">
    Click <span id="target">Button</span> then hit enter
</div>
<button id="button">go</button>

Edit:

Похоже, что оборачивание содержимого предмета в тег div или p устраняет проблему, но возникает другая проблема, потому что, если пользователи продолжают нажимать backspace или delete или Ctrl + Backsapace ... и т. Д. Тег обтекания может быть удален.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

я наконец-то удалось решить эту проблему, к сожалению, это очень Hacky ... Я действительно ненавижу contenteditable :( Надеюсь, что это помогает любому, кто борется с этим.

Хитрость заключается в том, чтобы обернуть содержимое contenteditable в тег div или p, к сожалению, одного этого недостаточно, поскольку пользователь может легко удалить этот тег, когда удаляет все содержимое и продолжает нажимать backspace или удалить или даже удалить все сразу, используя ctrl + a backspace ... и т. д.

Итак, нам также нужно убедиться, что наш упаковщик вставлен, если он не существует.

шаги:

  1. Добавить обработчик keyup.
  2. Проверьте, существует ли наша оболочка.
  3. Если это так, все хорошо.
  4. Если нет:

    1. Как-то сохранить текущую позицию каретки (я вставляю поддельный элемент, чтобы отслеживать его положение)

    2. создайте наш элемент и оберните в него текущий контент.

    3. Восстановление позиции каретки (и удаление поддельного элемента).

Это слишком много работы для чего-то такого простого, я действительно надеюсь, что я ошибаюсь и что существует более простое решение.

document.execCommand('defaultParagraphSeparator', false, 'p');

const button = document.getElementById('button');

button.addEventListener('click', function() {
  const range = document.createRange();
  const target = document.getElementById('target');

  range.selectNode(target);
  range.deleteContents();

  const sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
});

$('.wrapper').on('keyup', function(e) {
  if ($('.wrapper > p').length == 0) {
    pushCaretMarker();
    const html = '<p>' + $(this).html() + '<br></p>';
    $(this).html(html);
    popCaretMarker();
  }
});

function pushCaretMarker() {
  const range = getRange();
  const $span = $('<span id="caret-marker">|</span>');
  range.insertNode($span.get(0));
  range.collapse();
}

function popCaretMarker() {
  const $span = $('#caret-marker');
  if ($span.length > 0) {
    const range = getRange();
    range.selectNode($span.get(0));

    range.deleteContents();
  }
}

function getRange() {
  return window.getSelection().getRangeAt(0);
}
.wrapper {
  min-height: 20px;
}

.wrapper>p {
  margin: 0;
}

.wrapper>p:not(:last-child) {
  margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="wrapper" contenteditable="true">
  <p>
    Click <span id="target">Button</span> then hit enter
  </p>
</div>
<button id="button">go</button>
0 голосов
/ 26 апреля 2018

Какой браузер не работает? Кажется, работает на IE 11, FF, а также заявленный Chrome.

Вы всегда можете сделать ключевого слушателя и заставить его делать все, что вы хотите.

.onkeyup = function(e) {
    var key = e.keyCode ? e.keyCode : e.which;
    //13 is enter
    if (key === 13){       
       //Do work here.         
    }
}
...