Uncaught TypeError: Cannot read property 'top' of undefined

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

  1. 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");
            }
        });
    }
    
    0
    1. Modérateur
      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..... //
      0
    2. 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 :)
      0
    3. Modérateur
      @mari0nQue 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>
      
      
      0
    4. 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.
      0
    5. @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 :/
      0