网站搜索

javascript - 如何在 Live() 上绑定滚动事件?


前一阵子,我帮某人解决了一个问题,他希望他的文本区域可以自动增长。我写了一个函数,监听该区域的 scroll 和 keyup 事件,并重新计算行数。我想在另一个项目中使用这段代码,但出现了一个问题。这些文本区域还未知。为了解决这个问题,我使用 live 而不是 bind,这样未来的文本区域也会被绑定。

现在我发现 live 执行速度远慢于 bind。我在 jsFiddle 上创建了一个简化的示例。上面的文本区域按我想要的方式工作,但新添加的文本区域由于信号迟到而闪烁(我使用的是 Chrome)。

我如何让 live 和 bind 一样快? 问题是 scroll 不能与 live 语句一起使用。有没有办法让 live 支持 scroll? 是否有一个 jQuery 事件可以告诉我有新的 TextArea 被添加,这样我就可以用 bind 将 scroll 添加到新创建的元素上?

我期待你的想法。

编辑:已更改代码链接。已移除 scrollingCode。添加了另一个按钮来创建不同的文本区域。问题与 'scroll' 有关。它没有触发。

澄清:我不知道哪个函数会创建文本区域。我在 Chrome 中看到动态添加的框闪烁。

致未来的读者:

在 jQuery 1.3.x 中,只有以下 JavaScript 事件(除了自定义事件)可以使用 .live() 绑定:click, dblclick, keydown, keypress, keyup, mousedown, mousemove, mouseout, mouseover, 和 mouseup。从 jQuery 1.4 开始,.live() 方法支持自定义事件以及所有会冒泡的 JavaScript 事件。从 jQuery 1.4.1 开始,即使是 focus 和 blur 也能与 live 一起使用(映射到更合适的冒泡事件 focusin 和 focusout)。从 jQuery 1.4.1 开始,可以指定 hover 事件(映射到 mouseenter 和 mouseleave,而 mouseenter 和 mouseleave 又映射到 mouseover 和 mouseout)。

答案#1

答案很简单。scroll 是防止闪烁的原因,因为它会在调整大小的最初时刻触发。但 scroll 对 live 没有效果(因为它不冒泡),所以你新创建的文本区域将在 keyup 时调整大小,但它触发得较晚(因此会闪烁)。

更新: 当然,我甚至可以解决你的问题。你只需要问一下 :) [演示]

$('textarea.autoresize').live('keyup', function() {
    var el = $(this);
    if (!el.data("has-scroll")) {
        el.data("has-scroll", true);
        el.scroll(function(){
           resizeTextArea(el);
        });
    }
    resizeTextArea(el);
});

重点是,它将 live 与 bind 混合使用。keyup 事件会在所有元素上触发(因为使用了 live),并有条件地添加唯一的 scroll 事件。

更新 2:哦,顺便说一下,你的整个调整大小的代码可以更好地写成这样:

// resize text area (fixed version of Pointy's)
function resizeTextArea(elem) {
    elem.height(1); elem.scrollTop(0);
    elem.height(elem[0].scrollHeight - elem[0].clientHeight + elem.height())
}

答案#2

试试这个(JSFiddle):

$('#Add').click(function(){
    var id = "newtextarea"+Math.floor(Math.random()*1000);
   $('#pane').append($('<textarea class="new" rows="1" cols="40" id="'+id+'"></textarea><br/>'));
    $('textarea:last').focus();
    bindAgain(id);
});

//inital resize
resizeTextArea($('#tst'));

//'live' event
$('textarea.new').bind('keyup scroll', function() {
    resizeTextArea($(this));
});

function bindAgain(id)
{
    $('#'+id).bind('keyup scroll', function() {
    resizeTextArea($(this));
});

}

基本上,它使用动态创建的ID重新绑定事件。没有karim79的解决方案那么优雅,但它有效。