【问题标题】:Need better SQL syntax highlighter using contenteditable div使用 contenteditable div 需要更好的 SQL 语法高亮
【发布时间】:2017-05-25 09:57:14
【问题描述】:

我知道类似的问题以类似的方式被问过很多次,但鉴于我对此感到满意......

目标: 我想要一个类似textarea(div contenteditable)的东西,用户可以在其中输入一些SQL。当用户输入 SQL 时,一些流行词如“SELECT”、“FROM”.... 应该被着色。但是解决方案应该是流畅的,不会丢失光标位置并接受新行。如果后记正确的话应该可以改变颜色。

我尝试过的解决方案:

方式一Change color of specific words in textarea

我尝试将每个单词都包装起来并放置一个 span arround,就像链接中的示例一样。 问题:

  • 新行将被删除
  • 无法添加包含文本后缀的空格
  • 光标总是在末尾​​li>

方式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

【问题讨论】:

  • 嘿,大家,我没有针对特定问题的解决方案,但我找到了一个比每个自己的开发变体更好的解决方案...... post 链接到 codemirror 是比我的建议更好... 这里是 SQL 解决方案link

标签: javascript jquery contenteditable


【解决方案1】:
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)

【讨论】:

  • 嘿,你的第一个问题可以解决,如果你改变你的行“var regex = new RegExp(search);”到“var regex = new RegExp(search, 'g');”像我的例子。第二个问题和我的一样……
  • 完成,光标移动到末尾
  • 是的,但这不是 100% 的解决方案。光标应该在用户正在输入的那一刻......在开头,光标总是在结尾。但是,如果用户想更正一些书面文本,他在中间,光标应该留在那里,而不是在每个空格处移动到末尾......但我没有让它运行:/
猜你喜欢
  • 2013-08-01
  • 1970-01-01
  • 2019-11-05
  • 1970-01-01
  • 2023-04-08
  • 2013-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多