TypeError não capturado: Não é possível ler a propriedade 'top' de undefined

91

Peço desculpas se esta pergunta já foi respondida. Tentei pesquisar soluções, mas não consegui encontrar nenhuma que se adequasse ao meu código. Ainda sou novo no jQuery.

Tenho dois tipos diferentes de menus fixos para duas páginas diferentes. Aqui está o código para ambos.

$(document).ready(function () {
    var contentNav = $('.content-nav').offset().top;
    var stickyNav = function () {
        var scrollTop = $(window).scrollTop();
        if (scrollTop > contentNav) {
            $('.content-nav').addClass('content-nav-sticky');
        } else {;
            $('.content-nav').removeClass('content-nav-sticky')
        }
    };
    stickyNav();
    $(window).scroll(function () {
        stickyNav();
    });
});
$(document).ready(function () {
    var stickyNavTop = $('.nav-map').offset().top;
    // var contentNav = $('.content-nav').offset().top;
    var stickyNav = function () {
        var scrollTop = $(window).scrollTop();
        if (scrollTop > stickyNavTop) {
            $('.nav-map').addClass('sticky');
            // $('.content-nav').addClass('sticky');
        } else {
            $('.nav-map').removeClass('sticky');
            // $('.content-nav').removeClass('sticky')
        }
    };
    stickyNav();
    $(window).scroll(function () {
        stickyNav();
    });
});

Meu problema é que o código do menu lateral fixo na parte inferior não funciona porque a segunda linha do código var contentNav = $('.content-nav').offset().top;dispara um erro que diz "TypeError não capturado: não é possível ler a propriedade 'superior' de indefinido". Na verdade, nenhum outro código jQuery abaixo dessa segunda linha funciona, a menos que sejam colocados acima dela.

Depois de alguma pesquisa, acho que o problema é que $('.content-nav').offset().topnão consigo encontrar o seletor especificado porque está em uma página diferente. Nesse caso, não consigo encontrar uma solução.

Edubba
fonte
1
use jsbin.com por favor.
Royi Namir
verifique em html se o div está presente ou não
Bhadra

Respostas:

141

Verifique se o objeto jQuery contém algum elemento antes de tentar obter seu deslocamento:

var nav = $('.content-nav');
if (nav.length) {
  var contentNav = nav.offset().top;
  ...continue to set up the menu
}
Guffa
fonte
2
Isso funciona! E que solução simples. Eu tenho muito mais a aprender. Muitíssimo obrigado.
edubba
sim, funciona para mim também. mas qual é a diferença entre var contentNav = $('.content-nav').offset().tope seu código?
Prashant Tapase
@Prashant: A diferença é que o código verifica se o número de elementos que a $('.content-nav')chamada encontrou era diferente de zero antes de tentar obter a posição do primeiro elemento encontrado.
Guffa
1
stackoverflow.com/questions/28508939/… Eu tenho a mesa, mas ainda estou recebendo o erro.
SearchForKnowledge
@Guffa obrigada cara! no entanto, apenas pensando ... Eu sempre tive o elemento no lugar que era uma tag <header>. Isso importa se for um <div> ou <header>?
Antonio Almeida
17

Seu documento não contém nenhum elemento com classe content-nav, portanto, o método .offset()retorna indefinido que na verdade não possui toppropriedade.

Você pode ver por si mesmo neste violino

alert($('.content-nav').offset());

(você verá "undefined")

Para evitar travar todo o código, você pode ter esse código:

var top = ($('.content-nav').offset() || { "top": NaN }).top;
if (isNaN(top)) {
    alert("something is wrong, no top");
} else {
    alert(top);
}

Violino atualizado .

Shadow Wizard é ouvido para você
fonte
1
obrigado por esta resposta, tenho um problema diferente, mas está funcionando perfeitamente
Naved Khan
12

Eu sei que isso é extremamente antigo, mas eu entendo que esse tipo de erro é um erro comum para iniciantes, já que a maioria deles chamará suas funções quando seu elemento de cabeçalho for carregado. Visto que esta solução não é abordada neste tópico, vou adicioná-la. É muito provável que esta função javascript tenha sido colocada antes de o html real ser carregado . Lembre-se, se você chamar seu javascript imediatamente antes que o documento esteja pronto, os elementos que requerem um elemento do documento podem encontrar um valor indefinido.

Joseph Casey
fonte
$ (documento) .ready (função () {...}); dispara quando o documento é carregado e não importa onde o script está. Mas você está tão certo que qualquer script sem esse wrapper pode não funcionar quando indicado no topo da página.
David
11

O problema que você provavelmente está tendo é que existe um link em algum lugar da página para uma âncora que não existe. Por exemplo, digamos que você tenha o seguinte:

<a href="#examples">Skip to examples</a>

Deve haver um elemento na página com esse id, por exemplo:

<div id="examples">Here are the examples</div>

Portanto, certifique-se de que cada um dos links corresponde dentro da página com sua âncora correspondente.

drjorgepolanco
fonte
3

Passei por um problema semelhante e descobri que estava tentando obter o deslocamento do rodapé, mas estava carregando meu script dentro de uma div antes do rodapé. Era algo assim:

<div> I have some contents </div>
<script>
  $('footer').offset().top;
</script>
<footer>This is footer</footer>

Então, o problema era que eu estava chamando o elemento de rodapé antes que o rodapé fosse carregado.

I empurrado para baixo o meu script abaixo rodapé e funcionou muito bem!

MD. Atiqur Rahman
fonte
0

Eu tive o mesmo problema ("Uncaught TypeError: Cannot read property 'top' of undefined")

Tentei todas as soluções que pude encontrar e notar que ajudou. Mas então eu descobri que meu DIV tinha dois IDs.

Então, eu removi o segundo ID e funcionou.

Eu só queria que alguém me dissesse para verificar minhas identidades antes))

Andrew Losseff
fonte