RyeGuy RyeGuy - 2 months ago 29
CSS Question

How to Load Content into Section Element upon Navbar Click

Hello I would like to get the content of a webpage to update upon the navbar click. Here are the primary issues:

(1) The home page loads but when I toggle through the nav it section content goes blank.

(2) When I click back on the home tab the contents appear, but the MathJax CDN (not included here) does not reload.

(3) Sorry for no JSFiddle. Did not know how to duplicate the 'a href...' while keeping my site paths private.

It would be preferable to use Ajax so I will not have to load the entirety of the site's content when user visits home page. However any solution you provide is awesome! Thanks



$('ul.nav li a').on('click', function(e) { // User clicks nav link
e.preventDefault(); // Stop loading new link
var url = this.href; // Get value of href

$('li.active').removeClass('active'); // Clear current indicator
$(this).addClass('active'); // New current indicator

$('div#container').remove(); // Remove old content
$('#content').load(url + ' #container').hide().fadeIn('slow'); // New content
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Appreciate your effort</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="MYURL/home.html">Home</a>
</li>
<li class=""><a href="MYURL/producer.html"> Producer</a>
</li>
<li class=""><a href="MYURL/science.html">Science</a>
</li>
<li class=""><a href="MYURL/blog.html">Blog</a>
</li>
<li class=""><a href="MYURL/mission.html">Our Mission</a>
</li>
<li class=""><a href="MYURL/Contact.html">Contact</a>
</li>
</ul>
</div>
<!--/.nav-collapse -->
</div>
</nav>

<section id="content">
<div id="container">
<h1>
Home PAGE
</h1>
</div>
</section>

<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>




Answer

You can use the :target pseudo-class to change between content.

Basically you hide your new content and show it when the user clicks your menu item.

.content--new {
  display: none;
}
#section:target .content--old {
  display: none;
}
#section:target .content--new {
  display: block;
}
<nav>
  <ul>
    <li>
      <a href="#section">Section</a>
    </li>
  </ul>
</nav>

<section id="section">
  <p class="content content--old">
    Old Content
  </p>
  <p class="content content--new">
    New Content
  </p>
</section>


If you want to keep this new content shown after clicking another menu item, you can add a class to the container to do the same :target does.


EDIT:

You can use the .one() jQuery method to attach an event handler that will perform an AJAX call once the user clicks the menu item, this action will only be performed one time that's why we are using one() and not on().

In the demo an attribute is used to get the url to the ajax call.

HTML:

<nav>
  <ul>
    <li>
      <a class="menu__item" href="#section" data-url="/echo/html/">Section</a>
    </li>
  </ul>
</nav>

<section id="section">
  <div class="content content--old">
    Old Content
  </div>
  <div class="content content--new"></div>
</section>

CSS:

.content--new {
  display: none;
}

#section:target .content--old {
  display: none;
}

#section:target .content--new {
  display: block;
}

JS:

$(document).ready(function(e) {

  $(".menu__item").one("click", function(e) {

    var sectionUrl = $(this).attr("data-url");
    var callMethod = "POST";
    var dataHtml = "<h1>New Content</h1>";
    /*You can add a loader function here;*/

    $.ajax({
      url: sectionUrl,
      type: callMethod,
      cache: false,
      data: {
        'html': dataHtml
      },
      dataType: 'html',
      success: function(htmlReturned) {
        $(".content--new").html(htmlReturned);
        alert("This will only be executed once");
        /* Remove Loader */
      }
    });

  });

});

JSFIDDLE


NOTES:

  • The :target pseudo-class is still being used but you can always replace the old content html instead of adding it to the new content container.
  • The data used in the demo is just a string generated there, but you will use your AJAX response.