当我在对
getmdl
这个网站中的
其中一个template
进行react化的时候,遇到了<a>标签href=“#xxx”的时候,会进行单页前端路由跳转的问题。
<div className="android-be-together-section mdl-typography--text-center">
<div className="logo-font android-slogan">be together. not the same.</div>
<div className="logo-font android-sub-slogan">welcome to android... be yourself. do your thing. see what's going on.</div>
<div className="logo-font android-create-character">
<a href=""><img src="images/andy.png" /> create your android character</a>
</div>
// 红色按钮
<a href="#screens">
<button className="android-fab mdl-button mdl-button--colored mdl-js-button mdl-button--fab mdl-js-ripple-effect">
<i className="material-icons">expand_more</i>
</button>
</a>
</div>
<div className="mdl-grid" style={{height: 800}}>
//需要跳转到的锚点
<a name="screens"></a>
跳到这里
<br />
跳到这里
<br />
跳到这里
<br />
跳到这里
<br />
跳到这里
<br />
跳到这里
<br />
跳到这里
<br />
</div>
这个需求的另一个用途就是back to top的实现。在google上搜索了半天,最后用到的方案是在react-router的githubissue页面中找到的。
// solugebefola提出的
scrollToAnchor: function () {
let anchorName = this.props.location.hash;
if (anchorName) {
anchorName = anchorName.replace("#","");
let anchorElement = document.getElementById(anchorName);
if(anchorElement) { anchorElement.scrollIntoView(); }
}
}
我对上面的方法进行了一个修改,大致的样子如下:
scrollToAnchor = (anchorName) => {
if (anchorName) {
let anchorElement = document.getElementById(anchorName);
if(anchorElement) { anchorElement.scrollIntoView(); }
}
}
主要的实现方法就是用到了html元素的的scrollIntoView。所以第一步就是用getElementById找个锚点,然后如果这个元素存在,那么调用它的scrollIntoView方法。
好了,现在让我们来修改第一部分的代码。
class HomeView extends Component {
scrollToAnchor = (anchorName) => {
if (anchorName) {
let anchorElement = document.getElementById(anchorName);
if(anchorElement) { anchorElement.scrollIntoView(); }
}
}
render() {
return (
<div>
<div className="android-be-together-section mdl-typography--text-center">
<div className="logo-font android-slogan">be together. not the same.</div>
<div className="logo-font android-sub-slogan">welcome to android... be yourself. do your thing. see what's going on.</div>
<div className="logo-font android-create-character">
<a href=""><img src="images/andy.png" /> create your android character</a>
</div>
<a onClick={()=>this.scrollToAnchor('screens')}>
<button className="android-fab mdl-button mdl-button--colored mdl-js-button mdl-button--fab mdl-js-ripple-effect">
<i className="material-icons">expand_more</i>
</button>
</a>
</div>
<div className="mdl-grid" style={{height: 800}}>
<a id="screens"></a>
跳到这里
<br />
跳到这里
<br />
跳到这里
<br />
跳到这里
<br />
跳到这里
<br />
跳到这里
<br />
跳到这里
<br />
</div>
</div>
);
}
}
export default HomeView;
上面修改后的代码,我们只需要关注两个a标签和一个箭头函数。
我们进行了两个修改:
1. 将锚点用传统的name属性,改成id属性。这样我们就可以用document.getElementById方法方便的查询查询到锚点。
2. 将原来的红色按钮的href属性去掉,然后添加一个onClick方法。onClick方法传入一个锚点的id,然后用下面的函数来找到锚点并跳转到锚点。
scrollToAnchor = (anchorName) => {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在,就跳转到锚点
if(anchorElement) { anchorElement.scrollIntoView(); }
}
}
这样,当我点击那个红色按钮后,就跳转到了锚点(<div className="mdl-grid" style={{height: 800}}>这个div标签对应的页面元素到了浏览器的最上面)。