Uncaught TypeError: Cannot read property 'top' of undefined [Fermé]

Signaler
-
 mari0n -
Bonjour,
J'utilise le code suivant qui me permet d'ajouter une class à un élément du menu lorsque celui-ci est au niveau de l'écran de l'internaute :
$(document).ready(function () {
    $(document).on("scroll", onScroll); 
});

function onScroll(event){
    var scrollPos = $(document).scrollTop();
    $('#nav-main a').each(function () {
        var currLink = $(this);
        var refElement = $(currLink.attr("href"));
        if (refElement.position().top <= scrollPos +55 && refElement.position().top + refElement.height() > scrollPos +55) {
            $('#mnav-main ul li a').removeClass("active");
            currLink.addClass("active");
        }
        else{
            currLink.removeClass("active");
        }
    });
}


Il fonctionne très bien, mais dans l'inspecteur chrome, j'ai l'erreur suivante :
"Uncaught TypeError: Cannot read property 'top' of undefined"

Savez-vous pourquoi cette erreur, alors que tout fonctionne bien ?

3 réponses

Messages postés
760
Date d'inscription
samedi 29 mars 2014
Statut
Membre
Dernière intervention
8 septembre 2018
112
bonjour.
A mon avis tu doit te tromper, ton code ne fonctionne pas.
A partir de l'erreur que tu as, ce code js plante et ne vas pas plus loin que l'erreur.

cette ligne n'est pas normale pour moi
$(currLink.attr("href"));

elle appel un élément qui n'existe pas et donc qui n'as pas de position.

Tu devrais changer ta condition
if (refElement.position().top <= scrollPos +55 && refElement.position().top + refElement.height() > scrollPos +55) {

en
if (currLink.position().top <= scrollPos +55 && currLink.position().top + currLink.height() > scrollPos +55) {
Je doit préciser que j'ai importé la librairie JQuery :
https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js

Sans cela, le code ci-dessus ne fonctionne pas. Sinon il fonctionne bien sur mon site, que ce soit sur Chrome ou sur Safari, par contre dès que je scroll, la quantité d'erreurs augmente, celles affichées sont toute les mêmes : Uncaught TypeError: Cannot read property 'top' of undefined
Messages postés
32044
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
9 avril 2021
3 381
Bonjour,

Juste pour vérifier.. pourrais tu nous coller le code HTML de ta page ?


Oui, voici le code HTML :
<!DOCTYPE html>
<html lang="fr">
	<head>
		<meta charset="utf-8">
		<title>Mon site</title>
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<!--[if lt IE 9]>
		<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
		<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
		<![endif]-->
		<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
		<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
		<!--[if lt IE 9]>
		<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
		<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
		<![endif]-->
		<meta name="description" content="Ma meta description">
		<meta property="og:title" content="Mon site">
		<meta property="og:type" content="website">
		<meta property="og:url" content="lien vers mon site">
		<meta property="og:image" content="à ajouter">
		<meta property="og:description" content="Ma meta description">
		<meta property="og:locale" content="fr_FR">
		<meta property="og:site_name" content="Mon site">
		<meta name="robots" content="index, follow, notranslate, noodp">
		<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
		<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
		<link rel="stylesheet" type="text/css" href="style.css">
		<link href="https://fonts.googleapis.com/css?family=PT+Sans:400,700" rel="stylesheet">
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
	</head>
	<body id="main">
		<header id="menu">
				<nav class="navbar navbar-default">
					<div class="container-fluid">
						<div class="collapse navbar-collapse" id="nav-main">
							<ul class="nav navbar-nav navbar-right">
								<li>
									<a href="#" rel="nofollow noopener noreferrer" target="_blank">Section 1</a>
								</li>
								<li>
									<a href="#" rel="nofollow noopener noreferrer" target="_blank">Section 2</a>
								</li>
								<li>
									<a href="#" rel="nofollow noopener noreferrer" target="_blank">Section 3</a>
								</li>
								<li>
									<a href="#" rel="nofollow noopener noreferrer" target="_blank">Section 4</a>
								</li>
							</ul>
						</div>
					</div>
				</nav>
			</header>
		<div class="container-fluid">
			<p>Lorem ipsum</p>
		</div>
		<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
		<script type="text/javascript" src="js/scripts.js"></script>
	</body>
</html>


Je doit préciser qu'il y a eu une petite erreur dans le script de mon premier message (une lettre en trop ligne 12), j'ai bien retiré cette lettre mais l'erreur persiste, voici le code corrigé :

$(document).ready(function () {
    $(document).on("scroll", onScroll); 
});

function onScroll(event){
    var scrollPos = $(document).scrollTop();
    $('#nav-main a').each(function () {
        var currLink = $(this);
        var refElement = $(currLink.attr("href"));
        if (refElement.position().top <= scrollPos +55 && refElement.position().top + refElement.height() > scrollPos +55) {
            $('#nav-main ul li a').removeClass("active");
            currLink.addClass("active");
        }
        else{
            currLink.removeClass("active");
        }
    });
}
Messages postés
32044
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
9 avril 2021
3 381
Heu...
href="#"

C'est moi.... ou tes liens ne pointent sur aucune ancre ?
Normal donc qu'il ne trouve pas les éléménts non ?

Et puis dans la suite de ton code
<div class="container-fluid">
			<p>Lorem ipsum</p>
		</div>


Il n'y a mêrme pas les "sections" auxuqelles sont sensés faire référence tes liens....

Ca ne risque pas de fonctionner en effet..... //
En fait cette page, c'est mon CV, pour le mettre sur ce site j'ai donc retiré le superflu, car sinon ce serais une bien grosse page :)

Dans mon code, les liens du menu pointent bien vers les sections tel que a href="#parcours" etc...

Ensuite les sections existent bel et bien.

Le souci c'est juste que le script permettant d'ajouter une class aux liens du menu fonctionne très bien, mais crée des erreurs dans l'inspecteur Chrome. À la limite c'est pas grave en soit puisque tout fonctionne bien, mais j'aime pas bien les erreurs :)
Messages postés
32044
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
9 avril 2021
3 381 > mari0n
Que tu retires les données personnelles .. c'est normal .... mais moi ce qui m'interesse de voir c'est justement ce qui est présent (ou non) dans les HREF ainsi que les différentes DIV (et leurs ID )....
Car le code fonctionne sans erreur... à condition que les ID existent bien ...

Voici un code fonctionnel sans erreur :
<html>
 <head>
  <title>Test</title>
  <script type="text/javascript" src="jquery-3.0.0.min.js"> </script>
  <style>
   .active{
    color:red;
   }
   
   #nav-main{
     position: fixed;
     width: 100%;
     height: 30px;
     top: 0px;
     bottom: 0px;
  }
    
   .container > div {
      min-height:100px;
      background-color:lightgrey;
    }   
   .container{
     margin:50px;
     position : relative;
     padding:20px;
    
   }

  </style>
 </head>
 <body>
  <div id='nav-main'>
  <ul>
  <li> <a href="#a1" rel="nofollow noopener noreferrer" target="_blank">1</a> </li>
  <li> <a href="#a2" rel="nofollow noopener noreferrer" target="_blank">2</a> </li>
  <li> <a href="#a3" rel="nofollow noopener noreferrer" target="_blank">3</a> </li>
  </ul>
  </div>
  
  <div class="container">
  <div id="a1"> 
   <pre>
    sdfsdfsdfsdfsdfsdfsdf
    sdf
    sdfsd
    fzezezezezeze
    yuiuilui
    luiluil
    ul
    mlio
    l
    lu
    l
    ul
    ul
    uil
    uilui
    l
    uil
   </pre>
   <br><br>
  </div>
  
  
  <div id="a2"> 
    <pre>
    222222222222222
    sdfsd9ty9h8fghfghfg9hf
    9
    89
    8
    98
    3
    13
    123
    fsdfsdfsdfsdfsdf
    sdf
    sdfsd
    f
    sdfsdfsdfsdfdf
   </pre>
   <br><br>
  </div>
  
  <div id="a3"> 
    <pre>
    3333333333333333333333333
    sdfsdfsdfsdfsdfsdfsdf
    sdf
    sdfsd
    f
    sdfsdfsdfsdfdf
   </pre>
   <br><br>
  </div>
  </div>
 <script type="text/javascript">
 $(document).ready(function () {
    $(document).on("scroll", onScroll); 
});

function onScroll(event){
   var scrollPos = $(document).scrollTop();
   var offset = 30;
    $('#nav-main a').each(function () {
        var currLink = $(this);
        var href = currLink.attr("href");
        var refElement = $(href);
        if(typeof(refElement) !='undefined' && refElement.length != 0){
          var position = refElement.position().top; 
          console.log(" position = " + position + "  scrollPos = " +scrollPos );
          if (position <= scrollPos + offset && (position + refElement.height()) > (scrollPos + offset) ) {
            $('#mnav-main ul li a').removeClass("active");
            currLink.addClass("active");
          } else{
            currLink.removeClass("active");
          }
        }
        
    });
}
</script>
 </body>
</html>

Messages postés
2371
Date d'inscription
lundi 11 février 2013
Statut
Membre
Dernière intervention
13 janvier 2021
444
Il semble bien que tu ais un lien ou une section qui soit incorrecte et/ou qui n'existe pas.

Ajoute un log dans ta fonction comme ceci :
function onScroll(event){
    var scrollPos = $(document).scrollTop();
    $('#nav-main a').each(function () {
        var currLink = $(this);
        var refElement = $(currLink.attr("href"));
        
        if (refElement.position() == undefined) {
            console.log(currLink);
        }
        
        if (refElement.position().top <= scrollPos +55 && refElement.position().top + refElement.height() > scrollPos +55) {
            $('#nav-main ul li a').removeClass("active");
            currLink.addClass("active");
        }
        else{
            currLink.removeClass("active");
        }
    });
}

Ceci devrait t'indiquer quel est le lien de menu qui pose problème.
@jordane45
J'ai essayé ton script à la place du mien, il fonctionne bien, je n'ai plus d'erreur dans l'inspecteur, en revanche j'ai ceci :
http://nsa37.casimages.com/img/2016/11/21/1611210729413975.png

Bizarre non ?

@Pitet
J'ai essayé ton script, il ne fonctionne pas :/