Php &引用;“聪明的”;文本区域自动缩进
我正在尝试制作一个自动缩进文本区域,到目前为止,它可以使用以下代码。我遇到的问题是,我目前正在阻止按enter键以计算行中的制表符,然后插入换行符的默认操作 这是可行的,但我希望有textarea的默认操作,如果按住enter键,它不会滚动textarea,直到插入符号到达最下面一行,然后滚动条保持插入符号在最下面一行。如果在文本区域的任何地方使用插入符号,下面的当前代码将使其保持在视野范围内,但它会导致插入符号上方的内容向上滚动,这是一种折衷,因为插入符号不再消失。如果没有其他解决方案,这将很好,但我希望有其他想法Php &引用;“聪明的”;文本区域自动缩进,php,javascript,jquery,Php,Javascript,Jquery,我正在尝试制作一个自动缩进文本区域,到目前为止,它可以使用以下代码。我遇到的问题是,我目前正在阻止按enter键以计算行中的制表符,然后插入换行符的默认操作 这是可行的,但我希望有textarea的默认操作,如果按住enter键,它不会滚动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;
我希望它将您带到与“示例内容”相同的标签距离,以使您的代码更易于阅读。我目前拥有该功能,但问题是我正在拦截enter键,这意味着我必须提供该功能。我很难复制在光标到达底部边框之前不滚动文本框的确切功能。因此,如果您在textarea的顶部按住enter键,光标只会向下滚动textarea,移动任何文本,直到它到达底部边框,然后textarea的滚动条将跟随光标。有道理吗
编辑2更新的标记,以指示代码与PHP兼容
我一直在做这个,而这个职位一直坐着。我想,当我有机会时,我将探索的另一个选项是,不阻止enter,只允许默认的操作,即点击enter,并读取字符串,从lastIndexOf('\n')-1
到任何\t
的最新\n
。我想这会给我想要的字符串,但不会搞乱textarea的行为。将在测试后再次更新
编辑3已解决,根据我以前的更新,我决定在按下键后扫描字符串,保留自然行为(下面为感兴趣的人添加了更改的部分),唯一剩下的问题是,如果按住enter键,它将不会从enter键的原点计算缩进,这对我来说很好。我要把这个给你http://stackoverflow.com/users/15066/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);
您是否注意到堆栈溢出文本区域如何处理代码?如果键入:
function example(whatever) {
Example Stuff // And then hit enter here
}
起初,什么也不会发生。然后,当您缩进(通过键入或单击101010按钮)时,它会在代码上放置不同的背景。然后,在您等待片刻之后,它会对代码进行语法着色。但是如果你再开始打字,它会回到黑/白状态
我认为类似的方法可能适合你。与其尝试将所有内容都绑定到enter keypress事件,您应该做的是:
我知道这不是“真实”IDE的行为方式,但考虑到JS和web的局限性,这可能是最好的方法。对文本框进行子类化并手动处理WndProc如何?这将使您获得更细粒度的控制,并将处理typematic键重复(按键和类似事件仅在按住键时触发一次)
公共类MyTextBox:System.Windows.Forms.TextBox
{
受保护的覆盖无效WndProc(参考消息m)
{
//让O/S先处理键
基准WndProc(参考m);
//然后,如果是返回键,则添加选项卡
int numTabs=3;//TODO:在此处插入您自己的值
常量int WM_CHAR=0x0102;
如果(m.Msg==WM_CHAR&&(CHAR)m.WParam=='\r')
{
m、 WParam=new IntPtr('\t');//回收m,因为base已经使用它了
对于(int i=0;i
我想要文本区域的默认操作
如何绑定到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)
自动缩进示例
document.getElementById('TA')。addEventListener('keyup',函数(v){
if(v.keyCode!=13 | | v.shiftKey | | v.ctrlKey | | v.altKey | v.metaKey)
返回;
var val=this.value,pos=this.selectionStart;
变量行=val.slice(val.lastIndexOf('\n',位置-2)+1,位置-1);
var indent=/^\s*/.exec(行)[0];
如果(!缩进)返回;
var st=this.scrollTop;
this.value=val.slice(0,pos)+缩进+val.slice(this.selectionEnd);
this.selectionStart=this.selectionEnd=pos+indent.length;
this.scrollTop=st;
},假);
(此处不考虑IE)
我知道这不是一个直截了当的答案,但网上有一些例子可以帮助你实现这一点
如果我有更多的时间,我肯定会尝试一下,但不幸的是我没有。该项目的目的是能够直接在文本区域中编码,并在用户完成后清理代码。澄清,*而不是
public class MyTextBox : System.Windows.Forms.TextBox
{
protected override void WndProc(ref Message m)
{
// Let the O/S handle the key first
base.WndProc(ref m);
// Then, if it's the return key, append tabs
int numTabs = 3; // TODO: insert your own value here
const int WM_CHAR = 0x0102;
if(m.Msg == WM_CHAR && (char)m.WParam == '\r')
{
m.WParam = new IntPtr('\t'); // Recycle m since base is done with it
for (int i = 0; i < numTabs; i++)
WndProc(ref m);
}
}
}
<!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)