开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜