History API and History.js Back Button issue
Asked Answered
H

5

6

I am loading the page via Ajax. When the user clicks a link the page is being loaded AJAX successfully, but when the user click the back button the pages reloads the initial page. so the scenario is this.

  1. Load the initial page(index.php)
  2. User Clicks on the link
  3. The Page loads Successfully
  4. Clicks the Back button
  5. The initial page is now being shown twice.

Here's the mark up.

    $(function() {
            // Prepare
            var History = window.History; // Note: We are using a capital H instead of a lower h
            if (!History.enabled) {
                // History.js is disabled for this browser.
                // This is because we can optionally choose to support HTML4 browsers or not.
                return false;
            }

            // Bind to StateChange Event
            History.Adapter.bind(window, 'statechange', function() { // Note: We are using statechange instead of popstate
                var State = History.getState();
                $('#content').load(State.url);
            });

            $('a').click(function(evt) {
                evt.preventDefault();
                History.pushState(null, $(this).text(), $(this).attr('href'));
                alert(State.url)
            });
        });

THis is the markup

   <div id="wrap">
            <a href="page1.html">Page 1</a>
        </div>

        <div id="content">
            <p>Content within this box is replaced with content from
                supporting pages using javascript and AJAX.</p>
        </div>

IF you still do not get my question or the scenario

Here's the complete scenario. Initial Page

enter image description here

When the User Clicks the link the selected page loads successfully

enter image description here

When I click the back button the initial page is now doubled

enter image description here

As you can see the "Page1" link is doubled. Is this a browser issue? or my understading of the history api is something lacking or missing? What is the possible solution for this?

Heavily answered 25/12, 2012 at 5:41 Comment(1)
It's your error! You are loading the whole page within <div id="content"></div> when you go back.Grouper
C
5

If you construct your site to use a similar template for both the main pages as well as the content pages, you could use the container selector syntax for jquery.load:

// See: http://api.jquery.com/load/
$('#result').load('ajax/test.html #container');

Which in your case would result in:

$('#content').load(State.url + ' #content');

This will have the added benefit that the content url pages are accessible directly as well without adding to much tricks.

Catherincatherina answered 29/12, 2012 at 21:26 Comment(0)
B
1

This might happen because when you navigate backwards it will fire 'statechange' event, and in your callback you are loading a content of that page with the given url: $('#content').load(State.url);, so when, say, you are navigating backwards to the / URL it will load content of that index page and place it inside your container, so your mark up will actually look like this:

<div id="wrap">
        <a href="page1.html">Page 1</a>
</div>

<div id="content">
    <div id="wrap">
        <a href="page1.html">Page 1</a>
    </div>

    <div id="content">
        <p>Content within this box is replaced with content from
            supporting pages using javascript and AJAX.</p>
    </div>
</div>

There are several ways to solve this problem - the simplest one is just to detect if user navigated to the initial page and do not load this page through ajax, but insert predefined content. You can also detect on the server side if the request was made through ajax and then return only the content needed to update your page (which in your case may be <p>Content within this box is replaced with content from supporting pages using javascript and AJAX.</p>)

Brey answered 27/12, 2012 at 11:3 Comment(2)
I also suggest to keep loaded pages in cache, to not reload page on back/forwardPhotoactive
how would I reload it backward of forward using cache?Heavily
G
0
 $(function() {
            // Prepare
            var History = window.History; // Note: We are using a capital H instead of a lower h
            if (!History.enabled) {
                // History.js is disabled for this browser.
                // This is because we can optionally choose to support HTML4 browsers or not.
                return false;
            }

            // Bind to StateChange Event
            History.Adapter.bind(window, 'statechange', function() { // Note: We are using statechange instead of popstate
                var State = History.getState();
                if(State.url==document.URL){
                    $.ajax({
                          url: State.url,
                          success: function(data) {
                                        var dom_loaded=$(data);
                                        $('#content').html($('#content',dom_loaded).html());
                          }
                        });


                }else{
                    $('#content').load(State.url);
                }
            });

            $('a').click(function(evt) {
                evt.preventDefault();
                History.pushState(null, $(this).text(), $(this).attr('href'));
                alert(State.url)
            });
        });

Try this js.

Grouper answered 27/12, 2012 at 11:42 Comment(1)
an explanation will help, and what changes did you addHeavily
A
0

I was having similar problem. I simply added $content.html("") to clear the container before loading it via ajax. See snippet relevent section starts with //added by Joel to fix content loading twice on back button

$.ajax({
            url: url,
            success: function (data, textStatus, jqXHR) {
                // Prepare
                var 
                    $data = $(documentHtml(data)),
                    $dataBody = $data.find('.document-body:first'),
                    $dataContent = $dataBody.find(contentSelector).filter(':first'),
                    $menuChildren, contentHtml, $scripts;

                // Fetch the scripts
                $scripts = $dataContent.find('.document-script');
                if ($scripts.length) {
                    $scripts.detach();
                }

                // Fetch the content
                contentHtml = $dataContent.html() || $data.html();
                if (!contentHtml) {
                    document.location.href = url;
                    return false;
                }

                // Update the menu
                $menuChildren = $menu.find(menuChildrenSelector);
                $menuChildren.filter(activeSelector).removeClass(activeClass);
                $menuChildren = $menuChildren.has('a[href^="' + relativeUrl + '"],a[href^="/' + relativeUrl + '"],a[href^="' + url + '"]');
                if ($menuChildren.length === 1) { $menuChildren.addClass(activeClass); }

                // Update the content
                $content.stop(true, true);
                //added by Joel to fix content loading twice on back button
                $content.html("");
                //end added by joel
                $content.html(contentHtml).ajaxify().css('opacity', 100).show(); /* you could fade in here if you'd like */

                // Update the title
                document.title = $data.find('.document-title:first').text();
                try {
                    document.getElementsByTagName('title')[0].innerHTML = document.title.replace('<', '&lt;').replace('>', '&gt;').replace(' & ', ' &amp; ');
                }
                catch (Exception) { }

                // Add the scripts
                $scripts.each(function () {
                    var $script = $(this), scriptText = $script.text(), scriptNode = document.createElement('script');
                    scriptNode.appendChild(document.createTextNode(scriptText));
                    contentNode.appendChild(scriptNode);
                });

                // Complete the change
                if ($body.ScrollTo || false) { $body.ScrollTo(scrollOptions); } /* http://balupton.com/projects/jquery-scrollto */
                $body.removeClass('loading');
                $window.trigger(completedEventName);

                // Inform Google Analytics of the change
                if (typeof window._gaq !== 'undefined') {
                    window._gaq.push(['_trackPageview', relativeUrl]);
                }

                // Inform ReInvigorate of a state change
                if (typeof window.reinvigorate !== 'undefined' && typeof window.reinvigorate.ajax_track !== 'undefined') {
                    reinvigorate.ajax_track(url);
                    // ^ we use the full url here as that is what reinvigorate supports
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                document.location.href = url;
                return false;
            }
        }); // end ajax
Aculeate answered 30/12, 2012 at 21:5 Comment(0)
H
0

I m using this code, hope this will help you.

   //get the contents of #container and add it to the target action page's #container
    $('#container').load(url+' #container',function(){
        $('#container').html($(this).find('#container').html());
    });
Hewe answered 12/3, 2015 at 6:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.