remove evento event español bloquear jquery jquery-plugins scroll unbind

evento - ¿Qué puede hacer que la función de desvinculación de jQuery no funcione como se esperaba?



unbind jquery (1)

Eche un vistazo al siguiente código (adicionalmente, necesitará jquery.js , jquery.viewport.js y jquery.scrollTo.js ).

El comportamiento que esperaría de este script es que cada vez que me desplazo por la página, las filas rojas ( <tr> elementos con clase alwaysVisible ) deben insertarse justo debajo de la fila visible más alta (elemento <tr> ) de esa tabla. Luego, la página debe desplazarse para que la primera de estas filas rojas aparezca "exactamente" en la parte superior de la ventana gráfica. Lo que realmente sucede es que makeVisibleWhatMust(); se llama repetidamente hasta que llego al final de la página. Pensé $(window).unbind(''scroll''); mantendría makeVisibleWhatMust(); de ser llamado nuevamente, pero aparentemente esto no funciona.

¿Alguna idea de por qué?

Aquí está el JavaScript que escribí:

function makeVisibleWhatMust() { $(''#testContainer'').text( $(''#testContainer'').text() + ''called/n''); $(''table.scrollTable'').each ( function() { var table = this; $($(''tr.alwaysVisible'', table).get().reverse()).each ( function() { $(this).insertAfter( $(''tr:in-viewport:not(.alwaysVisible)'', table)[0] ); } ); $(window).unbind(''scroll''); $(window).scrollTo( $(''tr.alwaysVisible'')[0] ); $(window).bind(''scroll'', makeVisibleWhatMust); } ); } $(document).ready ( function() { $(window).bind(''scroll'', makeVisibleWhatMust); } );

Y aquí hay una página HTML para probarlo:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Scroll Tables Test Page</title> <script type="text/javascript" src="jQuery.js"></script> <script type="text/javascript" src="jquery.viewport.js"></script> <script type="text/javascript" src="jquery.scrollTo.js"></script> <script type="text/javascript" src="scrollTable.js"></script> <style type="text/css"> table th, table td { border: 1px solid #000; padding: .3em; } .alwaysVisible { background: #F66; } </style> </head> <body> <table class="scrollTable"> <thead> <tr class="alwaysVisible"> <th>Row name</th> <th>Content</th> </tr> <tr class="alwaysVisible"> <th>Row 2</th> <th>Row 2</th> </tr> </thead> <tbody> <script type="text/javascript"> for(var i = 0; i < 50; ++i) { document.writeln("<tr><td>Row " + i + "</td><td>Content</td></tr>"); } </script> </tbody> <tfoot> <tr> <td>Footer</td> <td>Footer 2</td> </tr> </tfoot> </table> <div id="testContainer">TEST CONTAINER</div> </body> </html>


Creo que tu problema es que scrollTo usa animate :

// From the plugin''s source function animate( callback ){ $elem.animate( attr, duration, settings.easing, callback && function(){ callback.call(this, target, settings); }); };

Y animate utiliza un temporizador para realizar la animación. El resultado es que .scrollTo volverá antes de que se complete el desplazamiento y volverás a enlazar tu controlador de desplazamiento mientras scrollTo todavía se está desplazando. De ahí los eventos cuando no los estás esperando.

Una solución fácil sería usar una bandera para decir a makeVisibleWhatMust que scrollTo está desplazando y usar una devolución de llamada scrollTo para borrar la bandera cuando esté lista, algo como esto:

function makeVisibleWhatMust() { // Ignore the event if we''re doing the scrolling. if(makeVisibleWhatMust.isScrolling) return; $(''#testContainer'').text( $(''#testContainer'').text() + ''called/n''); $(''table.scrollTable'').each(function() { var table = this; $($(''tr.alwaysVisible'', table).get().reverse()).each(function() { $(this).insertAfter( $(''tr:in-viewport:not(.alwaysVisible)'', table)[0] ); }); makeVisibleWhatMust.isScrolling = true; $(window).scrollTo($(''tr.alwaysVisible'')[0], { onAfter: function() { makeVisibleWhatMust.isScrolling = false; } }); } ); } makeVisibleWhatMust.isScrolling = false;

Y aquí hay una versión en vivo que parece funcionar: http://jsfiddle.net/ambiguous/ZEx6M/1/