我正在尝试创建一个自动缩进文本区域,到目前为止它可以使用以下代码。我遇到的问题是我目前正在阻止按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;
修改 作为更新,为了消除任何混淆,我正在尝试创建一个IDE样式的文本框,例如在大多数IDE中,如果键入以下内容
function example(whatever) {
Example Stuff // And then hit enter here
我希望它能够将您带到左边框的相同标签距离作为“示例资料”,以便让您的代码更易于阅读。我目前有这个功能,但问题是我正在拦截回车键,这意味着我必须提供该功能。我很难复制不滚动文本框的确切功能,直到光标到达底部边框。因此,如果你要在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);
答案 0 :(得分:2)
我想拥有textarea的默认动作
如何绑定到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)
答案 1 :(得分:1)
你有没有注意到Stack Overflow textareas如何处理代码?如果输入:
function example(whatever) {
Example Stuff // And then hit enter here
}
起初,什么都不会发生。然后,当您缩进(通过键入或单击101010按钮)时,它会在代码上添加不同的背景。 然后,等了一会儿之后,语法为代码着色。但如果你再次开始打字,它会回到黑/白。
我认为类似的方法可能对您有用。你应该做的是:
,而不是试图将所有内容与enter keypress事件联系起来连接正常的onKeySomething事件,但不要只查找“enter”;每次按键后:
1A。将一些全局变量(例如,计时器)设置为新的Date();
1B。 setTimeout(X,timeoutFunction)其中X在用户停止输入后要等待很长时间
创建timeoutFunction;此函数应检查全局“计时器”变量,如果是新的Date() - 计时器&gt; X触发actualFunction()
actualFunction可以解析textarea的内容,缩进你喜欢的东西,没有任何东西可以打断用户的正常流程
我知道这不是“真正的”IDE的表现,但考虑到JS和网络的局限性,它可能是最好的方法。
答案 2 :(得分:0)
如何对文本框进行子类化并手动处理WndProc?这样可以获得更细粒度的控制,并且可以解决键控键重复(KeyPress和类似事件只有在按住键时才会触发)。
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);
}
}
}
答案 3 :(得分:0)
我知道这不是一个直接的答案,但是你可以在网上看到一些可以帮助你实现这个的例子。
http://jsfiddle.net
http://teddevito.com/demos/textarea.html
http://thelackthereof.org/JQuery_Autoindent
如果我有更多时间,我肯定会试一试,但遗憾的是我没有。