【问题标题】:How do you keep the tab level in a textarea when pressing enter?按下回车键时如何在文本区域中保持标签级别?
【发布时间】:2014-02-11 23:25:56
【问题描述】:

当用户按下回车键时,我希望光标移动到新行,但如果它们当前缩进了两个制表符,那么光标应该保持缩进两个制表符。

我已经实现了忽略选项卡事件来阻止焦点在页面内移动,所以我现在只是在寻找将选项卡级别保持在新行上的逻辑。

if(e.keyCode === 13){

    //Logic here
}

【问题讨论】:

  • 您必须维护一个表单类局部变量来保存当前选项卡级别,然后根据需要将制表符或空格附加到 textarea 文本的末尾以保持该选项卡级别。您还需要挂钩 shift-tab 以便用户可以根据需要降低选项卡级别。

标签: javascript html


【解决方案1】:

http://jsfiddle.net/DVKbn/

$("textarea").keydown(function(e){
    if(e.keyCode == 13){

        // assuming 'this' is textarea

        var cursorPos = this.selectionStart;
        var curentLine = this.value.substr(0, this.selectionStart).split("\n").pop();
        var indent = curentLine.match(/^\s*/)[0];
        var value = this.value;
        var textBefore = value.substring(0,  cursorPos );
        var textAfter  = value.substring( cursorPos, value.length );

        e.preventDefault(); // avoid creating a new line since we do it ourself
        this.value = textBefore + "\n" + indent + textAfter;
        setCaretPosition(this, cursorPos + indent.length + 1); // +1 is for the \n
    }
});

function setCaretPosition(ctrl, pos)
{

    if(ctrl.setSelectionRange)
    {
        ctrl.focus();
        ctrl.setSelectionRange(pos,pos);
    }
    else if (ctrl.createTextRange) {
        var range = ctrl.createTextRange();
        range.collapse(true);
        range.moveEnd('character', pos);
        range.moveStart('character', pos);
        range.select();
    }
}

【讨论】:

【解决方案2】:

我改进了answer by Endless,使用execCommand 'insertText',而不是修改textarea.value

优点:

缺点:

  • Firefox 目前不支持。 (使用 Endless 的解决方案作为后备。)

$('textarea').on('keydown', function(e) {
    if (e.which == 13) { // [ENTER] key
      event.preventDefault()  // We will add newline ourselves.

      var start = this.selectionStart;
      var currentLine = this.value.slice(0, start).split('\n').pop();
      var newlineIndent = '\n' + currentLine.match(/^\s*/)[0];

      if (!document.execCommand('insertText', false, newlineIndent)) {
          // Add fallback for Firefox browser:
          // Modify this.value and update cursor position as per solution by Endless.
      }
    }
  

});
<textarea style="width:99%;height:99px;">        I am indented by 8 spaces.
	I am indented by a tab.</textarea>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

【讨论】:

    【解决方案3】:

    必须说基于一键按键的解决方案是晦涩难懂的,因为人们也喜欢粘贴文本。请改用input 事件。你可以像这样在 jQuery 中制作它:

    $('textarea').on('input', function(e) {
    var el = $(this);
    var cur = $(this).prop('selectionStart'); // retrieve current caret position before setting value
    var text = $(this).val();
    var newText = text.replace(/^(.+)\t+/mg, '$1'); // remove intermediate tabs
    newText = newText.replace(/^([^\t]*)$/mg, '\t\t$1'); // add two tabs in the beginning of each line
    
    if (newText != text) { // If text changed...
    	$(this).val(newText); // finally set value
    	// and reset caret position shifted right by one symbol
    	$(this).prop('selectionStart', cur + 1);
    	$(this).prop('selectionEnd', cur + 1);
    }
    });
    <textarea></textarea>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    顺便说一句,我懒得解释如何查看用户所需的标签计数,这个只是在每一行插入两个标签。

    【讨论】:

      猜你喜欢
      • 2011-04-10
      • 2010-10-21
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      • 2016-07-22
      相关资源
      最近更新 更多