Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 让Backbutton在单页网站中工作并实现;“说话”;网址_Javascript_Html_.htaccess_Single Page Application - Fatal编程技术网

Javascript 让Backbutton在单页网站中工作并实现;“说话”;网址

Javascript 让Backbutton在单页网站中工作并实现;“说话”;网址,javascript,html,.htaccess,single-page-application,Javascript,Html,.htaccess,Single Page Application,我有一个单页网站,希望实现以下目标: 后退按钮的工作方式就像一个普通的网站 而不是说 www.mysite.com/index.php?p=#这是一款很棒的产品 我想要这个网址 www.mysite.com/this-is-a-great-product 同时仍然有后退按钮正常工作 关于1.)我使用了我发现非常有效的以下代码: <!-- Getting BackButton to work properly --> <script type="text/javascript"

我有一个单页网站,希望实现以下目标:

  • 后退按钮的工作方式就像一个普通的网站

  • 而不是说

  • www.mysite.com/index.php?p=#这是一款很棒的产品

    我想要这个网址

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

    同时仍然有后退按钮正常工作

    关于1.)我使用了我发现非常有效的以下代码:

    <!-- 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>
    
    这将/index.php?p=products更改为/products

    那么,我如何更改上面的代码(在1下),使其不会将所有锚都更改为#1、#2等,而是引用/使用我在2下获得的URL,如

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

    (可能是一个非常愚蠢的问题,但也是一个非常重要的问题)-鉴于我只在我的网站上使用新的url链接-这是否仍有可能导致以任何方式重复内容

    关于这一点,我是否应该(出于这个原因或任何其他原因)使用rel canonical link=index.php将我的单页index.php推荐给自己


    非常感谢

    HTML5提供了一个支持浏览器历史记录的api,您可以在不重新加载的情况下管理url

    检查此链接

    演示是


    如前所述,您需要使用HTML5历史API。请注意,此API相对较新,因此需要考虑浏览器支持。在撰写本文时,大约71%的全球互联网用户支持它(有关浏览器支持信息,请参阅)。因此,您需要确保您有一个解决此问题的后备解决方案。您可能会希望使用较旧的#!在采用HTML5历史API之前流行的解决方案

    例如,如果使用历史API替换,
    example.com/#!设置
    使用example.com/settings和用户为更好的URL添加书签,然后当他们访问该URL时,他们的浏览器将向服务器请求设置(在web服务器的上下文中实际上不存在设置)。因此,您需要确保您的web服务器具有一些重定向规则(即RewriteEngine),以便它可以获取漂亮的URL并将它们重定向到#!版本(如果用户的浏览器支持历史API,它可以用漂亮的URL替换)


    若您自己编程不太舒服,我建议您使用一个JavaScript库,它可以为您做很多工作。我做了一些快速搜索,发现了以下内容,尽管可能还有更好的:

    基本上,我在
    jsfiddle
    上创建了一个小型原型,它跟踪通过ajax调用访问的所有URL

    还包含来回访问链接的导航

    它的实际工作原理:

    $(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');
        });
    };
    });
    
    • 我创建了一个名为
      history
      的全局数组,它按顺序跟踪通过ajax访问的所有URL
    • 此外,还定义了一个全局
      索引
      ,用于在
      history
      数组中来回导航链接时跟踪所访问的url
    • jsfiddle
      的底部有
      History部分
      ,它通过捕获链接名并按访问顺序发布链接来显示访问链接的顺序
    JS代码:

    $(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');
        });
    };
    });
    
    现场演示@JSFiddle:

    $(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');
        });
    };
    });
    
    注意:这个解决方案远不是完美的,所以不要认为它是最终的解决方案,而是把它作为建立在

    之上的基础。
  • 在浏览器左上角按钮中使用后退和前进功能时:
  • 原则上,只要您使用浏览器上以前访问过的网页的现有存储对象(堆栈),就不会有什么大问题。此对象是历史对象,您可以通过右键单击并选择“检查”,然后选择“控制台”选项卡,然后输入window.history并输入,随时查看其中的内容。 查看Pro Java For Web Developers(飞盘)的浏览器对象模型(BOM)部分,了解历史对象的背景。(只需几页,简单易读,不用担心。)请记住,在此过程中,您存储的是移动到的新页面,而不是离开的旧页面

    对于一个简单的SPA示例,请看这个示例。codepen.io/tamjk/pen/NWxWOxL

  • 关于URL,history对象用于将新页面状态加载到历史堆栈中的方法,即pushState(…),有一个可选的第三个参数,用于关联存储的每个网页的虚拟URL。 就我个人而言,当我第一次整理BACK&FORWARD函数时,我没有使用虚拟URL,因为浏览器被它们弄糊涂了,我只需要使用前两个参数,即
    • state对象—一个JSON,它包含足够的数据来重新创建存储的页面
    • 页面标题我希望你也可以使用一个虚拟URL,但我会把它留给学生作为练习,就像他们说的那样
    但是,如果愿意,您可以添加新页面的URL

    在上面的示例中,对于state对象,我只使用了页面导航链接及其内容元素的id。 对于标题,每次更改页面时,我都以编程方式更改HTML的页面标题元素。我这样做是因为我注意到浏览器根据HTML代码中的title元素列出了以前的页面。 不幸的是,由于CodePen的系统不允许,当您右键单击浏览器的后退和前进按钮时,此标题不会显示在CodePen上。但它会显示在你自己的网站上

    重要的是,无论使用导航栏链接导航时使用何种方法来存储当前网页状态,在使用BACK或F获得网页状态时,都不要将其添加到浏览器历史记录中