jquery Setting cursor to last position in contenteditable div with proper cursor position











up vote
0
down vote

favorite












I am moving between contenteditable divs with the arrow keys, and I'm using the cursor position value (window.getSelection().anchorOffset) to tell the position value of the cursor and know when I've reached the start or end of a div. As I move to the left (LEFT ARROW while the cursor is in position 0), I want the cursor to move to the right end of the previous div. I found Tim Down's answer, which does indeed allow me to move the cursor to the previous div. Then using the extra comment from Tim, I was able to place the cursor on the right edge of the previous div. However, I find that the cursor position value reported does not match the actual cursor position (in Chrome).



In response to a duplicate of the question, Mr_Green posted a fiddle, which I've modified to show the issue.



var result = $('#result');

$('#result').keydown(function(e) {
curposondown = window.getSelection().anchorOffset;
console.log(`cursorposondown: ${curposondown}`);
});
$('#result').keyup(function(e) {
console.log(e);
var element = e.currentTarget;
var key = e.which;
var text = element.textContent;
var pos = window.getSelection().anchorOffset;
console.log(`text: ${text}`);
console.log(`text length: ${text.length}`);
console.log(`char: ${e.which}`);
console.log(`cursor: ${pos}`);
});

$('.click').click(function () {
var preHtml = result.html();
result.html(preHtml + "hello");

result.focus();
placeCaretAtEnd( document.getElementById("result") );
});

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();
}
}


After typing in a few letters, while observing the console (Developer Tools), use the LEFT & RIGHT ARROW keys to move between the letters and see what is output for each keydown/keyup. Note that the cursor position shows the position before the cursor is moved on the keydown, and then after it's moved on keyup. (This is why I added the keydown hook, to differentiate between the first time the cursor moved to 0, which should not move to the previous div, and the time it is already at 0, when it should.) Pay particular attention to what position values are reported at the right end of the text, when you press the RIGHT ARROW.



Now press the "click to add text" button to append the "hello" string, and let the code move the cursor to the right side of the text. Then press the RIGHT ARROW and note that the cursor position says the cursor is at position 1 (on key down and up).



This means I can't detect that the cursor is at the right side of the text, at this point. (So the cursor cannot immediately be moved back to the next div, as it normally would if it were in that position.) After the user uses the LEFT ARROW key to move one character left, then moves back with the RIGHT ARROW key, the cursor position corrects itself.



So, the question is, is there a way to ensure that the cursor position value is updated to match the actual cursor position? Or is there something else I'm doing here that is inadvisable?










share|improve this question




























    up vote
    0
    down vote

    favorite












    I am moving between contenteditable divs with the arrow keys, and I'm using the cursor position value (window.getSelection().anchorOffset) to tell the position value of the cursor and know when I've reached the start or end of a div. As I move to the left (LEFT ARROW while the cursor is in position 0), I want the cursor to move to the right end of the previous div. I found Tim Down's answer, which does indeed allow me to move the cursor to the previous div. Then using the extra comment from Tim, I was able to place the cursor on the right edge of the previous div. However, I find that the cursor position value reported does not match the actual cursor position (in Chrome).



    In response to a duplicate of the question, Mr_Green posted a fiddle, which I've modified to show the issue.



    var result = $('#result');

    $('#result').keydown(function(e) {
    curposondown = window.getSelection().anchorOffset;
    console.log(`cursorposondown: ${curposondown}`);
    });
    $('#result').keyup(function(e) {
    console.log(e);
    var element = e.currentTarget;
    var key = e.which;
    var text = element.textContent;
    var pos = window.getSelection().anchorOffset;
    console.log(`text: ${text}`);
    console.log(`text length: ${text.length}`);
    console.log(`char: ${e.which}`);
    console.log(`cursor: ${pos}`);
    });

    $('.click').click(function () {
    var preHtml = result.html();
    result.html(preHtml + "hello");

    result.focus();
    placeCaretAtEnd( document.getElementById("result") );
    });

    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();
    }
    }


    After typing in a few letters, while observing the console (Developer Tools), use the LEFT & RIGHT ARROW keys to move between the letters and see what is output for each keydown/keyup. Note that the cursor position shows the position before the cursor is moved on the keydown, and then after it's moved on keyup. (This is why I added the keydown hook, to differentiate between the first time the cursor moved to 0, which should not move to the previous div, and the time it is already at 0, when it should.) Pay particular attention to what position values are reported at the right end of the text, when you press the RIGHT ARROW.



    Now press the "click to add text" button to append the "hello" string, and let the code move the cursor to the right side of the text. Then press the RIGHT ARROW and note that the cursor position says the cursor is at position 1 (on key down and up).



    This means I can't detect that the cursor is at the right side of the text, at this point. (So the cursor cannot immediately be moved back to the next div, as it normally would if it were in that position.) After the user uses the LEFT ARROW key to move one character left, then moves back with the RIGHT ARROW key, the cursor position corrects itself.



    So, the question is, is there a way to ensure that the cursor position value is updated to match the actual cursor position? Or is there something else I'm doing here that is inadvisable?










    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I am moving between contenteditable divs with the arrow keys, and I'm using the cursor position value (window.getSelection().anchorOffset) to tell the position value of the cursor and know when I've reached the start or end of a div. As I move to the left (LEFT ARROW while the cursor is in position 0), I want the cursor to move to the right end of the previous div. I found Tim Down's answer, which does indeed allow me to move the cursor to the previous div. Then using the extra comment from Tim, I was able to place the cursor on the right edge of the previous div. However, I find that the cursor position value reported does not match the actual cursor position (in Chrome).



      In response to a duplicate of the question, Mr_Green posted a fiddle, which I've modified to show the issue.



      var result = $('#result');

      $('#result').keydown(function(e) {
      curposondown = window.getSelection().anchorOffset;
      console.log(`cursorposondown: ${curposondown}`);
      });
      $('#result').keyup(function(e) {
      console.log(e);
      var element = e.currentTarget;
      var key = e.which;
      var text = element.textContent;
      var pos = window.getSelection().anchorOffset;
      console.log(`text: ${text}`);
      console.log(`text length: ${text.length}`);
      console.log(`char: ${e.which}`);
      console.log(`cursor: ${pos}`);
      });

      $('.click').click(function () {
      var preHtml = result.html();
      result.html(preHtml + "hello");

      result.focus();
      placeCaretAtEnd( document.getElementById("result") );
      });

      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();
      }
      }


      After typing in a few letters, while observing the console (Developer Tools), use the LEFT & RIGHT ARROW keys to move between the letters and see what is output for each keydown/keyup. Note that the cursor position shows the position before the cursor is moved on the keydown, and then after it's moved on keyup. (This is why I added the keydown hook, to differentiate between the first time the cursor moved to 0, which should not move to the previous div, and the time it is already at 0, when it should.) Pay particular attention to what position values are reported at the right end of the text, when you press the RIGHT ARROW.



      Now press the "click to add text" button to append the "hello" string, and let the code move the cursor to the right side of the text. Then press the RIGHT ARROW and note that the cursor position says the cursor is at position 1 (on key down and up).



      This means I can't detect that the cursor is at the right side of the text, at this point. (So the cursor cannot immediately be moved back to the next div, as it normally would if it were in that position.) After the user uses the LEFT ARROW key to move one character left, then moves back with the RIGHT ARROW key, the cursor position corrects itself.



      So, the question is, is there a way to ensure that the cursor position value is updated to match the actual cursor position? Or is there something else I'm doing here that is inadvisable?










      share|improve this question















      I am moving between contenteditable divs with the arrow keys, and I'm using the cursor position value (window.getSelection().anchorOffset) to tell the position value of the cursor and know when I've reached the start or end of a div. As I move to the left (LEFT ARROW while the cursor is in position 0), I want the cursor to move to the right end of the previous div. I found Tim Down's answer, which does indeed allow me to move the cursor to the previous div. Then using the extra comment from Tim, I was able to place the cursor on the right edge of the previous div. However, I find that the cursor position value reported does not match the actual cursor position (in Chrome).



      In response to a duplicate of the question, Mr_Green posted a fiddle, which I've modified to show the issue.



      var result = $('#result');

      $('#result').keydown(function(e) {
      curposondown = window.getSelection().anchorOffset;
      console.log(`cursorposondown: ${curposondown}`);
      });
      $('#result').keyup(function(e) {
      console.log(e);
      var element = e.currentTarget;
      var key = e.which;
      var text = element.textContent;
      var pos = window.getSelection().anchorOffset;
      console.log(`text: ${text}`);
      console.log(`text length: ${text.length}`);
      console.log(`char: ${e.which}`);
      console.log(`cursor: ${pos}`);
      });

      $('.click').click(function () {
      var preHtml = result.html();
      result.html(preHtml + "hello");

      result.focus();
      placeCaretAtEnd( document.getElementById("result") );
      });

      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();
      }
      }


      After typing in a few letters, while observing the console (Developer Tools), use the LEFT & RIGHT ARROW keys to move between the letters and see what is output for each keydown/keyup. Note that the cursor position shows the position before the cursor is moved on the keydown, and then after it's moved on keyup. (This is why I added the keydown hook, to differentiate between the first time the cursor moved to 0, which should not move to the previous div, and the time it is already at 0, when it should.) Pay particular attention to what position values are reported at the right end of the text, when you press the RIGHT ARROW.



      Now press the "click to add text" button to append the "hello" string, and let the code move the cursor to the right side of the text. Then press the RIGHT ARROW and note that the cursor position says the cursor is at position 1 (on key down and up).



      This means I can't detect that the cursor is at the right side of the text, at this point. (So the cursor cannot immediately be moved back to the next div, as it normally would if it were in that position.) After the user uses the LEFT ARROW key to move one character left, then moves back with the RIGHT ARROW key, the cursor position corrects itself.



      So, the question is, is there a way to ensure that the cursor position value is updated to match the actual cursor position? Or is there something else I'm doing here that is inadvisable?







      jquery html contenteditable caret cursor-position






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 12 at 8:49









      Aditya Sharma

      4541415




      4541415










      asked Nov 12 at 5:47









      rtillery

      235




      235





























          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53256504%2fjquery-setting-cursor-to-last-position-in-contenteditable-div-with-proper-cursor%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53256504%2fjquery-setting-cursor-to-last-position-in-contenteditable-div-with-proper-cursor%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Xamarin.iOS Cant Deploy on Iphone

          Glorious Revolution

          Dulmage-Mendelsohn matrix decomposition in Python