setting loses caret position on <pre> element on pressing TAB key
I have pre
with contentEditable="true"
on my webpage and I am trying to make it append "\t"
when I press <TAB>
. I found some other plugins for that but they were working only on <textarea>
.
So, the problem is that when I append text to the <pre>
through jQuery, it loses the caret position. I was sure it was losing focus but it's not. So $("pre").focus()
, will do nothing.
I tried to blur it first but this is not practical cause the caret will return on different position depending on the bro开发者_StackOverflow中文版wser. some help please... :P,
My code is here: http://jsfiddle.net/parisk/kPRpj/
Try using document.execCommand
instead. Here’s a demo. In short:
$("pre").keydown(function(e){
if (e.keyCode==9) {
e.preventDefault();
document.execCommand('InsertHTML', false, '\t');
}
});
firstly Try
$("pre").keydown(function(e){
if (e.keyCode==9) {
e.preventDefault();
$("pre").append("\t");
}
});
for inserting a tab. it will insert a tab after your cursor
then in chrome
var myselection = document.getSelection();
myselection.extend(jQuery("pre")[0].lastChild, jQuery("pre")[0].lastChild.length)
myselection.collapseToEnd();
in IE8
var myselection = document.selection;
myselection.extend(jQuery("pre")[0].lastChild, jQuery("pre")[0].lastChild.length)
myselection.collapseToEnd();
should get you caret at the end.
(all together)
$("pre").keydown(function(e){
if (e.keyCode==9) {
e.preventDefault();
$("pre").append("\t");
var myselection = null;
if(document.getSelection)
{
myselection = document.getSelection();
}
else if (document.selection)
{
myselection = document.selection;
}
if(myselection != null)
{
myselection.extend(jQuery("pre")[0].lastChild, jQuery("pre")[0].lastChild.length)
myselection.collapseToEnd();
}
}
});
EDIT
it would also be safer to add in a test to see if the lastChild is null and other such. Also in the keydown function jQuery("pre")
would be better to be jQuery(this)
and put into a variable if you are using more than once. (which the example is but I'm too lazy)
To only your question, the jquery caret libraries are pretty good at encapsulating the quirks around the different browsers (namely IE): http://plugins.jquery.com/plugin-tags/caret
You could always just use this to get an index of all the tab positions and then clean them later...
James Khoury's answer always puts the caret at the end of the <pre>
, which is not desirable when the user hits tab
in the middle of the text.
Here is a modified version tha fixes this issue : http://jsfiddle.net/kPRpj/12/.
It should be fairly trivial to make tab
indent the line instead of adding a tab
character at the caret position. To do that, you would replace
container.textContent = text.substring(0,start)+'\t'+text.substring(end);
with
var left = text.substring(0,start);
var lastLine = left.lastIndexOf("\n");
if (lastLine == -1) lastLine = 0;
container.textContent = left.substring(0,lastLine)+'\t'+text.substring(lastLine);
I've put a version that behaves this way on jsfiddle. However you might need to work around some inconsistencies in their management of '\n\r'
. For example, I see that chromium sees each line as a separate text node, which is rather unexpected. I haven't tested it in other browsers.
精彩评论