2010-09-01 13 views
24

Con el control de acordeón jQuery, ¿cómo puedo hacer que se desplace a un elemento que he seleccionado cuando está fuera de la pantalla?jQuery Accordion: ¿se desplazará a la parte superior del elemento abierto?

Cuando:

  • tengo un elemento de acordeón con mayores contenidos de la ventana visible
  • que desplazarse hasta el segundo punto de acordeón
  • hago clic en el segundo elemento de acordeón para mostrarlo
  • La primera opción de acordeón se contrae, y la segunda se abre, pero se desliza fuera de la pantalla.

¿Hay una opción para que el acordeón se desplace al segundo elemento?

Respuesta

20

Puede intentar usar el scrollTo jQuery plugin. Te permite hacer cosas como esta:

$.scrollTo('div#foo'); // scroll the browser window so div#foo is in view 
$('div#foo').('#bar'); // scroll within div#foo so #bar is in view 

Enlazar ScrollTo() al evento accordionactivate, así:

$('#youraccordion').bind('accordionactivate', function(event, ui) { 
    /* In here, ui.newHeader = the newly active header as a jQ object 
       ui.newContent = the newly active content area */ 
    $(ui.newHeader).ScrollTo(); // or ui.newContent, if you prefer 
}); 

Cuando se activa el evento accordionactivate?

Se activa después de activar un panel (después de la animación). Si el acordeón se colapsó previamente, ui.oldHeader y ui.oldPanel serán objetos jQuery vacíos. Si el acordeón se está colapsando, ui.newHeader y ui.newPanel serán objetos jQuery vacíos.

Referencias: jQuery UI Accordion

+0

el que el plugin es? Tu enlace no va a ninguna parte. – Toydor

+0

@Toydor, en los años transcurridos desde que escribí esta respuesta, el "repositorio" de complementos de jQuery, tal como está, se reestructuró por completo (después de perderse en un bloqueo, si no recuerdo mal). Actualicé el enlace para señalar lo que creo que es la versión actual del complemento. –

+3

FYI, la API para jQuery UI Accordion widgets ha cambiado. El nuevo evento para usar es 'accordionactivate': http://api.jqueryui.com/accordion/#event-activate –

0

Hey tenía el mismo problema. Aquí está lo que funcionó para mí, al menos, lo que parece la manera más fácil. Usando el complemento scrollTo.

<script type="text/javascript"> 
    $(function(){ 
     $('#youraccordionheader').click(function(){ 
      $.scrollTo(this)             
     }) 
    }); 
</script> 

Espero que pueda ser útil para alguien.

0

Implementé la primera respuesta y me gustó esta opción porque es una función para todos los paneles de acordeón. Sin embargo, he notado que seguí recibiendo un error cuando se trata de (re) cerrar el mismo panel de acordeón - que suspendería el guión en esta línea en el plugin ScrollTo:

attr[key] = val.slice && val.slice(-1) == '%' ? 

El val regresaba vacío, por lo que encontré otra respuesta aquí que dice que verifique si está vacía y agregó/reemplazó esta función, por lo que funciona ahora.

else{ 
var val = targ[pos]; 
// Handle percentage values 
if(val) { 
    attr[key] = val.slice && val.slice(-1) == '%' ? 
    parseFloat(val)/100 * max 
    : val; 
    } 
} 
1

Tuve problemas para vincular el evento cuando utilizó la función clic para cerrar del acordeón. Agregar solo una única declaración if lo solucionó.

$('#accordion').bind('accordionchange', function(event, ui) { 
    if(!ui.newHeader.length) { return; } 
    /* In here, ui.newHeader = the newly active header as a jQ object 
       ui.newContent = the newly active content area */ 
    $.scrollTo(ui.newHeader); // or ui.newContent, if you prefer 
}); 
7

Sé que esta pregunta es antigua, pero ninguna de las anteriores funcionó como me hubiera gustado. Así es como lo logré. El -50 era solo en caso de que esto apareciera en una aplicación web de iPad o iPhone para que la página no se desplazara por la parte superior del encabezado del acordeón detrás de la barra de estado.

$('#accordion').accordion({ 
    collapsible: true, 
    autoHeight: false, 
    animated: false 
}); 
$('.ui-accordion-header').bind('click',function(){ 
    theOffset = $(this).offset(); 
    $(window).scrollTop(theOffset.top - 50); 
}); 
+0

Sí, esto también funciona. ¡Muchas gracias! +1 para la propiedad 'autoHeight'. Su respuesta ayudó a matar dos pájaros de un tiro :) – theTuxRacer

+0

* Precisamente * lo que se necesitaba para mis páginas de ayuda de iPad basadas en popover. Muchas gracias! ¡Te votaría x100 si pudiera! – mpemburn

11

Como quiero que el colapso sea cierto, agregué una prueba if para cancelar el error de todos los artículos que se colapsaron. Además, no me quiero la cabecera a ser exactamente en la parte superior de la página, así que bajé la ubicación scrollTop por 100:

$(document).ready(function() { 
    $(".ui-accordion").bind("accordionchange", function(event, ui) { 
     if ($(ui.newHeader).offset() != null) { 
     ui.newHeader, // $ object, activated header 
     $("html, body").animate({scrollTop: ($(ui.newHeader).offset().top)-100}, 500); 
     } 
    }); 
    }); 
+1

TEN EN CUENTA que esto no funciona si * collapsible * está establecido en verdadero. – Martin

+0

Gracias. Este es el único código que funcionó a partir de todo lo anterior. – theTuxRacer

+2

+1 ya que no requiere ningún complemento. –

0

Basta con utilizar esta función en window.load

$(function() { 
    var icons = { 
    header: "ui-icon-circle-plus", 
    activeHeader: "ui-icon-circle-minus" 
    }; 
    $("#accordion").accordion({ 
    icons: icons, autoHeight: false, collapsible: true, active: false, 
    activate: function(event, ui){ 
     var scrollTop = $(".accordion").scrollTop(); 
     var top = $(ui.newHeader).offset().top; 
    //do magic to scroll the user to the correct location 

    //works in IE, firefox chrome and safari 
     $("html,body").animate({ scrollTop: scrollTop + top -35 }, "fast"); 
     }, 



    }); 

    }); 

perfectl wokring

1

La solución de Martin funciona muy bien. Sin embargo, cuando agrega este código, se desplazará a la parte superior siempre, sin importar si su acordeón está visible en la página o no.

Si desea desplazarse a la parte superior sólo cuando el contenido de acordeón más grande que la ventana visible, a continuación, utilizar código siguiente:

$(document).ready(function() { 

    function isScrolledIntoView(elem) 
    { 
     var docViewTop = $(window).scrollTop(); 
     var docViewBottom = docViewTop + $(window).height(); 

     var elemTop = $(elem).offset().top; 
     var elemBottom = elemTop + $(elem).height(); 

     return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)); 
    } 

    $(".accordion-inner").bind("accordionchange", function(event, ui) { 
     if ($(ui.newHeader).offset() != null) { 
     if (!isScrolledIntoView(ui.newHeader)) 
     { 
      ui.newHeader, // $ object, activated header 
      $("html, body").animate({scrollTop: ($(ui.newHeader).offset().top)-100}, 500); 
     } 
     } 
    }); 
    }); 
20

Funciona para mí y probado,

$("#accordion").accordion({ 
    heightStyle: "content", 
    collapsible: true, 
    active: false, 
    activate: function(event, ui) { 
     if(!$.isEmptyObject(ui.newHeader.offset())) { 
      $('html:not(:animated), body:not(:animated)').animate({ scrollTop: ui.newHeader.offset().top }, 'slow'); 
     } 
    } 
}); 

http://jsfiddle.net/ilyasnone/aqw613em/

+0

Este me funcionó, ¡gracias! – Desmond

+0

Simple, funciona muy bien. 9 líneas de código! – Sparky1

+1

Esto fue perfecto. Yo trabajo con "plegable: verdadero" y "activo: falso" "Esta debería ser la respuesta elegida. No la que se seleccionó. La que está arriba no funciona con" collapsible: true ". Buen trabajo – agon024

3

consulte this respuesta por techfoobar

$(function() { 
    $("#accordion").accordion({ 
     autoHeight: false, 
     collapsible: true, 
     heightStyle: "content", 
     active: 0, 
     animate: 300 // collapse will take 300ms 
    }); 
    $('#accordion h3').bind('click',function(){ 
     var self = this; 
     setTimeout(function() { 
      theOffset = $(self).offset(); 
      $('body,html').animate({ scrollTop: theOffset.top - 100 }); 
     }, 310); // ensure the collapse animation is done 
    }); 
}); 

Me funciona con la modificación anterior.

$("#accordion").accordion({ 
        heightStyle: "content", 
        collapsible: true, 
        activate: function (event, ui) { 

         try 
         { 
          var self = this; 
          theOffset = $(self).offset(); 
          $('body,html').animate({ scrollTop: theOffset.top - 100 }); 
         } catch (e) { 
          alert(e); 
         } 
        } 
       }); 
+0

gracias por el enlace de respuesta del propietario – mokNathal

0

No es necesario complemento scrollTo, puede hacer lo siguiente:

$('.accordionNormalitzador').bind('accordionactivate', function(event, ui) { 
     $(ui.newHeader)[0].scrollIntoView(); 
    }); 
Cuestiones relacionadas