2011-01-22 16 views
6

Hace un tiempo resolví un problema para alguien que tenía wanted his textarea to grow. Realicé una función que escucha los eventos scroll y keyup del área y recalcula el número de filas. Quería usar el código en otro proyecto, pero hay un problema. Los textarea no se conocen Para resolver esto, estoy usando live en lugar de bind, por lo que las áreas futuras también estarán vinculadas.¿Cómo se vincula el evento de desplazamiento en un Live()?

Ahora me parece que el live ejecuta mucho más lento que un bind. Creé a simplified example on jsFiddle. El área de texto superior se comporta como yo quiero, pero los recién agregados parpadean debido a la señalización tardía (estoy usando Chrome).

¿Cómo puedo hacer que el live sea tan rápido como el bind? El problema es que scroll no se puede utilizar con una instrucción live. ¿Hay alguna manera de habilitar scroll para live? ¿Hay quizás un evento jQuery que me indique que se ha agregado un nuevo TextArea, así que puedo usar un enlace para agregar el scroll en el elemento recién creado?

Espero sus ideas.

EDITAR: Se ha cambiado el enlace al código. Se eliminó el scrollingCode. Se agregó otro botón para crear un área de texto diferente. El problema tiene que ver con 'scroll'. No dispara.

aclaración: No sabrá qué función creará el textarea. Veo parpadeo en los cuadros agregados dinámicamente en Chrome.

Para los futuros lectores:

En jQuery 1.3.x solamente el siguiente JavaScript eventos (además de eventos personalizados) podrán ser marcadas con .live(): click, dblclick, keydown, keypress, keyup, mousedown, mousemove, mouseout, mouseover, and mouseup. Como de jQuery 1.4, el método .live() admite eventos personalizados, así como todos los eventos de JavaScript que burbujean. A partir de jQuery 1.4.1 incluso se enfoca y desenfoca el trabajo con live (mapeo al más apropiado, burbujeo, eventos enfocados en y focusout). A partir de jQuery 1.4.1 se puede especificar el evento de desplazamiento (asignando a mouseenter y mouseleave, que, a su vez, se asignan a mouseover y mouseout).

+0

@Pointy Sí, eso es cierto, es por eso que estoy haciendo un área de texto que será lo suficientemente grande para que no pueda desplazarse. Solo se desplaza muy ligeramente cuando el usuario ingresa datos nuevos y se dispara antes de la tecla. Intenta eliminar el desplazamiento del ejemplo y verás que no funcionará tan bien. –

+0

@Kees sí, lo veo después de jugar con él. Su jsFiddle cuelga mi navegador cuando intento escribir en el área de texto "estática", y funciona bien, supongo que cuando escribo un área de texto agregada. Una cosa: ¿por qué el código llama a "scrollTop (0)" en los bucles de ampliación/reducción? – Pointy

+0

@Pointy elem.scrollTop (0); se puede quitar :-). Fue por algo que estaba intentando: P. –

Respuesta

4

La respuesta es simple. scroll es lo que evita el parpadeo, ya que se dispara en el primer momento del cambio de tamaño. Pero scroll no tiene ningún efecto con live (porque no hace burbujas), por lo que las áreas de texto creadas recientemente se redimensionarán en keyup pero se dispararán más tarde (por lo tanto, parpadearán).

Actualización: Por supuesto que incluso puedo resolver su problema. Sólo tiene que pedir :) [Demo]

$('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); 
}); 

El punto es, que se mezcla con livebind. El evento keyup, que se activa en todos los elementos (debido a live), agrega el evento único scroll condicionalmente.

Actualización 2: Ah, y por cierto su código de redimensionamiento conjunto puede ser mejor escribir como:

// 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()) 
}​ 
+0

Tienes que estar bromeando :(. Espero que estés equivocado ;-). –

+0

??? Elimina 'keyup' de' live' y verás que 'live (" scroll ")' ni siquiera se llama. http://www.quirksmode.org/dom/events/scroll.html – galambalazs

+0

Sí ... ¡Ya veo! ¿Es posible hacer alguna acción 'en vivo' para agregar la acción de desplazamiento a mano? –

2

Try this (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)); 
}); 

} 

Básicamente, se vuelve a vincular el evento mediante un ID creado de forma dinámica. No es tan elegante como la solución de karim79, pero funciona.

+1

El problema es que no sé qué función está haciendo el área de texto.Será el comportamiento predeterminado de todos los textarea actuales y futuros en la página. –

0

que se unen a un evento personalizado que llamo cada vez que sucede algo importante. De esta manera:

$(body).live('MyCustomEvent', function() { 
    $("#MyScrollItem").scroll(function() { 
     // Do things here 
    } 
}); 

Hope that helps. Corto y dulce.

+0

está en lo cierto, pero ya estaba en la sección "Para lectores futuros" y cito textualmente: "a partir de jQuery 1.4.1 incluso el enfoque y desenfoque funcionan con directo (mapeo al más apropiado, burbujeo, enfoque de eventos y enfoque). A partir de jQuery 1.4.1, se puede especificar el evento de desplazamiento (asignación a mouseenter y mouseleave, que, a su vez, se asignan a mouseover y mouseout) ". La pregunta fue formulada para 1.3. * –

+0

Oops, lo siento, me lo perdí. Supongo que esto también puede ser útil para futuros lectores ;-) – dbme

0

Encontré una solución a este problema: el problema es donde .live y scroll no funcionan.

Mi solución es utilizar el evento bind ... y el tiempo de espera. El tiempo de espera le dará tiempo al DOM para actualizar, por ej.

El siguiente código se usa para cargar contenido cuando se desplaza hacia la parte inferior de la página. Eche un vistazo al setTimeout y al bind.

$('.list').bind("scroll",function(){ 
    $('.list').height())); 
    if($('.list').scrollTop() >= ($('.list').height()+ $(window).height())){   
     setTimeout(function(){ //Time out is used as there is a possibility that 
     last_function(); 
     },200); 
    } 
}); 
+0

Vuelva a verificar su código. Puede haber algunos paréntesis adicionales. – Zeeshan

Cuestiones relacionadas