
Me gusta tener confianza con los títulos de las publicaciones, pero la realidad en este caso es una *posible* solución para menús desplegables muy largos. El problema con los menús desplegables largos es que el menú desplegable en sí mismo puede ir debajo del “pliegue” del sitio web. Es decir, debajo del área visible de la ventana del navegador. Entonces, para acceder a los elementos del menú a continuación, debe desplazarse por la ventana del navegador. Para aquellos de nosotros con ruedas de desplazamiento de algún tipo en nuestros ratones (¿ratones?), no es un gran problema. Para aquellos que no tienen, esos elementos del menú inferior son totalmente inaccesibles, porque usar la barra de desplazamiento del navegador significa salir del menú (y probablemente cerrarlo).
Ver demostración Descargar archivos
Primero vi esta idea en vigor en la página del centro de cuentas de Media Temple. Tienen un menú desplegable para “Dominios” en el que se enumeran todos y cada uno de sus dominios alojados con ellos. Esta puede ser una lista muy larga. Media Temple había implementado una técnica en la que, a medida que se desplaza hacia abajo, el menú se movía de manera acelerada.
Por supuesto, mientras tomo esta captura de pantalla, descubro que la solución genial que habían complementado ya no está allí. Me hace preguntarme qué tipo de problemas tuvieron con eso, pero bueno, sigamos adelante. Aquí un intento de visualizar la idea:
jQuery lo hace funcionar
Voy a volcar todo el código aquí solo para una referencia rápida. Lo comenté, por lo que debería ser bastante fácil de seguir. Tiene más de 60 líneas, pero no te preocupes demasiado, es bastante simple.
- Establecer una altura máxima para los menús desplegables
- Al pasar el mouse, revela el submenú
- Calcule un multiplicador de velocidad basado en la altura del submenú
- Esté atento al movimiento del mouse en el menú
- Desplácese por el menú con el movimiento del mouse, según el multiplicador
- Al sacar el mouse, cerrar el menú
var maxHeight = 400;
$(function(){
$(".dropdown > li").hover(function() {
var $container = $(this),
$list = $container.find("ul"),
$anchor = $container.find("a"),
height = $list.height() * 1.1, // make sure there is enough room at the bottom
multiplier = height / maxHeight; // needs to move faster if list is taller
// need to save height here so it can revert on mouseout
$container.data("origHeight", $container.height());
// so it can retain it's rollover color all the while the dropdown is open
$anchor.addClass("hover");
// make sure dropdown appears directly below parent list item
$list
.show()
.css({
paddingTop: $container.data("origHeight")
});
// don't do any animation if list shorter than max
if (multiplier > 1) {
$container
.css({
height: maxHeight,
overflow: "hidden"
})
.mousemove(function(e) {
var offset = $container.offset();
var relativeY = ((e.pageY - offset.top) * multiplier) - ($container.data("origHeight") * multiplier);
if (relativeY > $container.data("origHeight")) {
$list.css("top", -relativeY + $container.data("origHeight"));
};
});
}
}, function() {
var $el = $(this);
// put things back to normal
$el
.height($(this).data("origHeight"))
.find("ul")
.css({ top: 0 })
.hide()
.end()
.find("a")
.removeClass("hover");
});
// Add down arrow only to menu items with submenus
$(".dropdown > li:has('ul')").each(function() {
$(this).find("a:first").append("<img src="https://css-tricks.com/long-dropdowns-solution/images/down-arrow.png" />");
});
});
HTML y CSS
Dudo en volcar un montón de código HTML y CSS aquí porque simplemente no es muy interesante. Puede descargar el código de todos modos, así que eche un vistazo allí. Es solo una lista desordenada anidada semántica normal y un estilo simple muy básico.
Pruebas
Lo probé en todo hasta IE 6 y parecía bueno.
Ver demostración Descargar archivos