将JQuery代码转换为Vanilla JavaScript

时间:2020-09-24 19:48:11

标签: javascript jquery

我有以下JQuery代码,它们为可编辑html文本中输入的SQL语句着色: enter image description here

// SQL keywords
    var keywords = ["SELECT","FROM","WHERE","LIKE","BETWEEN", "UNION",
    "FALSE","NULL","FROM","TRUE","NOT", "ORDER", "GROUP", "BY", "NOT", "IN"];
    // Keyup event
    $("#editor").on("keyup", function(e){
    // Space key pressed
    if (e.keyCode == 32){
        var newHTML = "";
        // Loop through words
        $(this).text().replace(/[\s]+/g, " ").trim().split(" ").forEach(function(val){
        // If word is statement
        if (keywords.indexOf(val.trim().toUpperCase()) > -1)
            newHTML += "<span class='statement'>" + val + "&nbsp;</span>";
        else
            newHTML += "<span class='other'>" + val + "&nbsp;</span>"; 
        });
        $(this).html(newHTML);

        // Set cursor postion to end of text
        var child = $(this).children();
        var range = document.createRange();
        var sel = window.getSelection();
        range.setStart(child[child.length-1], 1);
        range.collapse(true);
        sel.removeAllRanges();
        sel.addRange(range);
        this.focus();
        }
    });
        #editor {
            width: 400px;
            height: 100px;
            padding: 10px;
            background-color: #444;
            color: white;
            font-size: 14px;
            font-family: monospace;
        }
        .statement {
            color: orange;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="editor" contenteditable="true"></div>

我试图做到如下:但是失败了:

    // SQL keywords
    var keywords = ["SELECT","FROM","WHERE","LIKE","BETWEEN", "UNION",
    "FALSE","NULL","FROM","TRUE","NOT", "ORDER", "GROUP", "BY", "NOT", "IN"];
    // Keyup event
    document.querySelector('#editor').addEventListener('keyup', e => {
    // Space key pressed
    if (e.keyCode == 32){
        var newHTML = "";
        // Loop through words
        str = e.target.innerHTML
        str.replace(/[\s]+/g, " ").trim().split(" ").forEach(val => {
        // If word is statement
        if (keywords.indexOf(val.trim().toUpperCase()) > -1)
            newHTML += "<span class='statement'>" + val + "&nbsp;</span>";
        else
            newHTML += "<span class='other'>" + val + "&nbsp;</span>"; 
        });
        e.target.innerHTML = newHTML;

        // Set cursor postion to end of text

        var el =  e.target; 
        el.focus()
        if (typeof el.selectionStart == "number") {
            el.selectionStart = el.selectionEnd = el.value.length;
        } else if (typeof el.createTextRange != "undefined") {           
            var range = el.createTextRange();
            range.collapse(false);
            range.select();
        }
    }
    });
       #editor {
            width: 400px;
            height: 100px;
            padding: 10px;
            background-color: #444;
            color: white;
            font-size: 14px;
            font-family: monospace;
        }
        .statement {
            color: orange;
        }
<div id="editor" contenteditable="true"></div>

我认为我的错误是我尝试实现this

时将光标返回到文本字段的末尾

2 个答案:

答案 0 :(得分:0)

这是我的答案。

// SQL keywords
var keywords = ["SELECT", "FROM", "WHERE", "LIKE", "BETWEEN", "UNION", "FALSE", "NULL", "FROM", "TRUE", "NOT", "ORDER", "GROUP", "BY", "NOT", "IN"];
// Keyup event
document.querySelector('#editor').addEventListener('keyup', e => {
    // Space key pressed
    if (e.keyCode == 32) {
        var newHTML = "";
        // Loop through words
        str = e.target.innerText;
        str.replace(/[\s]+/g, " ").trim().split(" ").forEach(val => {
            // If word is statement
            if (keywords.indexOf(val.trim().toUpperCase()) > -1)
                newHTML += "<span class='statement'>" + val + "&nbsp;</span>";
            else
                newHTML += "<span class='other'>" + val + "&nbsp;</span>";
        });
        console.log(newHTML);
        e.target.innerHTML = newHTML;

        // Set cursor postion to end of text
        //    document.querySelector('#editor').focus()
        var child = e.target.children;
        var range = document.createRange();
        var sel = window.getSelection();
        range.setStart(child[child.length - 1], 1);
        range.collapse(true);
        sel.removeAllRanges();
        sel.addRange(range);
        this.focus();
            
    }
});
#editor {
    width: 400px;
    height: 100px;
    padding: 10px;
    background-color: #444;
    color: white;
    font-size: 14px;
    font-family: monospace;
}
.statement {
    color: orange;
}
<div id="editor" contenteditable="true"></div>

我用过

var child = e.target.children;
var range = document.createRange();
var sel = window.getSelection();
range.setStart(child[child.length - 1], 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
this.focus();

代替

var el = e.target;
el.focus()
if (typeof el.selectionStart == "number") {
    el.selectionStart = el.selectionEnd = el.value.length;
} else if (typeof el.createTextRange != "undefined") {
    var range = el.createTextRange();
    range.collapse(false);
    range.select();
}

答案 1 :(得分:0)

基于两个答案,一个被接受的答案,以及从@Yevgen删除的one,我更喜欢下面的代码,@Yevgen功能方法很好地处理了“分组依据”,而另一种方法则不是:

    // SQL keywords
    var keywords = ["SELECT", "FROM", "WHERE", "LIKE", "BETWEEN", "UNION", "FALSE", "NULL", "FROM", "TRUE", "NOT", "ORDER", "GROUP BY", "NOT", "IN"];
    // Keyup event
    document.querySelector('#editor').addEventListener('keyup', e => {
    // Space key pressed
    if (e.keyCode == 32) {
        var newHTML = "";
        // Loop through words
        str = e.target.innerText;
        chunks = str
          .split(RegExp(keywords.map(w => `(${w})`).join('|'), 'i'))
          .filter(Boolean)
        markup = chunks.reduce((acc, chunk) => {
          acc += keywords.includes(chunk.toUpperCase()) ?
          `<span class="statement">${chunk}</span>` :
          `<span class='other'>${chunk}</span>`
          return acc
        }, '')      
        e.target.innerHTML = markup;

        // Set cursor postion to end of text
        var child = e.target.children;
// Create the new range object. 
        var range = document.createRange();
// Here 'sel' is created object for window 
        var sel = window.getSelection();
// Setting start position of a Range 
        range.setStart(child[child.length - 1], 1);
// Collapses the Range to one of its 
        range.collapse(true);
// Remove all old range 
        sel.removeAllRanges();
// Add new range
        sel.addRange(range);
// Focus the element 
        this.focus();
            
        }
    });
        #editor {
            width: 400px;
            height: 100px;
            padding: 10px;
            background-color: #444;
            color: white;
            font-size: 14px;
            font-family: monospace;
        }
        .statement {
            color: orange;
        }
<div id="editor" contenteditable="true"></div>