En esta entrada trataré un tema bastante técnico, explicando cómo resolver este error concreto. Durante el rediseño de mi página, quise modernizar los menús de navegación. Quería que el menú quedase fijado cuando se desplazase uno con el Scroll. Cuando estaba programando los efectos para ello, en base a ejemplos que había encontrado, me encontré con el siguiente error: «Uncaught TypeError: Cannot read property ‘top’ of undefined». 

¿Por qué ocurre el error «Uncaught TypeError: Cannot read property ‘top’ of undefined»?

Al menos buscando información al respecto, enseguida supe porqué me ocurría y vi que no era la única. Pero no encontré ninguna información clara sobre cómo resolverlo.

Esto ocurre precisamente en el código de javascript que se añade para determinar la posición del menú respecto a la página. La propiedad «Top» (property ‘top’) intenta recuperar esta altura. Pero en caso de que el elemento para el que estamos intentando averiguarla no exista en la página, dará este error.

En mi caso ocurría porque tengo dos estilos de cabecera diferente según la página. La página principal, que es dónde tengo la cabecera a la que se debe aplicar este script. Y otro estilo para el resto de páginas, donde no existe esa cabecera. Por eso, en esas páginas me aparecía el error.

Cómo resolver el error Uncaught TypeError Cannot read property 'top' of undefined

Resolviendo el error «Uncaught TypeError: Cannot read property ‘top’ of undefined»

En caso de que el nombre sea incorrecto

En algunos casos que vi en que les ocurría el error, se trataba de un problema con los nombres de las variables. Por ejemplo, el tema WordPress que utilizaban tenía definido el script referenciando el menú con un nombre que no es la que tenía luego asignado.

Lo primero sería ver si se quiere mantener el tema actual. De ser así, en este caso sería tan sencillo como cambiar la referencia en el Script, para que haga referencia a la clase correcta, o cambiar la clase del menú. Según se vea más sencillo. Al implicar esto el modificar código, podría ser interesante definir un tema «hijo» para evitar editar el tema original y que los cambios pudieran perderse.

En caso de que el elemento realmente no exista

Para resolverlo me planteé el cargar el Script sólo en la página principal. Pero el mismo fichero contenía también los efectos de navegación para la adaptación a móviles. (Reducir el menú a un botón de tipo «Hamburguesa» que abre y cierra el menú.) Por lo que no podía hacer eso, ya que esta parte sí aplicaba a toda la página.

Separar esta parte del script a otro fichero tampoco me convencía, porque cuantos más ficheros peor, y luego los medidores de velocidad muestran advertencias sobre esto.

Así que quería una solución diferente.

Al final lo que hice fue añadir una validación previa para verificar si la variable existe. Así que con esto, asunto resuelto.

// Código para añadir los efectos de la cabecera al hacer scroll
jQuery(function ($) {
    if (typeof $('.mi-menu').offset() !== 'undefined') {
        var altura = $('.mi-menu').offset().top;
        if ($(document).scrollTop() > altura) {
            $('.mi-menu').addClass('mi-menu-fixed');
        }
 
        // Fijar el menú de navegación al hacer scroll
        $(document).on('scroll', function () {
 
            if ($(document).scrollTop() > altura) {
                $('.mi-menu').addClass('mi-menu-fixed');
 
            } else {
                $('.mi-menu').removeClass('mi-menu-fixed');
            }
 
        });
    };
 
});

También podría interesarte…

Recibeel PDF gratis y empieza tu aventura

Recibeel PDF gratis y empieza tu aventura

¡Apúntate a mi lista VIP ya! Recibirás las dos primeras fases de mi libro "Crea una web Funcional y con Personalidad" y te acompañaré en la aventura de preparar todo lo que necesitas para comenzar con emails semanales. ¡Nada de SPAM!

¡Gracias por suscribirte! Tus datos se han enviado correctamente. Ahora sólo tienes que confirmar tu suscripción desde el e-mail que habrás recibido. Si no lo encuentras, echa un vistazo en las carpetas de SPAM o Promociones.