【发布时间】:2011-04-21 12:13:48
【问题描述】:
我有 HTML 文本区域。我想对其进行修改,使其实现自动缩进,即插入 NEWLINE 后,我想在新行的开头自动插入空格(空格的数量取决于上一行的缩进)。我发现,我可以通过注册一个监听“keypress”事件的处理程序来做到这一点。现在我有一个选择:(a)保留默认处理程序并在浏览器将换行符添加到 textarea.value 之后插入空格,或者(b)使用 preventDefault() 并自己插入整个内容(即换行符和空格)。
在情况 (a) 中,如下面的代码所示,我的处理程序在浏览器添加换行符之前执行,因此空格(或用于说明的“--”)结束在行尾,而不是在新的开始。
在情况(b)中,如下代码中的cmets所示,文本被正确修改,但是如果导致光标离开textarea视图,则内容不会滚动(很可能是因为内容滚动是一部分默认处理),所以光标消失在文本区域边界后面,只有当我发送另一个击键(即不是换行符)时才会重新出现。
如何在不丢失默认滚动的情况下实现自动缩进效果?
我知道这种效果可以通过延迟插入空格来近似(例如使用 setTimeout()),以便运行时有足够的时间来完成默认处理(即插入换行符和垂直滚动),但是对我来说,这似乎是一个巨大的问题,并且引入了一种竞争条件,我担心它会在最意想不到的情况下打击到我(大量复制粘贴、由于其他操作导致运行速度变慢、键盘重复率高等)。理想情况下,我希望 (i) 在默认处理之后调用我的代码,或者 (ii) 能够阻止默认处理、运行我的代码并显式调用默认处理。如何实现?
谢谢!
格雷格
PS:我对集成复杂的 textarea 替换不感兴趣,例如Editarea(我使用了一个,它在浏览器中非常脆弱)。
在 FF3 上测试。
<html>
<head>
<script type="text/javascript">
function onKeyPressHandler(e) {
if (e.which == 13) // ASCII newline
{
var start = this.selectionStart;
var end = this.selectionEnd;
var v = this.value;
this.value = v.slice(0, start) + '--' + v.slice(end); // (a)
// (b): this.value = v.slice(0, start) + '\n--' + v.slice(end);
// (b): e.preventDefault();
}
}
onload = function() {
var editor = document.getElementById("editor");
editor.addEventListener('keypress', onKeyPressHandler, false);
}
</script>
</head>
<body>
<textarea rows="20" cols="80" id="editor"></textarea>
</body>
</html>
【问题讨论】:
标签: javascript textarea indentation