Javascript 从文本区域删除顶行的最简洁(快速)的方法

Javascript 从文本区域删除顶行的最简洁(快速)的方法,javascript,jquery,textarea,Javascript,Jquery,Textarea,我有一个网页,显示日志文件最后的1000行,然后每隔x秒通过AJAX更新一次,加载新内容(如果有的话)并用$('#log')追加到文本区。追加(新的_数据),一种尾部-f 一段时间后,当附加的行太多,页面变得缓慢或无响应时,问题就会出现 所以我想把行数限制在5000行,这意味着我应该: 检索新数据 计算overflow=5000-新数据中的行数\u-文本区域中的行数 如果overflow>0从文本区域删除第一行overflow行 将新的_数据附加到textarea 在我看来,这涉及到一个或多

我有一个网页,显示日志文件最后的
1000行
,然后每隔
x
秒通过AJAX更新一次,加载新内容(如果有的话)并用
$('#log')追加到文本区。追加(新的_数据)
,一种
尾部-f

一段时间后,当附加的行太多,页面变得缓慢或无响应时,问题就会出现

所以我想把行数限制在5000行,这意味着我应该:

  • 检索
    新数据
  • 计算
    overflow=5000-新数据中的行数\u-文本区域中的行数
  • 如果
    overflow>0
    从文本区域删除第一行
    overflow
  • 将新的_数据附加到textarea

在我看来,这涉及到一个或多个
拆分('\n')
textarea
new\u data
值,然后使用数组长度和切片,但我猜是否有更简洁或更好的方法来实现这一点。

您应该能够使用单个
拆分
,然后在截断数据后加入
,大概是这样的:

// on data retrieved
var total = ((textarea.value 
              ? textarea.value + "\n" 
              : "") 
          + new_data).split("\n");

if (total.length > 10) 
    total = total.slice(total.length - 10);

textarea.value = total.join("\n");
工作示例:(为了简洁起见,请缩短到10行)

类似的内容(下面链接的演示可能更有用):

HTML
更多行

行数:0

JavaScript
var$log=$('#log'),
$按钮=$(“#单击我”),
$numLines=$(“#numLines”),
最大线数=5000,
lorem_ipsum=‘lorem ipsum Door sit amet,Concertetur adipiscing Elite’,
lineCounter=0;
$按钮。单击(函数()
{
$log.val($log.val()+generateMoreLines()).change();
});
$log.change(函数()
{
var text=tail(最大行数,$log.val());
$log.val(文本);
$numLines.text(countNewlines(text));
});
功能生成emorelines()
{
var buf=[];
对于(变量i=0;i<1000;i++)
{
buf.push(lineCounter+++lorem_ipsum);
}
返回buf.join('\n');
}
函数countNewlines(haystack)
{
返回计数('\n',haystack);
}
功能计数(针、干草堆)
{
var num=0,
len=干草堆长度;
对于(变量i=0;i限制)
{
还田草垛
.split(“\n”)
.slice(-limit)
.join('\n');
}
返回草垛;
}
换行符处理不是完美的(是否计算所有出现的
'\n'
?如果字符串以
'\n'
等开头或结尾会怎样)


演示:

textarea实际上并不将
'\n'
显示为换行符。文本区域是否可以调整大小?如果限制字符数而不是行数,则会简单得多。请投票选择使用字符长度而不是行数。我知道这会简单得多,但我希望尽可能以基于linuxish行的方式使页面正常工作。这毕竟是一个日志。。。即使有一些解决方法可以很容易地避免这种情况,但如果第一行textarea被截断,那将是非常难看的…@Matt:不,它不可调整大小,只是一个普通的textarea 80cols x 24row如果textarea被限制为80列,那么当一个日志行包含80个以上的字符时会发生什么?它是否环绕到下一行,或溢出宽度?如果要删除多余的行,是否将多余的字符作为一行的一部分进行计数?顺便说一句,有些浏览器会允许使用句柄调整任何textarea的大小,除非您这样做。+1,我绝对喜欢您使用时间戳的策略,这样可以很容易地看到滑动窗口。您可能需要更改
textarea.value=total.join(“\n”)
textarea.val(total.join(“\n”)
以使用jQuery运行代码。@neurino:是的,可以,但我更喜欢直接映射到DOM属性,而不是使用jQuery的访问器方法。它的效率稍微高一些:-)它应该是
textarea[0]。如果
textarea
是一个jQuery对象,那么它的值就是
。因为内容来自日志文件,所以字符串总是在没有
\n
的情况下开始和结束(我第一次使用调用
tail-n 1000
获取内容,然后记住文件位置并在后续调用中使用
seek
)。
<button id="clickme">More lines</button>
<br/>
<textarea id="log" rows="24" cols="80"></textarea>
<p>Lines: <span id="numLines">0</span></p>
var $log = $('#log'),
    $button = $('#clickme'),
    $numLines = $('#numLines'),
    MAX_LINES = 5000,
    lorem_ipsum = ' Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
    lineCounter = 0;

$button.click(function()
{
    $log.val($log.val() + generateMoreLines()).change();
});

$log.change(function ()
{
    var text = tail(MAX_LINES, $log.val());
    $log.val(text);
    $numLines.text(countNewlines(text));
});

function generateMoreLines()
{
    var buf = [];
    for (var i = 0; i < 1000; i++)
    {
        buf.push(lineCounter++ + lorem_ipsum);
    }
    return buf.join('\n');
}

function countNewlines(haystack)
{
    return count('\n', haystack);
}

function count(needle, haystack)
{
    var num = 0,
        len = haystack.length;
    for (var i=0; i < len; i++)
    {
        if (haystack.charAt(i) === needle)
        {
             num++;
        }
    }
    return num;
}

function tail(limit, haystack)
{
    var lines = countNewlines(haystack) + 1;
    if (lines > limit)
    {
        return haystack
            .split('\n')
            .slice(-limit)
            .join('\n');
    }
    return haystack;
}