简体   繁体   中英

$(document).ready firing before the DOM is loaded

I'm working on a nav bar using Bootstrap 4.0. I have a pillbox nav bar and I wrote a javascript function to automatically detect the current page and add the active class to the right pillbox. I set the function to run when the DOM is ready but it runs before any of the HTML in the BODY is loaded. Essentially the script fails to find any elements with the 'nav-link' class at runtime and does nothing. If I add the async attribute to the script however, it works as expected.

function main () {

$nav = $('nav-link');

$('.nav-link').each( function () {
    var currentPage = location.href.split("/").slice(-1);
    var currentLink = $(this).attr('href').slice(2);
    console.log(currentPage);
    console.log(currentLink);

    if (currentLink == currentPage) { 
        $(this).addClass('active');
    } else {
        $(this).removeClass('active');
    }

});


}

$(document).ready(main());

This is my HTML file.

<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Home</title>
    <!-- Library CDNs -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
    <!-- Custom JS -->
    <script async type="text/javascript" src='checkNavActive.js'></script>
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
    <!-- Custom CSS -->
    <link rel="stylesheet" href="./wikiCSS.css">
</head>

<body>

<div>
    <ul class="nav nav-pills">
      <li class="nav-item">
        <a class="nav-link" href=".\Home.html">Home</a>
      </li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href=".\DryLab.html" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">DryLab</a>
        <div class="dropdown-menu">
          <a class="dropdown-item" href=".\DryLab.html" >DryLab</a>
          <a class="dropdown-item" href="#">Another action</a>
          <a class="dropdown-item" href="#">Something else here</a>
        </div>
      </li>
      <li class="nav-item">
        <a class="nav-link" href=".\WetLab.html">WetLab</a>
      </li>
    </ul>
</div>


<div class="container title">
    <div class="row">
        <div class="col text-center">
            <h1>Home</h1>
        </div>
    </div>
</div>


</body>

Using $(document).ready(main()) calls the main() function then and there. You should be using $(document).ready(main)

 function main() { $nav = $('nav-link'); $('.nav-link').each(function() { var currentPage = location.href.split("/").slice(-1); var currentLink = $(this).attr('href').slice(2); console.log(currentPage); console.log(currentLink); if (currentLink == currentPage) { $(this).addClass('active'); } else { $(this).removeClass('active'); } }); } $(document).ready(main); 
 <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Home</title> <!-- Library CDNs --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script> <!-- Custom JS --> <script async type="text/javascript" src='checkNavActive.js'></script> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous"> <!-- Custom CSS --> <link rel="stylesheet" href="./wikiCSS.css"> </head> <body> <div> <ul class="nav nav-pills"> <li class="nav-item"> <a class="nav-link" href=".\\Home.html">Home</a> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href=".\\DryLab.html" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">DryLab</a> <div class="dropdown-menu"> <a class="dropdown-item" href=".\\DryLab.html">DryLab</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> </div> </li> <li class="nav-item"> <a class="nav-link" href=".\\WetLab.html">WetLab</a> </li> </ul> </div> <div class="container title"> <div class="row"> <div class="col text-center"> <h1>Home</h1> </div> </div> </div> </body> 

You should just use $(main) , which is a shorthand for $(document).ready(main) .

Your syntax is executing the main function instead of passing it, that's why you experience your problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM