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?
jquery html contenteditable caret cursor-position
add a comment |
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?
jquery html contenteditable caret cursor-position
add a comment |
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?
jquery html contenteditable caret cursor-position
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
jquery html contenteditable caret cursor-position
edited Nov 12 at 8:49
Aditya Sharma
4541415
4541415
asked Nov 12 at 5:47
rtillery
235
235
add a comment |
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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