问题描述
我目前正在学习 React,我发现了这个很酷的包:https://www.npmjs.com/package/react-single-page-navigation。
我开始使用它,一切都很顺利。然后我想让我的网络应用响应式,所以我为小屏幕构建了一个移动导航(简单的下拉菜单)。
首先,这个导航也有效!下拉菜单始终显示,我可以点击带有引用的按钮,然后通过平滑滚动导航到所需的部分。 由于下拉菜单的显示和隐藏功能,我添加了一个带有状态 menuVisible 的构造函数到移动导航组件和两个函数来处理点击“打开下拉菜单”按钮和点击除下拉项目之外的任何其他地方(标准下拉机制)。
这种机制运作良好,dropdwon 看起来不错。但是:导航不再起作用。相反,我总是在网络应用的第一部分上下“导航”一些像素。
这是工作的桌面导航组件:
import React,{Component} from 'react';
export default class DesktopNavigation extends Component {
render() {
return (
<nav className={this.props.sticky ? 'navbar navbar--sticky' : 'navbar'} id='mainNav'>
<div className='navbar--logo-holder'>
<img alt='logo' className='navbar--logo'/>
<h1 className={this.props.sticky ? 'navbar--logo-text-sticky' : 'navbar--logo-text'}>Booyar</h1>
</div>
<ul className='navbar--link'>
<div ref={this.props.refs.Home} onClick={() => this.props.goTo('Home')}>
<div className={(this.props.activeElement === 'Home' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Home
</div>
</div>
<div ref={this.props.refs.About} onClick={() => this.props.goTo('About')}>
<div className={(this.props.activeElement === 'About' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
About
</div>
</div>
<div ref={this.props.refs.Services} onClick={() => this.props.goTo('Services')}>
<div className={(this.props.activeElement === 'Services' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Services
</div>
</div>
<div ref={this.props.refs.Projects} onClick={() => this.props.goTo('Projects')}>
<div className={(this.props.activeElement === 'Projects' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Projects
</div>
</div>
<div ref={this.props.refs.Contact} onClick={() => this.props.goTo('Contact')}>
<div className={(this.props.activeElement === 'Contact' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Contact
</div>
</div>
</ul>
</nav>
);
}
}
以下是无法正常工作的移动导航组件:
import React,{Component} from 'react';
import DropdownMenu from "./dropdownMenu";
export default class MobileNavigation extends Component {
constructor(props) {
super(props);
this.state = {
sticky: this.props.sticky
}
}
callbackIssticky = (issticky) => {
this.setState({sticky: issticky})
}
render() {
return (
<nav className={this.state.sticky || this.props.sticky ? "mobile-navbar mobile-navbar-sticky" : "mobile-navbar"} id="mainNav">
<div className="mobile-navbar--logo-holder">
<img alt="logo" className="mobile-navbar--logo"/>
</div>
<DropdownMenu
refs={this.props.refs}
activeElement={this.props.activeElement}
goTo={this.props.goTo}
sticky={this.props.sticky}
callback={this.callbackIssticky}
/>
</nav>
);
}
}
import React,{Component} from 'react';
/**
* This class represents the dropdown menu in mobile view.
*/
export default class DropdownMenu extends Component {
constructor(props) {
super(props);
this.state = {
menuVisible: false
}
this.handleClick = this.handleClick.bind(this);
this.handleOutsideClick = this.handleOutsideClick.bind(this);
}
handleClick() {
if (!this.state.menuVisible) {
document.addEventListener('click',this.handleOutsideClick,false);
this.props.callback(true);
} else {
document.removeEventListener('click',false);
this.props.callback(false);
}
this.setState(stateBefore => ({
menuVisible: !stateBefore.menuVisible,}));
}
handleOutsideClick(event) {
if (this.node.contains(event.target)) {
return;
}
this.handleClick();
}
render() {
const items =
<div className={'dropdown-items'}>
<button
ref={this.props.refs.Home} onClick={() => this.props.goTo('Home')}
className={(this.props.activeElement === 'Home' ? "active-mobile-page " : "")}>
Home
</button>
<button
ref={this.props.refs.About} onClick={() => this.props.goTo('About')}
className={(this.props.activeElement === 'About' ? "active-mobile-page " : "")}>
About
</button>
<button
ref={this.props.refs.Services} onClick={() => this.props.goTo('Services')}
className={(this.props.activeElement === 'Services' ? "active-mobile-page " : "")}>
Services
</button>
<button
ref={this.props.refs.Projects} onClick={() => this.props.goTo('Projects')}
className={(this.props.activeElement === 'Projects' ? "active-mobile-page " : "")}>
Projects
</button>
<button
ref={this.props.refs.Contact} onClick={() => this.props.goTo('Contact')}
className={(this.props.activeElement === 'Contact' ? "active-mobile-page " : "")}>
Contact
</button>
</div>;
return (
<div className={'dropdown-menu' + (this.state.menuVisible ? ' dropdown-menu-open' : '')}
ref={node => this.node = node}>
<button className={'hamburger hamburger--elastic' + (this.state.menuVisible ? ' is-active' : '')} onClick={this.handleClick} type={'button'}>
<span className="hamburger-Box">
<span className={'hamburger-inner' + (this.state.menuVisible || this.props.sticky ? ' hamburger-inner-sticky' : '')}>
</span>
</span>
</button>
{this.state.menuVisible ? items : undefined}
</div>
);
}
}
当然,一切都由 <ScrollNavigation elements={{Home: {},About: {},Services: {},Projects: {},Contact: {}}}>...</ScrollNavigation>
包裹,如 react-single-page-navigation 文档中所述。
我决定是否使用 css 和以下类显示移动或桌面导航:
import React,{Component} from 'react';
import MobileNavigation from "./mobileNavigation";
import DesktopNavigation from "./desktopNavigation";
export default class Navigation extends Component {
render() {
return (
<div>
<MobileNavigation
refs={this.props.refs}
activeElement={this.props.activeElement}
goTo={this.props.goTo}
sticky={this.props.issticky}/>
<DesktopNavigation
refs={this.props.refs}
activeElement={this.props.activeElement}
goTo={this.props.goTo}
sticky={this.props.issticky}/>
</div>
);
}
}
我希望这是足够的信息。我不喜欢发布我的整个项目,但我认为这没有必要。桌面导航按预期工作。移动导航只是在主页部分导航毫米。我认为有一个基本的反应“东西”导致了我无法弄清楚的行为,因为当我取消对渲染方法(以及渲染方法中调用未注释的东西;) 之外的所有内容的注释时,移动导航可以工作.
如果您需要更多信息或有其他问题,请提问! :)
提前致谢,节日快乐!
马克西姆图斯
解决方法
好的,所以我的错误是将滚动导航 ref={this.props.refs.Home}
(等)的引用放在按钮上。我以某种方式误解了 instructions in the docs of react-single-page-navigation。 ref 道具就像“锚点”,因此滚动导航知道要滚动的位置。我将此引用添加到按钮本身,因此导航只是滚动到按钮的位置。
所以我只是从按钮中删除了它,现在一切正常(桌面导航也是如此,知道为什么它以前在那里工作,但出现同样的错误)。
<ul className='navbar--link'>
<div onClick={() => this.props.goTo('Home')}>
<div
className={(this.props.activeElement === 'Home' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Home
</div>
</div>
<div onClick={() => this.props.goTo('About')}>
<div
className={(this.props.activeElement === 'About' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
About
</div>
</div>
<div onClick={() => this.props.goTo('Services')}>
<div
className={(this.props.activeElement === 'Services' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Services
</div>
</div>
<div onClick={() => this.props.goTo('Projects')}>
<div
className={(this.props.activeElement === 'Projects' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Projects
</div>
</div>
<div onClick={() => this.props.goTo('Contact')}>
<div
className={(this.props.activeElement === 'Contact' ? 'active-page ' : '') + (this.props.sticky ? 'navbar--link-item-sticky' : 'navbar--link-item')}>
Contact
</div>
</div>
</ul>
现在,滚动导航的触发器仅定义 goTo 属性,而 ref 属性由我网站的部分定义。