2017-08-21 55 views
0

我有一个音频播放器,我希望当前URL始终指向当前播放的位置。所以我想我会用相同的密钥将新位置推送到路由器,告诉反应路由器它应该忽略散列更改。反应路由器:忽略hashchange

audioElement.addEventListener('timeupdate', (evt) => { 
    this.props.router.push({ 
     ...this.props.location, 
     hash: '#'+audioElement.currentTime 
    }); 
}); 

但是,随着音频​​回放,页面内容不断重新加载。我该如何防止路由器对hashchange事件做出反应?

我正在使用react router 3和redux。如果它做出改变,我愿意升级到v4版本,但它只是为了尝试而看起来太费劲了。

回答

1

您最好将'#'+audioElement.currentTime置于历史状态,因为更改散列总是会导致刷新(据我所知)。

audioElement.addEventListener('timeupdate', (evt) => { 
    this.props.router.push({ 
     ...this.props.location, 
     state: { 
      ...this.props.location.state, 
      audioCurrentTime: '#'+audioElement.currentTime 
     } 
    }); 
}); 
+0

谢谢@炼狱。存在的问题是,当我进行推送时,URL变为'''''',页面中断。但它不刷新,所以我认为我们正在走上正轨。 :-) – Sixtease

+0

@Sixtease我编辑了答案,加了'... this.props.location' – Purgatory

+0

我应该早点看过这个:这不能完成这项工作,因为它不会更改地址栏中的URL,所以复制粘贴URL的目的将指向当前位置,这不能通过这个来完成...除非我错了。 :-) 我也试过应用路由器中间件,但似乎不可能从那里取消重新渲染,真的。 :-( – Sixtease

0

我通过修补react-router/lib/createTransitionManager.js得到它:

你可以像这样做。 有一个function listen,我增加了大约这样的:

if (state.location.path === location.path && state.location.hash !== location.hash) { 
    /* do nothing */ 
} 
else { 
    ... 
} 

UPDATE:对于反应路由器4,你不用修补代码,只猴子修补路由器:

import { Router } from 'react-router-dom'; 
let previousLocation; 
const routerSetState = Router.prototype.setState; 
Router.prototype.setState = function(...args) { 
    const loc = this.props.history.location; 
    if (loc.pathname === previousLocation.pathname && 
     loc.search === previousLocation.search && 
     loc.hash  !== previousLocation.hash 
    ) { 
     previousLocation = {...loc}; 
     return; 
    } 

    previousLocation = {...loc}; 
    return routerSetState.apply(this, args); 
}; 
const routerDidMount = Router.prototype.componentDidMount; 
Router.prototype.componentDidMount = function(...args) { 
    previousLocation = { 
     ...this.props.history.location, 
    }; 
    if (typeof routerDidMount === 'function') { 
     return routerDidMount.apply(this, args); 
    } 
};