How to place the caret where it previously was after replacing the html of a contenteditable div?

喜欢而已 提交于 2019-12-05 17:35:12

rangy.js has a text range module that lets you save selection as indices of the characters that are selected, and then restore it. Since your modifications do not alter innerText, this looks like a perfect fit:

      var sel = rangy.getSelection();
      var savedSel = sel.saveCharacterRanges(this);
      $(this).html(html);
      sel.restoreCharacterRanges(this, savedSel);

Implementing this manually requires careful traversal of the DOM inside contenteditable and careful arithmetics with the indices; this can't be done with a few lines of code.

Your placeCaretAtEnd can't possibly place the caret after the link you've inserted, since it doesn't "know" which (of the possibly multiple) link it is. You have to save this information beforehand.

/**
* Trigger when someone releases a key on the field where you can post remarks, posts or reactions
*/
$(document).on("keyup", ".post-input-field", function (event) {

       // if the user has pressed the spacebar (32) or the enter key (13)
       if (event.keyCode === 32 || event.keyCode === 13) {
          let html = $(this).html();
          html = html.replace(/(^|\s)(#\w+)/g, " <a href=#>$2</a>").replace("<br>", ""); 
          var sel = rangy.getSelection();
          var savedSel = sel.saveCharacterRanges(this);
          $(this).html(html);
          sel.restoreCharacterRanges(this, savedSel);
       }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-core.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-textrange.js"></script>
<div contenteditable="true" class="post-input-field">
I love (replace this with #sushi and type space) but there is no fish at home
</div>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!