当用户使用HTML5 popstate处理程序在浏览器历史记录中导航回来时,我正在尝试检索滚动位置.
这是我有的:
$(document).ready(function () {
$(window).on('popstate', PopStateHandler);
$('#link').click(function (e) {
var stateData = {
path: window.location.href,
scrollTop: $(window).scrollTop()
};
window.history.pushState(stateData, 'title', 'page2.html');
e.preventDefault();
});
});
function PopStateHandler(e) {
alert('pop state fired');
var stateData = e.originalEvent.state;
if (stateData) {
//Get values:
alert('path: ' + stateData.path);
alert('scrollTop: ' + stateData.scrollTop);
}
}
<a id="link" href="page2.html"></a>
Run Code Online (Sandbox Code Playgroud)
当我向后导航时,我无法检索stateData的值.
我认为这是因为popstate正在检索初始页面加载的值,而不是单击超链接时我推送到历史记录的状态.
我怎么能在导航回来时获得滚动位置?
我正在使用历史API将新URL推送到网页而不重新加载它.我有多个按钮,都有不同的功能.
我的脚本现在几乎没有问题.当我按下按钮时会发生一些事情,当我返回时,脚本会触发事件监听器而不重新加载页面.
但是,当我现在按下前进按钮时,我想继续前进.URL已正确更改为下一个,但事件侦听器仍然会像按下后退按钮一样触发
例:
index1.htmlindex2.htmlindex3.htmlindex2.htmlindex3.html,但内容是index1.html我想这是因为我有一个监听器,它会监听popstate后退按钮和按下前进按钮的情况.如何区分按下哪种按钮?
这是绑定侦听器的部分:
if (window.history && window.history.pushState) {
$(window).unbind('popstate');
$(window).bind('popstate', function (e) {
clearOverlays();
var url = URL
$.ajax ( {
url : url
}).done ( function ( data ) {
console.log(data);
});
});
}
Run Code Online (Sandbox Code Playgroud) 我目前正在使用Nginx作为反向代理并为我的静态资产提供服务.我使用的是React Router的HashLocation设置,因为它是默认设置,它允许我刷新路由而没有任何问题,也不需要任何其他配置,但使用该设置的问题是url有/#/ prepending的必要性我的路线(例如http://example-app.com/#/signup).
我现在正在尝试切换到React Router的HistoryLocation设置,但我无法弄清楚如何正确配置Nginx以便为所有路由提供index.html(例如http://example-app.com/signup).
这是我最初的nginx设置(不包括我的mime.types文件):
nginx.conf
# The maximum number of connections for Nginx is calculated by:
# max_clients = worker_processes * worker_connections
worker_processes auto;
# Process needs to run in foreground within container
daemon off;
events {
worker_connections 1024;
}
http {
# Hide nginx version information.
server_tokens off;
# Define the MIME types for files.
include /etc/nginx/mime.types;
# Update charset_types due to updated mime.types
charset_types
text/xml
text/plain
text/vnd.wap.wml
application/x-javascript
application/rss+xml
text/css
application/javascript
application/json; …Run Code Online (Sandbox Code Playgroud) 的第二个参数History.pushState,并History.replaceState可以用来设置的历史记录条目的"称号".
这意味着当用户点击第1页到第8页时,这是他应该在历史记录栏中看到的内容:

它正在开发Safari和Opera.
但在Chrome和FireFox上,这是用户看到的内容:

尝试更改document.title不起作用,因为它更改了历史标题中的所有条目:

什么是这个问题的最佳解决方案?
我们是否被迫只对所有使用和实现的页面使用一个历史标题?pushStatereplaceState
我在本地测试应用程序上实现了History.js. 一切似乎都有效,但是如果我按下浏览器中的后退按钮,之前的内容就无法恢复.
当用户按下后退按钮时,我是否真的必须再次手动加载内容(即进行另一个ajax调用)?然后github如何做到这一点?我看到他们在单击代码树中的后退按钮时不再进行另一个ajax调用.
这是我的代码:
History.Adapter.bind(window,'statechange',function()
{
var State = History.getState();
History.log(State.data, State.title, State.url);
});
$('a').each(function(index, link) {
if ($(link).attr('data-ajax-disabled') != 'true') {
$(link).click(function(event)
{
var clips = $(this).attr('data-ajax-clips') || '';
$.ajax($(this).attr('href'),
{
data: {_clips:clips},
success: function(data)
{
var data = $.parseJSON(data);
History.pushState({state:1}, data.title || document.title, 'http://127.0.0.1/site/www/');
$.each(data.clips, function(key, val)
{
$(key).replaceWith(val);
});
}
});
return false;
});
}
});
Run Code Online (Sandbox Code Playgroud)
data.clips是一个json数组,它包含作为键的html对象的id和作为值的实际html内容.例如
'#header'=>'标题div中的内容'
如上所述,更换工作正常.我在标题中输出一个随机数.链接上的每次点击都会在标题中吐出另一个随机数.但是,如果按下后退按钮,数字保持不变,只会恢复标题(也是随机数).
我有一个页面,其中有几个搜索/过滤按钮,当点击时,通过AJAX刷新下面列表的内容.
在这个过程中,我正在修改历史记录(通过pushstate),以便新的过滤页面可以添加书签,因此后退按钮可以正常工作.我也在听popstate事件,对Back做出反应.
我的代码看起来或多或少像这样:
window.addEventListener("popstate", function(ev) {
if (!window.history_ready) { return; } // Avoid the one time it runs on load
refreshFilter(window.location.href, true);
});
refreshFilter: function(newURL, backButtonPressed){
$.ajax({ url: newURL}).done( blah );
if (!backButtonPressed) {
window.history_ready = true;
history.pushState(null, null, newURL);
}
}
Run Code Online (Sandbox Code Playgroud)
除了一个奇怪的案例外,这种方法效果很好......
至少在最新的Chrome中
为什么会发生这种情况,我该如何避免呢?
我正在使用History API并使用push和pop状态.我想在某些情况下停止popstate事件,我只将哈希附加到URL.例如,在某些情况下单击锚点它会附加#到URL并且popstate立即被触发)我想避免所有场景#或者#somehasvalue附加到URL并阻止popstate触发.我正在使用查询参数维护URL,我没有任何需要#在URL中触发popstate事件的场景.
这是我的代码.
if (supportsHistoryApi()) {
window.onpopstate = function (event) {
var d = event.state || {state_param1: param1, state_param2: param2};
var pathName = window.location.pathname,
params = window.location.search;
loadData(event, pathName + params, d.state_param1, d.state_param2);
}
Run Code Online (Sandbox Code Playgroud) 我的Google-fu什么都没有.
当你这样做:
var stateObj = { state: "some state" };
history.pushState(stateObj, "page 2", "other.htm");
Run Code Online (Sandbox Code Playgroud)
是否有关联的窗口回调?
我知道有这个:
window.onpopstate = function() {
}
Run Code Online (Sandbox Code Playgroud)
当用户点击后退按钮时,这非常适合收听.但是,我想在任何时候听到URL的变化,我不知道该怎么做.
URL随时更改时是否存在全局回调?
当浏览AngularJS的开发人员指南时,我注意到当使用后退按钮导航回页面时,我不会回到上一个滚动位置.相反,我回到了顶端.由于开发人员指南是使用AngularJS构建的,我担心,当我使用AngularJS构建自己的Web应用程序时,如果他们有相同的体验,它会使我的用户烦恼.为什么会发生这种情况,如何解决?我是否需要以某种方式使用HTML5的历史记录API?
转到开发人员指南并亲自查看此行为:http://docs.angularjs.org/guide/directive
给出一个简单的组件:
export default class SearchForm extends Component {
constructor(props) {
super(props)
this.state = { query: '' }
}
onSubmit = (event) => {
event.preventDefault()
history.push(`/results/${this.state.query}`, { query: this.state.query })
}
render() {
return (
<form onSubmit={this.onSubmit}>
<input
type="text"
value={this.state.query}
onChange={event => this.setState({ query: event.target.value })}
/>
<button>Search</button>
</form>
)
}
}
Run Code Online (Sandbox Code Playgroud)
而且测试:
describe('SearchForm Component', () => {
it('should navigate to results/query when submitted', () => {
const wrapper = shallow(<SearchForm />)
...?
})
})
Run Code Online (Sandbox Code Playgroud)
如何验证表单提交是否将用户带到具有正确查询值的下一页?
我试过简单地模拟onSubmit处理程序并至少确认它已被调用,但这会导致安全性错误history.push.
const wrapper …Run Code Online (Sandbox Code Playgroud) html5-history ×10
javascript ×6
html5 ×5
reactjs ×2
angularjs ×1
back-button ×1
dom ×1
enzyme ×1
history.js ×1
html ×1
jestjs ×1
jquery ×1
nginx ×1
post ×1
pushstate ×1
react-router ×1
unit-testing ×1