Uncaught TypeError: impossible de lire la propriété 'top' de undefined

91

Je m'excuse si cette question a déjà reçu une réponse. J'ai essayé de rechercher des solutions mais je n'ai trouvé aucune qui convenait à mon code. Je suis encore nouveau sur jQuery.

J'ai deux types différents de menus collants pour deux pages différentes. Voici le code pour les deux.

$(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();
    });
});

Mon problème est que le code pour le menu latéral collant en bas ne fonctionne pas car la deuxième ligne de code var contentNav = $('.content-nav').offset().top;déclenche une erreur qui lit "Uncaught TypeError: Cannot read property 'top' of undefined". En fait, aucun autre code jQuery en dessous de cette deuxième ligne ne fonctionne à moins qu'ils ne soient placés au-dessus.

Après quelques recherches, je pense que le problème est que $('.content-nav').offset().tople sélecteur spécifié ne peut pas être trouvé car il se trouve sur une page différente. Si oui, je ne trouve pas de solution.

Edubba
la source
1
utilisez jsbin.com s'il vous plaît.
Royi Namir
vérifier en html si la div est présente ou non
Bhadra

Réponses:

141

Vérifiez si l'objet jQuery contient un élément avant d'essayer d'obtenir son décalage:

var nav = $('.content-nav');
if (nav.length) {
  var contentNav = nav.offset().top;
  ...continue to set up the menu
}
Guffa
la source
2
Cela marche! Et quelle solution simple. J'ai tellement plus à apprendre. Merci beaucoup.
edubba
oui ça marche pour moi aussi. mais quelle est la différence entre var contentNav = $('.content-nav').offset().topet votre code?
Prashant Tapase
@Prashant: La différence est que le code vérifie si le nombre d'éléments que l' $('.content-nav')appel a trouvé était différent de zéro avant d'essayer d'obtenir la position du premier élément trouvé.
Guffa
1
stackoverflow.com/questions/28508939/ ... J'ai la table mais je reçois toujours l'erreur.
SearchForKnowledge
@Guffa merci mon pote! mais je me demandais simplement ... J'ai toujours eu l'élément en place qui était une balise <header>. Cela importerait-il s'il s'agit d'un <div> ou d'un <header>?
Antonio Almeida
17

Votre document ne contient aucun élément avec classe content-nav, donc la méthode .offset()retourne undefined qui n'a en effet aucune toppropriété.

Vous pouvez voir par vous-même dans ce violon

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

(vous verrez "undefined")

Pour éviter de planter tout le code, vous pouvez avoir un tel code à la place:

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

Violon mis à jour .

Shadow Wizard est une oreille pour vous
la source
1
merci pour cette réponse, j'ai un problème différent mais cela fonctionne parfaitement
Naved Khan
12

Je sais que c'est extrêmement ancien, mais je comprends que ce type d'erreur est une erreur courante pour les débutants, car la plupart des débutants appelleront leurs fonctions lors du chargement de leur élément d'en-tête. Vu que cette solution n'est pas du tout abordée dans ce fil, je vais l'ajouter. Il est très probable que cette fonction javascript ait été placée avant le chargement du html réel . N'oubliez pas que si vous appelez immédiatement votre javascript avant que le document ne soit prêt, les éléments nécessitant un élément du document peuvent trouver une valeur non définie.

Joseph Casey
la source
$ (document) .ready (fonction () {...}); se déclenche lorsque le document est chargé et que l'emplacement du script n'a pas d'importance. Mais vous avez tellement raison que tout script sans ce wrapper peut ne pas fonctionner lorsqu'il est noté en haut de la page.
David
11

Le problème que vous rencontrez probablement est qu'il y a un lien quelque part dans la page vers une ancre qui n'existe pas. Par exemple, disons que vous avez ce qui suit:

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

Il doit y avoir un élément dans la page avec cet identifiant, exemple:

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

Assurez-vous donc que chacun des liens correspond à l'intérieur de la page avec l'ancre correspondante.

drjorgepolanco
la source
3

J'ai rencontré un problème similaire et j'ai constaté que j'essayais d'obtenir le décalage du pied de page mais que je chargeais mon script dans un div avant le pied de page. C'était quelque chose comme ça:

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

Donc, le problème était que j'appelais l'élément de pied de page avant le chargement du pied de page.

J'ai poussé mon script sous le pied de page et cela a bien fonctionné!

MARYLAND. Atiqur Rahman
la source
0

J'ai eu le même problème ("Uncaught TypeError: Cannot read property 'top' of undefined")

J'ai essayé toutes les solutions que j'ai pu trouver et j'ai noté que cela m'a aidé. Mais ensuite, j'ai remarqué que mon DIV avait deux identifiants.

J'ai donc supprimé la deuxième pièce d'identité et cela a fonctionné.

Je souhaite juste que quelqu'un me dise de vérifier mes pièces d'identité plus tôt))

Andrew Losseff
la source