使用contenteditable div需要更好的SQL语法高亮显示器

时间:2017-05-25 09:57:15

标签: javascript jquery contenteditable

我知道像这样的问题以类似的方式多次被问到,但是由于我对...感到满意,所以没有解决方案......

目标: 我希望有一个类似textarea(div contenteditable)的东西,其中的用法可以输入一些SQL。当用户输入SQL时,一些流行语如“SELECT”,“FROM”....应该是彩色的。但解决方案应该流畅,不会丢失光标位置并接受新行。如果正确的措辞是正确的话,应该可以改变颜色。

我尝试过的解决方案:

方式1 Change color of specific words in textarea

我试图将每个单词换行并放置一个跨度,就像链接中的示例一样。 问题:

  • 新行将被删除
  • 无法添加包含文字后缀的空格
  • 光标始终位于末尾

方式2 :正则表达式(我再也找不到链接)

不使用“$(this).text()”但是“$(this).html()”,删除所有标签(没有中断/新行)并使用正则表达式再次为单词着色。单词是彩色的,新的行仍然存在,但光标可能会丢失:/ 所以我试图保存当前光标位置并在结束时恢复...但它不起作用...这是我当前的代码:

$("#SQL_editor").on("keyup", function(e){
            if (e.keyCode == 32){
                saveSelection();

                var pureHtml = $(this).html();
                pureHtml = pureHtml.replace(new RegExp('<span class="statement">', 'g'),  '');
                pureHtml = pureHtml.replace(new RegExp('</span>', 'g'),  '');
                pureHtml = pureHtml.replace(new RegExp('SELECT ', 'g'),  '<span class="statement">SELECT </span>');
                pureHtml = pureHtml.replace(new RegExp('FROM ', 'g'),  '<span class="statement">FROM </span>');
                pureHtml = pureHtml.replace(new RegExp('WHERE ', 'g'),  '<span class="statement">WHERE </span>');
                pureHtml = pureHtml.replace(new RegExp('NULL ', 'g'),  '<span class="statement">NULL </span>');
                pureHtml = pureHtml.replace(new RegExp('ON ', 'g'),  '<span class="statement">ON </span>');
                pureHtml = pureHtml.replace(new RegExp('IN ', 'g'),  '<span class="statement">IN </span>');
                pureHtml = pureHtml.replace(new RegExp('LIKE ', 'g'),  '<span class="statement">LIKE </span>');
                pureHtml = pureHtml.replace(new RegExp('NOT ', 'g'),  '<span class="statement">NOT </span>');
                $(this).html(pureHtml);

                restoreSelection();
                //placeCaretAtEnd($("#SQL_editor").get(0));
            }
        });



function saveSelection(){
                console.log("save");
                if(window.getSelection)//non IE Browsers
                {
                    savedRange = window.getSelection().getRangeAt(0);
                }
                else if(document.selection)//IE
                { 
                    savedRange = document.selection.createRange();  
                } 
            }

            function restoreSelection(){
                isInFocus = true;
                document.getElementById("SQL_editor").focus();
                if (savedRange != null) {
                    if (window.getSelection) {//non IE and there is already a selection{

                        var s = window.getSelection();
                        if (s.rangeCount > 0) 
                            s.removeAllRanges();
                        s.addRange(savedRange);
                    } else if (document.createRange)//non IE and no selection
                    {
                        window.getSelection().addRange(savedRange);
                    } else if (document.selection)//IE
                    {
                        savedRange.select();
                    }
                }
            }

不幸的是,它不起作用。目前,光标焦点始终在开头。但它不应该总是在开始时而不是总是在结尾......它应该在用户键入空间的这个位置(在适当的行中)......

任何人都可以帮我解决这个问题,或者使用一个更好的解决方案吗?

非常感谢

V

1 个答案:

答案 0 :(得分:0)

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

placeCaretAtEnd( document.getElementById("content") );

此问题已被提出:contenteditable, set caret at the end of the text (cross-browser)