Javascript在textarea中的括号之间移动文本

时间:2015-11-17 20:36:23

标签: javascript jquery regex

我有一个简单的文本区域,文字如下:

Lorem Ipsum [text] dolar, rock n'[more] roller.

我正在尝试检测光标在括号之间的时间,如果是这样,允许按Ctrl +向右或向左箭头将文本和括号向右或向左移动一个位置,每按一次按键,而不会超过开始或结束线,没有移过相邻的括号块。我猜这与将右侧第一个字符(或空格)复制到左侧的Ctrl +右箭头相同,反之亦然。

我有一些基本的jquery技能,但我对此的所有尝试都失败了。否则,我会粘贴一段显示我所拥有的代码。谢谢,

3 个答案:

答案 0 :(得分:3)

解决方案需要几个不同的部分:

查找光标位置:

foreach (var row in rssDocument.SelectNodes("teryt/catalog/row"))
{    
    foreach (var col in row.SelectNodes("col"))
    {             
        Console.WriteLine(col.InnerText);    
    }
}

找到字符串的位置(查看插入符号是否在其中)。您可以使用正则表达式,如:

function getCaretPosition(element)
{
    var CaretPos = 0;

    //Old IE way
    if ( document.selection )
    {
        element.focus();
        var textSelection = document.selection.createRange();
        textSelection.moveStart( 'character', -element.value.length );
        CaretPos = textSelection.text.length;
    }

    //DOM way
    else if ( element.selectionStart || element.selectionStart == '0' )
        CaretPos = element.selectionStart;

    return (CaretPos);
}

您还需要在textarea和该事件监听器中收听按键事件:

  1. 如果它是左箭头或右箭头(按住ctrl按钮),则:
  2. 找到插入位置,看看它是否在支架文本中,如果是这样的话:
  3. 向左或向右移动文本(您可以在括号内的文本之前/之后获取文本的子字符串并创建新的连接字符串)
  4. 这些作品应该使这项工作。 (我不打算为你写,因为那对你没有帮助)

答案 1 :(得分:0)

这是fiddle执行此操作,以下是代码:

$('textarea').on('keydown', function(e) {
    // Is Ctrl-left and Ctrl+right pressed?
    if (e.ctrlKey && (e.which === 37 || e.which === 39)) {
        var pos = this.selectionStart;
        var val = this.value;
        var openBracketOnLeft = val.substr(0, pos).lastIndexOf('[');
        var closeBracketOnLeft = val.substr(0, pos).lastIndexOf(']');
        var closeBracketOnRight = val.substr(pos).indexOf(']');
        // Is start of selection within two brackets?
        if (openBracketOnLeft > closeBracketOnLeft && closeBracketOnRight !== -1) {
            closeBracketOnRight += pos + 1;
            var tagText = val.substr(openBracketOnLeft, closeBracketOnRight - openBracketOnLeft);
            var level = 0;
            // Repeat moving the tag until we do not break another tag in two.
            do {
                // Is Ctrl-left pressed, and is tag not yet on far left?
                if (e.which === 37 && openBracketOnLeft) {
                    ch = val.substr(openBracketOnLeft - 1, 1);
                    val = val.substr(0, openBracketOnLeft - 1)
                        + tagText
                        + ch 
                        + val.substr(closeBracketOnRight);
                    openBracketOnLeft--;
                    closeBracketOnRight--;
                // Is Ctrl-right pressed, and is tag not yet on far right?
                } else if (e.which === 39 && closeBracketOnRight < val.length) {
                    ch = val.substr(closeBracketOnRight, 1);
                    val = val.substr(0, openBracketOnLeft) 
                        + ch 
                        + tagText 
                        + val.substr(closeBracketOnRight + 1);
                    openBracketOnLeft++;
                    closeBracketOnRight++;
                } else {
                    break;
                }
                level += ch == '[' ? 1 : ch == ']' ? -1 : 0;
            } while (level);
            // Select the tag, without the brackets
            this.value = val;
            this.selectionStart = openBracketOnLeft + 1;
            this.selectionEnd = closeBracketOnRight - 1;
            e.preventDefault();
        }
    };
});

答案 2 :(得分:0)

这是一种没有邪恶的正则表达式字符串的方法。相反,我想尝试使用jQuery&#39; keydown&#39;与提问者提到的内容一致的事件(参见:jQuery中的newb)。还要注意&#39; keydown&#39;对于这种方法更好,因为关键词&#39;会发射多次,不过我想这也会发生......不管怎样,这就是我想出的:

$('#inputFieldInQuestion').on('keydown', function (event) {
    // if both the control key and left key are pushed
    if (event.keyCode == 37 && event.ctrlKey) {
        // grab the text from the input and caret position in the input box
        var inputBoxText = $(this).val(),
            currentCaretPosition = this.selectionStart
        // loop through all the characters in the input box text
        for (var i = 0; i < inputBoxText.length; i++) {
            // if the current character is an open bracket start testing for the end
            if (inputBoxText[i] === "[") {
                for (var j = i + 1; j < inputBoxText.length; j++) { 
                    // this means that there is another bracketed string in between the 
                    // beginning and the current bracketed string
                    if (inputBoxText[j] === "[") { break }
                    // if instead we come to the end of the bracketed string will determine
                    // if the bounds make sense
                    else if (inputBoxText[j] === "]") {
                        // if the caret position is in the bounds that you have just created
                        // we continue the shift
                        if (currentCaretPosition > i && currentCaretPosition < j) {
                            // test as per the question if the bracketed string is adjascent
                            // to another bracketed string
                            if (inputBoxText[i - 1] !== "]") {
                                // if the bracketed text is all the way to the left of the 
                                // input box
                                if (i > 0) {
                                    // slice and dice the string and move things left by one 
                                    // character
                                    var frontString = inputBoxText.substring(0, i),
                                        stringToMove = inputBoxText.substring(i, j + 1),
                                        endString = inputBoxText.substring(j + 1)
                                    $(this).val(frontString.slice(0, i - 1) + stringToMove + frontString.slice(i - 1) + endString)
                                    this.setSelectionRange(currentCaretPosition - 1, currentCaretPosition - 1); break
                                }
                            }
                            else { break }
                        }
                    }
                }
            }
        }
        // important so that the ctrl-left doesn't shift the cursor to the end of the word
        return false;
    }
    // if both the control key and right key are pushed
    else if (event.keyCode == 39 && event.ctrlKey) {
        var inputBoxText = $(this).val(),
            currentCaretPosition = this.selectionStart
        for (var i = 0; i < inputBoxText.length; i++) {
            if (inputBoxText[i] === "[") {
                for (var j = i; j < inputBoxText.length; j++) {
                    if (inputBoxText[j] === "]") {
                        if (currentCaretPosition > i && currentCaretPosition < j) {
                            // test as per the question if the bracketed string is adjascent
                            // to another bracketed string
                            if (inputBoxText[j + 1] !== "[") {
                                // bracketed text is all the way to the right of the input box
                                if (inputBoxText.length - j > 1) {
                                    var frontString = inputBoxText.substring(0, i),
                                        stringToMove = inputBoxText.substring(i, j + 1),
                                        endString = inputBoxText.substring(j + 1)
                                    $(this).val(frontString + endString.slice(0, 1) + stringToMove + endString.slice(1))
                                    this.setSelectionRange(currentCaretPosition + 1, currentCaretPosition + 1); break
                                }
                            }
                            else { break }
                        }
                    }
                }
            }
        }
        return false;
    }
})

这可能是执行此操作最复杂的方法,但它确实起作用并且满足所提出的所有约束。由于我刚刚注意到这是标记的正则表达式,这可能是一个可怕的解决方案。让掏膛开始!

超级奖励:如果您有任何数量的&#34; []&#34;字符串中的对。