Reputation: 56914
I am trying to write my first single-page application. The idea is to have 1 HTML file that contains many <div>
tags; where each <div>
represents a single web "page". Then the application just shows 1 <div>
at a time, and hides the others. In this way, as users navigate my app, I'm really just showing/hiding different "page" divs, and giving the illusion of a single page app.
Additional requirements are:
http://myapp.example.com/#fizz
, http://myapp.example.com/#buzz
, etc.)I decided on using Crossroads for routing, and Hasher for History. The other lead contender was AngularJS, but in the end I decided against AngularJS because it was too heavyweight for what I'm trying to do here, and seemed to have a steeper learning curve associated with it.
So far, my project has the following directory structure:
myapp/
index.html
myapp.js
myapp.css
signals.min.js <-- Required by both Crossroads and Hasher
crossroads.min.js
hasher.min.js
The JSFiddle containing my index.html
, myapp.css
and myapp.js
files is here:
The idea is that the user can click one of the links in the "navbar" ("Home", "About", "Contact") and be brought to the "page" (div) representing that particular page.
As you can see, the default "page" should be HOME
, meaning this is the only div you should be able to see. But all the page divs are visible, and none are hidden. And until I can get the page divs showing/hiding correctly, I can't really test routing/history functionality. Have I configured Crossroads/Hasher wrong somehow?
Upvotes: -1
Views: 2143
Reputation: 2415
I think there is a solution for your requirements. It is a really easy, lightweight approach without the need of any javascript just with the power of CSS. ;-)
The key of the whole approach is the CSS pseudo-class selector :target
.
So let me first explain the concept of :target
: The pseudo selector matches when the fragment identifier (or hash, #content for instance) in the URL and the id
of an HTML element are the same. If we have a URL like http://www.example.com/hallo.html#content
and an element with the id="content"
the selector #content:target { ... }
would match.
You can´t really see the URL in this fiddel, but you will in another example. Her is the code of the fiddle:
HTML:
<a href="#content">content</a>
<div id="content">
Markup is poetry!
</div>
CSS:
#content {
border: 1px solid black;
padding: 20px;
}
#content:target {
background: lightblue;
}
The :target
approach leads to this stripped down example to explain the page-navigation-idea: http://jsfiddle.net/Cxr73/1/ Again you can´t really see the URLs with the fragment identifier.
HTML:
<a href="#div1">div1</a>
<a href="#div2">div2</a>
<a href="#div3">div3</a>
<div id="div2">
<div id="div3">
<div class="div1Inner">content div1</div>
<div class="div2Inner">content div2</div>
<div class="div3Inner">content div3</div>
</div>
</div>
CSS:
.div2Inner, .div3Inner,
#div2:target .div1Inner, #div3:target .div1Inner {
display: none;
}
#div2:target .div2Inner, #div3:target .div3Inner {
display: block;
}
Hide all div
s that should not be displayed at first: .div2Inner, .div3Inner { display: none;}
. So just <div class="div1Inner">content div1</div>
is visible. Show the corresponding div
when the fragment identifier is part of the URL: #div2:target .div2Inner, #div3:target .div3Inner {display: block;}
. In the end you have to hide div1
when div2
or div3
are visible: #div2:target .div1Inner, #div3:target .div1Inner { display: none; }
. Combine the first and the last CSS selector and you get to the CSS shown above.
Some recommendations on your markup:
<center>
element was deprecated because it defines the presentation of its contents. For this purposes we have CSS.nav
, header
, section
, footer
, etc.Here you have the final approach of my ideas, with your CSS plus the :target
selectors (starts at line 600) and what I consider a clean markup:
Fiddle: http://jsfiddle.net/Cxr73/2/
To finally see the fragment identifier plus the :target
in action and for test purposes another URL: DEMO ... this demo will disappear in a few days, but the fiddle will stay.
I think that pretty much matches all your needs. Have fun!
Upvotes: 4