admin 管理员组文章数量: 1086019
I am attempting to create a JavaScript editor for a web page that employs syntax-based formatting. It pletely replaces the innerHTML
of a <pre>
tag using onkeyup
. However, this results in the caret being moved to the beginning of the editor.
The only solution that I can find is to get the offset of the selection start and end before changes are made, then set these at the end. My code for getting the selection start and end is modified from :
var selStart, selEnd;
if (typeof window.getSelection != "undefined") {
var range = window.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(editor);
preCaretRange.setEnd(range.endContainer, range.endOffset);
selStart = preCaretRange.toString().length;
selEnd = selStart + range.toString().length;
} else if (typeof document.selection != "undefined" && document.selection.type != "Control") {
var textRange = document.selection.createRange();
var preCaretTextRange = document.body.createTextRange();
preCaretTextRange.moveToElementText(editor);
preCaretTextRange.setEndPoint("EndToEnd", textRange);
selStart = preCaretTextRange.text.length;
selEnd = selStart + textRange.text.length;
} else selStart = 0;
That part works fine, in Firefox, at least. My problem is with setting the selection. What I have so far is as follows:
// restore selection
if (selStart) {
if (range) {
range = window.getSelection().getRangeAt(0);
range.setStart(editor,selStart);
range.setEnd(editor,selEnd);
// Doesn't work, in FF at least
// Behavior: when there are no tags,
// for 0, caret set at beginning
// for 1, caret set at end
// for anything greater, "IndexSizeError: Index or size is negative or greater than the allowed amount"
// when the editor contains tags,
// for 0, caret set at beginning of editor
// for 1, caret set at beginning of first tag (unless same as start of editor)
// for 2, caret set at end of first tag
// for 3, caret set at beginning of second tag
// for 4, caret set at end of second tag, and so on
// for a number that is 1 greater than whatever number would set the caret at the end of the last tag, caret set at end of editor
// for a number greater than that, same error as before
} else if (document.selection && document.selection.createRange) {
// Not sure what to do here
}
}
Is that how setStart
and setEnd
are supposed to work? What am I doing wrong? Is there a better way to set the selection start and end, preferably without using a library?
I am attempting to create a JavaScript editor for a web page that employs syntax-based formatting. It pletely replaces the innerHTML
of a <pre>
tag using onkeyup
. However, this results in the caret being moved to the beginning of the editor.
The only solution that I can find is to get the offset of the selection start and end before changes are made, then set these at the end. My code for getting the selection start and end is modified from https://stackoverflow./a/4812022/2093695:
var selStart, selEnd;
if (typeof window.getSelection != "undefined") {
var range = window.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(editor);
preCaretRange.setEnd(range.endContainer, range.endOffset);
selStart = preCaretRange.toString().length;
selEnd = selStart + range.toString().length;
} else if (typeof document.selection != "undefined" && document.selection.type != "Control") {
var textRange = document.selection.createRange();
var preCaretTextRange = document.body.createTextRange();
preCaretTextRange.moveToElementText(editor);
preCaretTextRange.setEndPoint("EndToEnd", textRange);
selStart = preCaretTextRange.text.length;
selEnd = selStart + textRange.text.length;
} else selStart = 0;
That part works fine, in Firefox, at least. My problem is with setting the selection. What I have so far is as follows:
// restore selection
if (selStart) {
if (range) {
range = window.getSelection().getRangeAt(0);
range.setStart(editor,selStart);
range.setEnd(editor,selEnd);
// Doesn't work, in FF at least
// Behavior: when there are no tags,
// for 0, caret set at beginning
// for 1, caret set at end
// for anything greater, "IndexSizeError: Index or size is negative or greater than the allowed amount"
// when the editor contains tags,
// for 0, caret set at beginning of editor
// for 1, caret set at beginning of first tag (unless same as start of editor)
// for 2, caret set at end of first tag
// for 3, caret set at beginning of second tag
// for 4, caret set at end of second tag, and so on
// for a number that is 1 greater than whatever number would set the caret at the end of the last tag, caret set at end of editor
// for a number greater than that, same error as before
} else if (document.selection && document.selection.createRange) {
// Not sure what to do here
}
}
Is that how setStart
and setEnd
are supposed to work? What am I doing wrong? Is there a better way to set the selection start and end, preferably without using a library?
-
1
Keep in mind directly editing
innerHTML
causes the undo/redo buffer to be erased. Ran into similar problems developing tabIndent.js. – Julian H. Lam Commented Apr 5, 2013 at 2:58 -
@Julian: Thanks for the heads-up. I am aware of this, and considering using some kind of alternative, such as making the entire contents of the the editor a range and using something like
var code = range.toString();
followed byrange.deleteContents();
,code = range.createContextualFragment(code);
, andrange.insertNode(code);
– Brian McCutchon Commented Apr 5, 2013 at 3:08
1 Answer
Reset to default 6I've posted a couple of different functions for this. I can't find my most recent one but the following has a link to jsFiddle containing a restoreSelection()
function that should be helpful:
https://stackoverflow./a/7404126/96100
Update: I've found my more recent version of this code. It should work the same but the internals are a bit more elegant.
https://stackoverflow./a/13950376/96100
本文标签: javascriptSet Selection Start and End in a ContentedibleStack Overflow
版权声明:本文标题:javascript - Set Selection Start and End in a Contentedible - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1744072390a2528727.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论