1

I'm building a small single page app with a navigation. the pages are position in div-container which are display by clicking on a link. The code for the page changig

        // show the given page, hide the rest
        function show(elementID) {
            history.pushState({ 
                plate_id: 1, 
                plate: elementID 
            }, null, elementID);
            goTo(elementID);
        }
        function goTo(elementID) {
            var ele = document.getElementById(elementID);
            if (!ele) {
                console.log("fail");
                return;
            }
            // get all pages, loop through them and hide them
            var pages = document.getElementsByClassName('page');

            for(var i = 0; i < pages.length; i++) {
                pages[i].style.display = 'none';
            }
            // then show the requested page
            ele.style.display = 'block';
        }
        window.onpopstate = function (event) {  
              var content = "";
              if(event.state) {
                content = event.state.plate;
              }
              if (content != '') goTo(content);
        }

the links looks like

<a href="#" onclick="show('Page_1');" id="1">page 1</a>

and the divs

<div id="Page_1" class="page" style="">

now when i'm using a link the url changes to .../Page_1# or .../Page_2# and the page is display directly. Now if i use a back button (own or browser doesn't matter) some magic happens which i don't understand.

for example

  1. clicking on first link -> go to ../Page_1# (directly, everythinks fine)
  2. clicking on secound link -> go to ../Page_2# (directly, everythinks fine)
  3. using back button -> go to ../Page_2 (without # and nothing happens but should go to Page_1???!!)
  4. using back button again -> go to ../Page_1# (nothing happen)
  5. using back button again -> go to ../Page_1 (page 1 is loading)

i don't understand why the thinks in step 3 and 4 happens! it will be nice if someone could help me

Linda
  • 2,375
  • 4
  • 30
  • 33

2 Answers2

1

Maybe you want your link's onclick to be: onclick="show('Page_1'); return false;" or onclick="return show('Page_1');" and your show function to finish with return false;.

By returning false, the browser won't actually follow the href="#" but just execute your JavaScript instead.

evilham
  • 346
  • 3
  • 12
  • Well this works for me! Thank's! I'm new to programming and trying to implement thinks in a "clean" way... so is this good or are there any other options just a little bit "professional"?! – Linda Dec 02 '14 at 08:19
  • 1
    And some other problem...if i go to page1, then to page2 and so on the URL changes to .../page1 , .../page2 and so on. Now if th user touches the refresh button he will get an 404 Error because it's only a single page app and the wanted url doesn't excist. So is there a workaround for the refresh button? – Linda Dec 02 '14 at 08:29
  • In that case, instead of having URLs that look like `http://example.org/bla/Page_1` and so on, you probably want them to look like this: `http://example.org/bla?Page_1`. Notice the question mark :). I'm asuming `bla` is the `html` file of your webapp and that the server redirects it to `bla.html`. – evilham Dec 02 '14 at 11:50
  • well and how to add this mystic "?" ? – Linda Dec 02 '14 at 15:09
  • 1
    Same way you change the URL to something else! That is with history.pushState, you just give a URL with the '?' symbol. Take a look at [this](https://stackoverflow.com/questions/6944744/javascript-get-portion-of-url-path#6944772). – evilham Dec 08 '14 at 11:02
0

I would do this with AngularJS, because there you don't have to care about history.js. It's working out of the box.

Please check the following demo to get you started. You can also find the same code at jsFiddle here.

At the links the active class are not set properly, but that's not difficult to do. That's described at some examples at AngularJS and here at SO. See this SO question

'use strict';

var pageTemplate = "<div>{{page.title}}<div>";
var pageTitles = ['Page1', 'Page2'];

var app = angular.module('routingDemo', ['ngRoute']);

app.config(['$routeProvider', '$locationProvider',

function ($routeProvider, $locationProvider) {
    //$locationProvider.html5Mode(true);

    $routeProvider.
    when('/', {
        //templateUrl: 'partials/phone-list.html',
        template: "<div>main page</div>",
        //controller: 'MainCtrl'
    }).
    when('/pages/:pageId', {
        //templateUrl: 'partials/phone-detail.html',
        template: pageTemplate,
        controller: 'PagesCtrl'
    }).
    otherwise({
        redirectTo: '/'
    });
}]);

app.controller('PagesCtrl', ['$scope', '$routeParams', function ($scope, $routeParams) {
    $scope.page = {
        'title': pageTitles[$routeParams.pageId - 1]
    };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.3/angular.js"></script>
<script src="https://code.angularjs.org/1.2.6/angular-route.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>

<div ng-app="routingDemo">
    <nav class="navbar navbar-default" role="navigation">
        <div class="navbar-header"> 
            <a class="navbar-brand" href="#/">Static pages demo</a>
        </div>
        <div>
            <ul class="nav navbar-nav">
                <li class="active"><a href="#/pages/1">Page 1</a></li>
                <li><a href="#/pages/2">Page 2</a></li>
            </ul>
        </div>
    </nav>
    <div class="container" ng-view></div>
</div>
Community
  • 1
  • 1
AWolf
  • 8,770
  • 5
  • 33
  • 39