当浏览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) 在不更改URL的情况下推送到历史记录和设置数据:
window.history.pushState({
stateName: "myStateName",
randomData: window.Math.random()
}, "myStateName", location.href);
Run Code Online (Sandbox Code Playgroud)
....然后通过按浏览器中的Back按钮来听pop事件并触发它:
window.onpopstate = function(event) {
console.log(event.state); //logs null
}
Run Code Online (Sandbox Code Playgroud)
您将在大多数情况下将null作为状态值而不是:
{
stateName: "myStateName",
randomData: 0.34234234234
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题,为什么会这样呢?
我们正在构建一个带有音频播放器的Drupal站点,该站点应该在您浏览页面时继续播放(类似于soundcloud).
目前我们正在<a>使用ajax 加载clicked 的网站并将html注入页面并使用history.js来操作该位置.
但是有一个主要的缺点:
由于新加载的页面上可能有不同的css和js,我们必须将当前脚本,样式和链接元素与ajax响应文本(丑陋的正则表达式)进行比较,并且只添加新的但不存在的元素.通过这样做,加载另一个页面一旦执行脚本就不会删除/删除/撤消.这可能会成为一个性能问题(反正是针对标记的正则表达式).
使用iframe可以解决这个问题和其他问题:
首次单击站点上的链接时,页面内容将替换为仅加载页面的iframe.音频播放器位于原始dom中,即在iframe之外.单击iframe内的链接可以在历史API中捕获并使用.
所以,虽然我从未想过我会这么认为:我认为使用iframe可能是更好的选择,不是吗?
PS:我的主要问题是我无法控制网站上的不同页面有不同的脚本,样式确实没问题.如果网站上只有一个巨大的静态js和css,我没有遇到任何问题.
更新
除了在iOS中,iframe解决方案工作正常.iframes就像地狱一样.不过,我认为我们将采用iframe解决方案.
我试图了解(v5)包和之间的区别,BrowserRouter以及Router对react-router-dom下面的示例有什么区别。
该文件说:
BrowserRouter A,使用HTML5历史记录API(pushState,replaceState和popstate事件)使UI与URL保持同步。
来源:https : //reacttraining.com/react-router/web/api/BrowserRouter
路由器 所有路由器组件的通用底层接口。通常,应用将使用高级路由器之一代替:BrowserRouter,HashRouter,MemoryRouter,NativeRouter,StaticRouter
来源:https : //reacttraining.com/react-router/web/api/Router
据我了解,我应该为HTML5浏览器应用程序使用BrowserRouter,到目前为止,我一直在这样做。
history.push(...)示例:
我正在尝试history.push('/myNewRoute')在一个大块内执行一个:
import history as './history';
...
export function someAsyncAction(input) {
return dispatch => {
fetch(`${API_URL}/someUrl`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({ input }),
}).then(() => {
history.push('/myNewRoute');
}).catch((err) => {
dispatch(setError(err));
})
};
};
Run Code Online (Sandbox Code Playgroud)
history 定义为此模块:
import { createBrowserHistory } from 'history';
export default createBrowserHistory();
Run Code Online (Sandbox Code Playgroud)
并且history还将传递到我的路由器: …
html5-history reactjs react-router react-thunk react-router-dom
如何设置URL参数History.pushState()以避免浏览器刷新?如果有一个不简单的JS解决方案,是否已经有一个流行的库或jQuery的内置函数?
这是一个相关的SO问题,其中接受的答案根据注释和我的测试实际上不起作用(它删除查询字符串而不是更新值):history.pushState()更改查询值
为了清楚起见,我指的是查询字符串中的URL参数:
http://google.com/page?name=don所以我们可以更改don为tim而不会导致重新加载.
这是我找到的一种可能的解决方案.但是我很担心使用只有2个粉丝的JS库:P
我有一个包含一些选择字段的页面.一旦用户更改了选择字段的值.使用所有选择字段的值作为状态对象创建新的历史对象:
$(".chosen-select-field").chosen().change(function() {
$(".chosen-select-field").each( function ( index ) {
parameterNames[index].value = $( this ).val();
});
history.pushState(parameterNames, '', newUrl);
});
Run Code Online (Sandbox Code Playgroud)
parameterNames是一个包含键和值的对象数组,例如
parameterNames.push({key:"name", value:"foobar"});
Run Code Online (Sandbox Code Playgroud)
当用户单击浏览器中的后退或前进按钮时,以下代码将恢复状态.它工作但行为意外.
例如,我更改了三个选择字段(创建三个历史记录条目).然后我回去 执行restoreState,相应地更改一个选择字段.但是浏览器本身仍然处于历史中的相同位置(无法前进,仍然有相同数量的反向历史条目).
然后我再次点击后退按钮.这次state-object与我点击的列表时间相同.浏览器会移回历史记录中的一个条目.
第三次单击后退按钮时,下一个选择字段已更改,但浏览器再次保持该状态,除非我第四次单击.
谁能解释我做错了什么?
var restoreState = function(event) {
event = event.originalEvent;
parameterNames = event.state;
$(".chosen-select-field").each( function ( index ) {
if ($( this ).val() != parameterNames[index].value){
$( this ).val(parameterNames[index].value).change();
$( this ).trigger('chosen:updated');
}
});
};
// Bind history events
$(window).bind("popstate",restoreState);
Run Code Online (Sandbox Code Playgroud) 我有window.history.replaceState(null, null, 'about');在main.js分别位于required/javascripts我的服务器上.
然后在about页面(位于/我的服务器上的(root)),我有一个window.history.replaceState(null, null, 'about:me');在此页面上使用的链接.一切正常,但当我点击另一个具有相同功能但链接about:girlfriend为URL的链接时,我收到此错误消息:
Uncaught SecurityError: Failed to execute 'pushState' on 'History': A history state object with URL 'about:girlfriend' cannot be created in a document with origin 'http://my.domain.com'.
我不知道为什么我的浏览器(Chrome的最新版本)认为我正在尝试使用此页面pushState而且我不知道为什么我收到此错误消息,无论我读了多少次.有人可以帮我解释一下吗?我不用History.js这个.
值得一提的是,如果我换成:别的东西,我就不会收到此错误信息,例如-或/.我想使用:因为/不工作(404 Page Not Found)并且-不适合 - 它更好用:.
Daniel F Pupius将问题描述为:
很多网站都错了,这真的很烦人.当用户使用浏览器的前进或后退按钮导航时,滚动位置应与上次在页面上的位置相同.这有时在Facebook上正常工作,但有时却没有.Google+似乎总是失去你的滚动位置.
因此,在浏览新页面时,已经有很多关于将滚动条重置到页面顶部的问题.Ember.js的Cookbook还展示了如何融入Route.activate:
export default Ember.Mixin.create({
activate: function() {
this._super();
window.scrollTo(0,0);
}
});
Run Code Online (Sandbox Code Playgroud)
然而,这只能解决问题的一半.当用户使用后退/前进按钮时,滚动位置将不会恢复,而只是重置.
有很多尝试解决这个问题,很多只是将滚动位置存储在Ember.Controller实例中,例如在本文中.然而,这只是部分解决方案.如果多次使用控制器,则仅保留单个滚动状态.
如何保留恢复旧滚动状态的默认浏览器实现?因此,如果Route.activate从html5历史状态更改触发,什么都不做?
在使用HashLocationStrategy时, 我可以通过手动更改浏览器地址栏中的地址来更改路由,而无需重新加载页面.即从导航mysite/#/home到mysite/#/profile
但是,如果我使用PathLocationStrategy(它是默认位置策略),当我尝试做同样的事情时,我有不需要的页面重新加载.即从导航mysite/home到mysite/profile
有可能解决这个问题吗?
我正在使用Angular 2.0.0-beta17
html5-history ×10
javascript ×3
jquery ×3
html5 ×2
reactjs ×2
ajax ×1
angular ×1
angularjs ×1
drupal ×1
ember.js ×1
enzyme ×1
iframe ×1
jestjs ×1
query-string ×1
react-router ×1
react-thunk ×1
scroll ×1
unit-testing ×1
url ×1