最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Getting Backbutton to work in single page website and implementing "speaking" URLs - Stack Overfl

programmeradmin0浏览0评论

I have a single page website and would like to achieve the following:

  1. back button working as if it was a normal website

  2. and instead of say,

www.mysite/index.php?p=#this-is-a-great-product

I'd like to have this url

www.mysite/this-is-a-great-product

while still having back button working properly.

Regarding 1.) I use the following code ive found which works great:

<!-- Getting BackButton to  work properly -->
<script type="text/javascript">
var times = 0;
function doclick() {
    times++;
}
function doclick() {
    times++;
    location.hash = times;
}
window.onhashchange = function() {     
    if (location.hash.length > 0) {        
        times = parseInt(location.hash.replace('#',''),10);     
    } else {
        times = 0;
    }
}
</script>

…but of course it just changes any anchors to /#1, then /#2 and so forth ro get the backbutton to work. But as I'm not a programmer I don't know how to change it… :(

Regarding 2.) i can add in htaccess this:

>RewriteEngine On
>RewriteRule ^([^/.]+)/?$ /index.php?page=$1

and this changes /index.php?p=products to /products.

So how do I change the above code (under 1.) so it doesn't change all anchors to #1, #2, etc. but instead references / uses the urls I achieved under 2, like

www.mysite/this-is-a-great-product

And (probably a very dumb question, but a very important one) -given I use only the new url links on my site- is there any danger that this still might result in duplicate content in any way?

Regarding this, should I (for that reason or any other) sefreferential my single page index.php to itself using rel canonical link=index.php?

Thanks so much in advance!

I have a single page website and would like to achieve the following:

  1. back button working as if it was a normal website

  2. and instead of say,

www.mysite.com/index.php?p=#this-is-a-great-product

I'd like to have this url

www.mysite.com/this-is-a-great-product

while still having back button working properly.

Regarding 1.) I use the following code ive found which works great:

<!-- Getting BackButton to  work properly -->
<script type="text/javascript">
var times = 0;
function doclick() {
    times++;
}
function doclick() {
    times++;
    location.hash = times;
}
window.onhashchange = function() {     
    if (location.hash.length > 0) {        
        times = parseInt(location.hash.replace('#',''),10);     
    } else {
        times = 0;
    }
}
</script>

…but of course it just changes any anchors to /#1, then /#2 and so forth ro get the backbutton to work. But as I'm not a programmer I don't know how to change it… :(

Regarding 2.) i can add in htaccess this:

>RewriteEngine On
>RewriteRule ^([^/.]+)/?$ /index.php?page=$1

and this changes /index.php?p=products to /products.

So how do I change the above code (under 1.) so it doesn't change all anchors to #1, #2, etc. but instead references / uses the urls I achieved under 2, like

www.mysite.com/this-is-a-great-product

And (probably a very dumb question, but a very important one) -given I use only the new url links on my site- is there any danger that this still might result in duplicate content in any way?

Regarding this, should I (for that reason or any other) sefreferential my single page index.php to itself using rel canonical link=index.php?

Thanks so much in advance!

Share Improve this question edited Jun 22, 2018 at 20:06 pgSystemTester 9,9422 gold badges26 silver badges57 bronze badges asked Jan 29, 2014 at 8:50 surisuri 3631 gold badge4 silver badges12 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 3

As mentioned, you will want to use the HTML5 History API. Please note, this API is relatively new and therefore browser support is a concern. At the time of writing, approximately 71% of global Internet users have support for it (see http://caniuse.com/#feat=history for browser support information). Therefore, you will want to ensure you have a fall-back solution for this. You will likely want to use the older #! solution that was popular before the HTML 5 History API was adopted.

If you use the history API to replace, for example, example.com/#!settings with example.com/settings and a user bookmarks that nicer URL, then when they go to visit it, their browser will make a request to the server for /settings (which doesn't actually exist in the web server's context). Therefore, you will need to make sure your web server has some redirection rules (i.e. RewriteEngine) such that it can take the pretty URLs and redirect them to the #! version (and then if the user's browser supports the history API it can replace that with the nice URL).

If you aren't very comfortable programming yourself, I'd recommend using a JavaScript library that does a lot of the work for you. I did some quick searching and discovered the following, though there might be better ones out there: https://github.com/browserstate/history.js

Basically i have created a small prototype on jsfiddle which tracks all the urls accessed via ajax calls.

Also contains navigation to access links back and forth .

How It Actually Works:

  • I have created a global array called history, which keeps track of all urls accessed via ajax in sequence.
  • also there a global index defined to keep track of the url being accessed when navigating back and forth the links in history array.
  • There is History section at the bottom of the jsfiddle, which shows the sequence in which the links are accessed by capturing the link names and posting them in the order in which they were accessed.

JS Code:

$(function () {
var history = [];
var index = 0;
$('.links').on('click', function () {
    $('#history').append($(this).text());
    var address = $(this).attr('data-ref');
    index += 1;
    history[index] = address;

    $('.links').attr('disabled', 'disabled');
    loadExternalPage(address);
    console.log('list:' + history);
});

$('#back').on('click', function () {
    console.log(index);
    index -= 1;
    console.log(index);
    console.log(history[index]);
    loadExternalPage(history[index]);
});

$('#forward').on('click', function () {
    console.log(index);
    index += 1;
    console.log(index);
    console.log(history[index]);
    loadExternalPage(history[index]);
});

var loadExternalPage = function (address) {
    console.log(history[index]);
    $('#result-section').load(address, function () {
        console.log('data-loaded');
        $('.links').removeAttr('disabled');
    });
};
});

Live Demo @ JSFiddle:http://jsfiddle.net/dreamweiver/dpwmcu0b/8/

Note: This solution is far from being perfect, so dont consider it as final solution but rather use it as a base to build upon

  1. On using BACK and FORWARD functions in the browser top-left button:

In principle, there is no great problem with this as long as you work with the existing storage object (a stack) for previously visited web pages on your browser. This object is the history object and you can see what is in it anytime by right-clicking and selecting "Inspect", then selecting the "Console" tab, then enter window.history and enter. Check out the Browser Object Model (BOM) section of Pro Java For Web Developers (Frisbee) for the background to the history object. (Just a few pages, an easy read, don't worry.) Just remember that in this process you are storing the new page that you move to, not the old page that you are leaving !

For a simple SPA example, look at this example - codepen.io/tamjk/pen/NWxWOxL

  1. In regard to the URL, the method that the history object uses to load a new page state into the history stack, i.e. pushState(...), has an optional third parameter for associating a dummy URL for each web page that is stored. Personally, when I first sorted out the BACK & FORWARD functions, I did not use dummy URLs as the browser was being confused by them and I had enough to do sorting out the history sequence using just the first two parameters, i.e.
  • the state object - a JSON holding enough data to recreate the page stored
  • a title for the page I expect that you could also use a dummy URL but I will leave that to the student as an exercise, as they say.

But you can add the URL of the new page if you want to.

In the example above, for the state object I just used the IDs of the page's nav link and its content element. For the title, I programmatically changed the HTML's page title element with each change of page. I did this after noticing that the browser listed the previous pages according to the title element in the HTML code. Unfortunately, this title does not show up on CodePen when you right-click on the browser BACK and FORWARD buttons due to CodePen's system not allowing it. But it will show on your own sites.

It's important that whatever method you use to store current web page states when using the navbar links to navigate, you DO NOT ADD page states to the browser history when you arrive at them using BACK or FORWARD buttons. Otherwise your history stack will have repetitions of entries going back and deletion of entries going forward.
In the CodePen, this was achieved by having the addToHistory(..) function separate to and outside the scope of the switchPage(...) function. This allows you use of the switchPage function in both normal navbar navigation and browser BACK/FORWARD navigation. The third parameter of switchPage(...) is a boolean indicating if the page is to be stored in history or not.

Anyway, this is just something to get you started.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论