【问题标题】:History API and History.js Back Button issueHistory API 和 History.js 后退按钮问题
【发布时间】:2012-12-25 05:41:23
【问题描述】:

我正在通过 Ajax 加载页面。当用户单击链接时,页面正在成功加载 AJAX,但是当用户单击后退按钮时,页面会重新加载初始页面。所以场景是这样的。

  1. 加载初始页面(index.php)
  2. 用户点击链接
  3. 页面加载成功
  4. 点击后退按钮
  5. 初始页面现在显示两次。

这是标记。

    $(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)
            });
        });

这是标记

   <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>

如果你仍然没有得到我的问题或场景

这是完整的场景。 初始页面

当用户点击链接时,所选页面加载成功

当我点击后退按钮时,初始页面现在翻了一番

如您所见,“Page1”链接翻了一番。这是浏览器的问题吗?还是我对历史 API 的理解是缺少或缺失的?对此有什么可能的解决方案?

【问题讨论】:

  • 这是你的错误!当您返回时,您将在&lt;div id="content"&gt;&lt;/div&gt; 内加载整个页面。

标签: javascript jquery ajax history.js


【解决方案1】:

如果您构建您的网站以对主页和内容页面都使用类似的模板,您可以使用 jquery.load 的容器选择器语法:

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

在您的情况下会导致:

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

这将具有额外的好处,即内容 url 页面也可以直接访问,而无需添加太多技巧。

【讨论】:

    【解决方案2】:

    这可能会发生,因为当您向后导航时,它会触发“statechange”事件,并且在您的回调中,您正在使用给定的 url 加载该页面的内容:$('#content').load(State.url);,所以当您向后导航到/ URL 它将加载该索引页面的内容并将其放置在您的容器中,因此您的标记实际上如下所示:

    <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>
    

    有几种方法可以解决这个问题 - 最简单的一种是检测用户是否导航到初始页面并且不通过 ajax 加载此页面,而是插入预定义的内容。 您还可以在服务器端检测请求是否通过 ajax 发出,然后仅返回更新页面所需的内容(在您的情况下可能是 &lt;p&gt;Content within this box is replaced with content from supporting pages using javascript and AJAX.&lt;/p&gt;

    【讨论】:

    • 我还建议将加载的页面保留在缓存中,不要在后退/前进时重新加载页面
    • 如何使用缓存从前向后重新加载?
    【解决方案3】:
     $(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)
                });
            });
    

    试试这个js。

    【讨论】:

    • 解释会有所帮助,您添加了哪些更改
    【解决方案4】:

    我遇到了类似的问题。我只是在通过 ajax 加载之前添加了 $content.html("") 来清除容器。请参阅 sn -p 相关部分以 //由 Joel 添加,用于修复后退按钮上的内容加载两次

    $.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
    

    【讨论】:

      【解决方案5】:

      我正在使用此代码,希望对您有所帮助。

         //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());
          });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-19
        • 1970-01-01
        相关资源
        最近更新 更多