我想要一个处理按Tab键情况的 textarea 。
默认情况下,如果您按Tab键,则焦点会离开 textarea。但是当用户想在 textarea 中输入tab键的情况下呢?
我可以捕获此事件并将焦点返回到 textarea 并将选项卡添加到当前光标位置吗?
我想要一个处理按Tab键情况的 textarea 。
默认情况下,如果您按Tab键,则焦点会离开 textarea。但是当用户想在 textarea 中输入tab键的情况下呢?
我可以捕获此事件并将焦点返回到 textarea 并将选项卡添加到当前光标位置吗?
您可以:http : //jsfiddle.net/sdDVf/8/。
$("textarea").keydown(function(e) {
    if(e.keyCode === 9) { // tab was pressed
        // get caret position/selection
        var start = this.selectionStart;
        var end = this.selectionEnd;
        var $this = $(this);
        var value = $this.val();
        // set textarea value to: text before caret + tab + text after caret
        $this.val(value.substring(0, start)
                    + "\t"
                    + value.substring(end));
        // put caret at right position again (add one for the tab)
        this.selectionStart = this.selectionEnd = start + 1;
        // prevent the focus lose
        e.preventDefault();
    }
});
这是不需要 JQuery 的 pimvdb 答案的修改版本:
document.querySelector("textarea").addEventListener('keydown',function(e) {
    if(e.keyCode === 9) { // tab was pressed
        // get caret position/selection
        var start = this.selectionStart;
        var end = this.selectionEnd;
        var target = e.target;
        var value = target.value;
        // set textarea value to: text before caret + tab + text after caret
        target.value = value.substring(0, start)
                    + "\t"
                    + value.substring(end);
        // put caret at right position again (add one for the tab)
        this.selectionStart = this.selectionEnd = start + 1;
        // prevent the focus lose
        e.preventDefault();
    }
},false);
我在 Firefox 21.0 和 Chrome 27 上测试过。不知道它是否适用于其他任何地方。
天哪,以前的所有答案都未能提供通常体面的(即对于程序员)选项卡控件。
也就是说,点击TAB选择的行将缩进这些行,并SHIFTTAB取消它们的缩进。
_edited(2016 年 11 月):keyCode 替换为 charCode || keyCode,每个KeyboardEvent.charCode - Web APIs | MDN
(function($) {
  $.fn.enableSmartTab = function() {
    var $this;
    $this = $(this);
    $this.keydown(function(e) {
      var after, before, end, lastNewLine, changeLength, re, replace, selection, start, val;
      if ((e.charCode === 9 || e.keyCode === 9) && !e.altKey && !e.ctrlKey && !e.metaKey) {
        e.preventDefault();
        start = this.selectionStart;
        end = this.selectionEnd;
        val = $this.val();
        before = val.substring(0, start);
        after = val.substring(end);
        replace = true;
        if (start !== end) {
          selection = val.substring(start, end);
          if (~selection.indexOf('\n')) {
            replace = false;
            changeLength = 0;
            lastNewLine = before.lastIndexOf('\n');
            if (!~lastNewLine) {
              selection = before + selection;
              changeLength = before.length;
              before = '';
            } else {
              selection = before.substring(lastNewLine) + selection;
              changeLength = before.length - lastNewLine;
              before = before.substring(0, lastNewLine);
            }
            if (e.shiftKey) {
              re = /(\n|^)(\t|[ ]{1,8})/g;
              if (selection.match(re)) {
                start--;
                changeLength--;
              }
              selection = selection.replace(re, '$1');
            } else {
              selection = selection.replace(/(\n|^)/g, '$1\t');
              start++;
              changeLength++;
            }
            $this.val(before + selection + after);
            this.selectionStart = start;
            this.selectionEnd = start + selection.length - changeLength;
          }
        }
        if (replace && !e.shiftKey) {
          $this.val(before + '\t' + after);
          this.selectionStart = this.selectionEnd = start + 1;
        }
      }
    });
  };
})(jQuery);
$(function() {
  $("textarea").enableSmartTab();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea rows="10" cols="80">
/* Just some code to edit with our new superTab */
(function($) {
    $.fn.enableSmartTab = function() {
        $this = $(this);
        $this.keydown(function(e) {
            if ((e.charCode === 9 || e.keyCode === 9) && !e.metaKey && !e.ctrlKey && !e.altKey) {
                e.preventDefault();
            }
        }
    }
}
</textarea>
在香草(默认)JS 中,这将是:
var textareas = document.getElementsByTagName('textarea');
if ( textareas ) {
  for ( var i = 0; i < textareas.length; i++ ) {
textareas[i].addEventListener( 'keydown', function ( e ) {
  if ( e.which != 9 ) return;
  var start             = this.selectionStart;
  var end                 = this.selectionEnd;
  this.value            = this.value.substr( 0, start ) + "\t" + this.value.substr( end );
  this.selectionStart = this.selectionEnd = start + 1;
  e.preventDefault();
  return false;
});
  }
}
textarea {
   border: 1px solid #cfcfcf;
   width: 100%;
   margin-left: 0px;
   top: 0px;
   bottom: 0px;
   position: absolute;
}
<textarea>
var x = 10;
var y = 10;
</textarea>
在(多个)textarea 元素内启用制表符
更正@alexwells 答案并启用现场演示
var textAreaArray = document.querySelectorAll("textarea");
    for (var i = textAreaArray.length-1; i >=0;i--){
        textAreaArray[i].addEventListener('keydown',function(e) {
            if(e.keyCode === 9) { // tab was pressed
                // get caret position/selection
                var start = this.selectionStart;
                var end = this.selectionEnd;
                var target = e.target;
                var value = target.value;
                // set textarea value to: text before caret + tab + text after caret
                target.value = value.substring(0, start)
                            + "\t"
                            + value.substring(end);
                // put caret at right position again (add one for the tab)
                this.selectionStart = this.selectionEnd = start + 1;
                // prevent the focus lose
                e.preventDefault();
            }
        },false);
    }
<textarea rows="10" cols="80"></textarea>
   <textarea rows="10" cols="80"></textarea>