2
\$\begingroup\$

I am loading divs from separate HTML files into a div on the index.html page.

This is being done using jQuery's .load(). There is however, a lot of repetition and I'm wondering if there is a cleaner way to achieve this.

The HTML:

<nav class="menu-side">
  <a href="#" id="about">About</a>
  <a href="#" id="help"></i>Help</a>
  <a href="#" id="contact">Contact</a>
</nav>
<div id="target">
  <!-- content is being loaded here from other .html files -->
</div>

The JS:

$(document).ready( function() {
    $("#about").on("click", function() {
        $("#target").load("../pages/theAboutPage.html");
    });
    $("#help").on("click", function() {
        $("#target").load("../pages/theHelpPage.html");
    });
    $("#contact").on("click", function() {
        $("#target").load("../pages/theContactPage.html");
    });
});
\$\endgroup\$
  • 7
    \$\begingroup\$ Welcome to Code Review! To help us help you, please post your entire code and not just snippets of it. As it stands, there is only so much we can review. \$\endgroup\$ – Phrancis Sep 29 '14 at 21:47
4
\$\begingroup\$

Quick and simple: Use the href attribute of the navigation links. Please note that this in no way represents a full ajax app and leaves a lot to be desired.

HTML

<nav id="menu" class="menu-side">
    <a href="../pages/theAboutPage.html" id="about">About</a>
    <a href="../pages/theHelpPage.html" id="help">Help</a>
    <a href="../pages/theContactPage.html" id="contact">Contact</a>
</nav>
<div id="target">
    <!-- content is being loaded here from other .html files -->
</div>

JavaScript

$(function() {
    var $menu = $('#menu'), 
        $target = $('#target');

    $menu.on('click', '> a', function(event) {
        var $this = $(this);
        event.preventDefault();
        $target.load($this.attr('href'));
    });
});

JSFiddle

\$\endgroup\$
  • \$\begingroup\$ Can you clarify what you mean by "leaves a lot to be desired"? If this does the job required then what's lacking? \$\endgroup\$ – CommonCents Oct 1 '14 at 16:11
  • \$\begingroup\$ The code is fine as is (removes repetition in your submitted code). in a typical ajax app one would go further and add routing and history changes, so your "pages" are represented in url fragments and you don't break the back button. But that is beyond the scope of your question imho. \$\endgroup\$ – mlnmln Oct 1 '14 at 16:19
  • \$\begingroup\$ Thank you. What you have described is new to me. Could you point me towards a link i can read further about url fragments, routing, history changes and not breaking the back button? \$\endgroup\$ – CommonCents Oct 1 '14 at 16:39
5
\$\begingroup\$

ngView

First of all you described ngView from angularjs

It is what it does. It just helps to organize routing code and template loading. In next section I'll show samples from my current self-learning project.

If you need strict jQuery solution, place appropriate comment.

Angular solution

Make navigation bar with virtual links and place ng-view attribute into container div.

<nav class="menu-side">
  <a href="#/about">About</a>
  <a href="#/help"></i>Help</a>
  <a href="#/contact">Contact</a>
</nav>
<div class="container" ng-view></div>

Mark html tag with ng-app attribute and value of you app name

<html ng-app="my_app_name">

Load js at end of body. You can use cdn for angular libraries. app.js is your application source file.

<script type="text/javascript" src="libs/angular/angular.min.js"></script>
<script type="text/javascript" src="libs/angular-route/angular-route.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>

Your app.js contains main routes

(function() {
  'use strict';
  angular.module('my_app_name', ['ngRoute'])
  .config([
    '$routeProvider', function($routeProvider) {
      $routeProvider.when('/about', {
        templateUrl: 'templates/about.html'
      });
      $routeProvider.when('/help', {
        templateUrl: 'templates/help.html'
      });
      $routeProvider.when('/contact', {
        templateUrl: 'templates/contact.html'
      });
    }
  ]);
}).call(this);

After that you will gen fast, scalable template rendering. Also you can read angular docs for more features.

jQuery solution

IMHO: there is no common solution, but some practices can be applied.

e.g. making configuration array for repeated code.

var navbar_selector = '#navbar',
    target_selector = '#target',
    nav_config = [
        {"id": "about", "text": "About", "url": "../pages/theAboutPage.html"},
        {"id": "help", "text": "Help", "url": "../pages/theHelpPage.html"},
        {"id": "contact", "text": "Contact", "url": "../pages/theContactPage.html"}
    ];

nav_config.forEach(function (config) {
    $('<a/>').attr({"id": config.id, "text": config.text}).click(function(){
        $(target_selector).load(config.url);
    }).appendTo(navbar_selector);
})

But it's steel ugly solution.

\$\endgroup\$
  • \$\begingroup\$ Thank you. I will look into Angular. Right now I would like to learn about a strict jQuery solution. \$\endgroup\$ – CommonCents Sep 29 '14 at 22:29
  • 2
    \$\begingroup\$ Recommending Angular.js seems like overkill for this problem. Angular.js, being a heavy-duty and highly capable framework, is not something that you introduce into your application just for convenience — there should be a more compelling reason. \$\endgroup\$ – 200_success Sep 29 '14 at 22:37
  • \$\begingroup\$ @CommonCents, I don't think that there is some common approach in jQuery. But you can use arrays of needed data for repeated part of code. \$\endgroup\$ – outoftime Sep 29 '14 at 22:52
  • \$\begingroup\$ @CommonCents, good quick start for angular at codeschool \$\endgroup\$ – outoftime Sep 29 '14 at 23:02
  • 1
    \$\begingroup\$ @JoshWillik, I wasn't sure about that and didn't want to check it out. \$\endgroup\$ – outoftime Sep 30 '14 at 19:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.