Попытка установить каретку в конце contenteditable div на фокусе и затем нажать ввод для новой строки - PullRequest
0 голосов
/ 03 октября 2019

Я запускаю этот код, чтобы установить каретку в конце предмета спора, когда div сфокусирован. Я также запускаю скрипт на клавише ввода, чтобы исправить странность разрывов строк в Firefox. По какой-то причине эти две функции не работают вместе, и я получаю следующее сообщение:

IndexSizeError: Индекс или размер отрицателен или превышает допустимую сумму

Попробуйте нажать на div и нажмите Enter в Firefox, и вы поймете, что я имею в виду. Это работает в Safari и Chrome.

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

function placeCaretAtEnd(el) {
    el.focus();
    if (typeof window.getSelection != "undefined"
            && typeof document.createRange != "undefined") {
        var range = document.createRange();
        range.selectNodeContents(el);
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (typeof document.body.createTextRange != "undefined") {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.collapse(false);
        textRange.select();
    }
}

$(document).on('keydown', 'div', function(e) {
  var keyCode = e.keyCode || e.which; 
  var $self = $(this);
  var esc = keyCode == 27;
  var nl = keyCode == 13;
  var tab = keyCode == 9;
  var shift = e.shiftKey;
  var sel, node, offset, text, textBefore, textAfter, range;

  if(nl)
  {
    sel = window.getSelection();

    // the node that contains the caret
    node = sel.anchorNode;

    // if ENTER was pressed while the caret was inside the input field

    // prevent the browsers from inserting <div>, <p>, or <br> on their own
    e.preventDefault();

    // the caret position inside the node
    offset = sel.anchorOffset;        

    // insert a '\n' character at that position
    text = node.textContent;
    textBefore = text.slice( 0, offset );
    textAfter = text.slice( offset ) || ' ';
    node.textContent = textBefore + '\n' + textAfter;

    // position the caret after that new-line character
    range = document.createRange();
    range.setStart( node, offset + 1 );
    range.setEnd( node, offset + 1 );

    // update the selection
    sel.removeAllRanges();
    sel.addRange( range );
  }
 });
 
$(document).on('focus', 'div', function(e) {
  var $self = $(this);
  setTimeout(function() {
    placeCaretAtEnd($self[0]);
  },0);
});
div {
  white-space: pre-wrap;
  overflow-wrap: break-word;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div contenteditable>Lots of text
Lots of text
Lots of text</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...