"智能"文本区域自动缩进

Rob*_*ert 5 javascript php jquery

我正在尝试创建一个自动缩进文本区域,到目前为止它使用以下代码.我遇到的问题是我目前正在阻止按Enter键的默认操作,以便计算行中的选项卡,然后插入换行符.

这有效,但我希望得到textarea的默认动作,因为如果按住enter键,它不会滚动textarea直到插入符号触及底行,然后滚动条在底行保留插入符号.如果在textarea的任何地方使用,下面的当前代码将插入符号保持在视野中,但它会使插入符号上方的内容向上滚动,这是一种折衷,因为插入符号不再消失.如果没有其他解决方案,这将工作正常,但我希望还有其他想法.

    var start = this.selectionStart-1;
    var end = this.selectionEnd;
    var sT = this.scrollTop;
    var sH = this.scrollHeight;
    var vH = $(this).height();

    var x = (sH - sT) - vH;

    // Check if hitting enter on the first line as no newline will be found
    if (this.value.lastIndexOf('\n',start)==-1)
     var startSubstr = 0;
    else 
     var startSubstr = this.value.lastIndexOf('\n',start)+1;

    var endFirst = end - startSubstr;

    var valueToScan = this.value.substr(startSubstr,endFirst);
    var count = 0;

    // Count only \t at the beginning of the line, none in the code   
    while (valueToScan.indexOf('\t')!=-1) {
     if (valueToScan.indexOf('\t')!=0)
      break;
     count++;
     valueToScan = valueToScan.substr(valueToScan.indexOf('\t')+1);
    }

    // Command to isert the newline, and then add the \t's found in previously  
    $(this).insertAtCaret('\n');
    for (var i=0;i<count;count--) {
     $(this).insertAtCaret('\t');
    }  

    var sH = this.scrollHeight;
    this.scrollTop = (sH - x) - vH;
Run Code Online (Sandbox Code Playgroud)

编辑 作为更新,为了消除任何混淆,我正在尝试创建一个IDE样式的文本框,例如在大多数IDE中,如果您键入以下内容

function example(whatever) {
     Example Stuff // And then hit enter here
Run Code Online (Sandbox Code Playgroud)

我希望它能够将您带到左边框的相同选项卡距离作为"Example Stuff",以便让您的代码更易于阅读.我目前有这个功能,但问题是我正在拦截回车键,这意味着我必须提供该功能.我很难复制不滚动文本框的确切功能,直到光标到达底部边框.因此,如果你要在textarea的顶部按住enter键,光标只会向下滚动textarea,用它移动任何文本直到它到达底部边框,然后textarea的滚动条将跟随光标.合理?

编辑2 更新了标签,表明代码是用PHP

这篇文章一直坐着,我一直在努力.我认为,当我有机会时,我将要探索的另一个选择是阻止输入,只允许输入命令的默认操作,并将字符串读取lastIndexOf('\n')-1到最近\n的任何字符串\t.我想这会给我一些我正在寻找的字符串,但不会弄乱textarea的行为.测试后会再次更新.

编辑3已解决,根据我之前的更新,我决定在按下按键后扫描字符串,保留自然行为(下面为感兴趣的人添加了更改的部分),唯一的问题是,如果你按住回车,它赢了不计算输入印刷机原点的缩进,这对我来说很好.我打算把这个给http://stackoverflow.com/users/15066/matyr'>matyr,虽然我在他回答之前确实弄清楚他仍然是最接近的.

if (this.value.lastIndexOf('\n',start-2)==-1) {
 var startSubstr = 0;
} else {
 var startSubstr = this.value.lastIndexOf('\n',start-1)+1;
}    
var valueToScan = this.value.substr(startSubstr,start);
Run Code Online (Sandbox Code Playgroud)

mat*_*tyr 2

我想要文本区域的默认操作

keyup绑定到而不是keydown/keypress并在本机换行符后插入制表符怎么样?

滚动条与插入符一起位于底行

您可以通过恢复来保留滚动位置scrollTop

<!DOCTYPE html>
<title>autoindent example</title>
<textarea id="TA" rows="8"></textarea>
<script>
document.getElementById('TA').addEventListener('keyup', function(v){
  if(v.keyCode != 13 || v.shiftKey || v.ctrlKey || v.altKey || v.metaKey)
    return;
  var val = this.value, pos = this.selectionStart;
  var line = val.slice(val.lastIndexOf('\n', pos - 2) + 1, pos - 1);
  var indent = /^\s*/.exec(line)[0];
  if(!indent) return;
  var st = this.scrollTop;
  this.value = val.slice(0, pos) + indent + val.slice(this.selectionEnd);
  this.selectionStart = this.selectionEnd = pos + indent.length;
  this.scrollTop = st;
}, false);
</script>
<p>(not considering IE here)
Run Code Online (Sandbox Code Playgroud)