2013-11-23 25 views
3

我制作了单页网站。当用户点击菜单按钮时,内容将加载一个Ajax。 它工作正常。 为了提高搜索引擎优化,并允许用户复制/过去不同内容的URL,我使用如何使用HTML5 pushState更改浏览器URL时处理返回按钮

function show_content() { 
     // change URL in browser bar) 
     window.history.pushState("", "Content", "/content.php"); 
     // ajax 
     $content.load("ajax/content.php?id="+id); 
} 

它工作正常。 URL更改和浏览器不重新加载页面

但是,当用户单击浏览器中的后退按钮时,URL会更改并且内容必须加载。

我做这个和它的作品:

window.onpopstate = function(event) { 
     if (document.location.pathname == '/4-content.php') { 
      show_content_1(); 
     } 
     else if (document.location.pathname == '/1-content.php') { 
      show_content_2(); 
     } 
     else if (document.location.pathname == '/6-content.php') { 
      show_content_(); 
     } 
    }; 

你知道,如果有改善这种代码的方法吗?

回答

8

我所做的是在加载页面时将对象文字传递给pushState()。这样你总是可以回到你的第一个创建的pushState。在我的情况下,我必须推两次才能回去。在页面加载时推送状态帮助我。

HTML5允许您使用数据属性,因此您的触发器可以使用它们来绑定HTML数据。

我使用try catch,因为我没有时间为旧版浏览器找到polyfill。你可能想检查Modernizr,如果这是需要你的情况。

pageLoad的

try { 
    window.history.pushState({ 
     url: '', 
     id: this.content.data("id"), // html data-id 
     label: this.content.data("label") // html data-label 
    }, "just content or your label variable", window.location.href); 
} catch (e) { 
    console.log(e); 
} 

EVENT处理程序

填充有默认信息

var obj = { 
    url: settings.assetsPath, // this came from php 
    lang: settings.language, // this came from php 
    historyData: {} 
}; 

绑定history.pushState()触发的对象。在我的情况下,委托,因为我有页面上的动态元素。

// click a trigger -> push state 
this.root.on("click", ".cssSelector", function (ev) { 
    var path = [], 
     urlChunk = document.location.pathname; // to follow your example 

    // some data-attributes you need? like id or label 
    // override obj.historyData 
    obj.historyData.id = $(ev.currentTarget).data("id"); 

    // create a relative path for security reasons 
    path.push("..", obj.lang, label, urlChunk); 
    path = path.join("/"); 

    // attempt to push a state 
    try { 
     window.history.pushState(obj.historyData, label, path); 
     this.back.fadeIn(); 
     this.showContent(obj.historyData.id); 
    } catch (e) { 
     console.log(e); 
    } 
}); 

history.back()事件绑定到自定义按钮,链接或其他东西。 我用.preventDefault()因为我的按钮是一个链接。

// click back arrow -> history 
this.back.on("click", function (ev) { 
    ev.preventDefault(); 
    window.history.back(); 
}); 

当历史弹回到 - >检查推动状态,除非这是第一次尝试

$(window).on("popstate", function (ev) { 
    var originalState = ev.originalEvent.state || obj.historyData; 
    if (!originalState) { 
     // no history, hide the back button or something 
     this.back.fadeOut(); 
     return; 
    } else { 
     // do something 
     this.showContent(obj.historyData.id); 
    } 
}); 

使用对象文本作为参数是很方便的通过您的ID。然后你可以使用一个功能showContent(id)

无论我在哪里使用this它只不过是一个jQuery对象/函数,存储在IIFE内。

请注意,我将这些脚本放在一起,从我的实现中结合来自您最初请求的一些想法。所以希望这给你一些新的想法;)

+0

感谢这个详细的解释。通过pushState()的对象文字是一个更好的解决方案。 –

相关问题