我已经创建了一个移动的菜单,根据状态切换打开和关闭。一旦它打开,我希望用户能够通过点击ul外的任何地方关闭菜单。
我将ul上的tabIndex属性设置为0,这使ul具有“焦点”。我还向ul添加了一个onBlur事件,它触发隐藏ul的状态更改(dropdownExpanded = false)。
<ul tabIndex="0" onBlur={this.hideDropdownMenu}>
<li onClick={this.handlePageNavigation}>Page 1</li>
<li onClick={this.handlePageNavigation}>Page 2</li>
<li onClick={this.handlePageNavigation}>Page 3</li>
</ul>
字符串
然而,当我实现这个修复时,我在每个li元素上的onClick事件都无法触发。
我知道事件冒泡时发生了一些事情,但我不知道如何修复它。有人能帮忙吗?
注意事项:
我知道你可以在ul下面创建一个透明的div,它跨越整个视口,然后只需要添加一个onClick even到那个div就可以改变状态,但是我读到了这个tabIndex/focus解决方案on Stack Overflow,我真的很想让它工作。
以下是代码的更完整视图(用户可以选择自己的国家,这会更新ui):
const mapStateToProps = (state) => {
return {
lang: state.lang
}
}
const mapDispatchToProps = (dispatch) => {
return { actions: bindActionCreators({ changeLang }, dispatch) };
}
class Header extends Component {
constructor() {
super();
this.state = {
langListExpanded: false
}
this.handleLangChange = this.handleLangChange.bind(this);
this.toggleLangMenu = this.toggleLangMenu.bind(this);
this.hideLangMenu = this.hideLangMenu.bind(this);
}
toggleLangMenu (){
this.setState({
langListExpanded: !this.state.langListExpanded
});
}
hideLangMenu (){
this.setState({
langListExpanded: false
});
}
handleLangChange(e) {
let newLang = e.target.attributes['0'].value;
let urlSegment = window.location.pathname.substr(7);
// blast it to shared state
this.props.actions.changeLang( newLang );
// update browser route to change locale, but stay where they are at
browserHistory.push(`/${ newLang }/${ urlSegment }`);
//close dropdown menu
this.hideLangMenu();
}
compileAvailableLocales() {
let locales = availableLangs;
let selectedLang = this.props.lang;
let markup = _.map(locales, (loc) => {
let readableName = language[ selectedLang ].navigation.locales[ loc ];
return (
<li
key={ loc }
value={ loc }
onMouseDown={ this.handleLangChange }>
{ readableName }
</li>
);
});
return markup;
}
render() {
let localeMarkup = this.compileAvailableLocales();
return (
<section className="header row expanded">
< Navigation />
<section className="locale_selection">
<button
className="btn-locale"
onClick={this.toggleLangMenu}>
{this.props.lang}
</button>
<ul
className={this.state.langListExpanded ? "mobile_open" : " "}
value={ this.props.lang }
tabIndex="0"
onBlur={this.hideLangMenu}>
>
{ localeMarkup }
</ul>
</section>
</section>
)
}
}
型
5条答案
按热度按时间kqhtkvqz1#
尝试使用onMouseDown而不是onClick。
zzwlnbp82#
关键是onBlur正在触发重新渲染,这似乎会导致浏览器不跟进onClick:https://github.com/facebook/react/issues/4210
但是如果你检查onBlur事件,你可以找到一些关于发生了什么的信息,event.relatedTarget被填充,你可以使用这些信息来检测onBlur何时被onClick触发,并链接你需要做的任何事情。
qlzsbp2j3#
我刚刚在一个面包屑链接数组中遇到了这个问题,其中onBlur处理程序导致重新渲染,阻止链接点击工作。实际问题是react每次都会重新生成链接元素,所以当它重新渲染时,它会从鼠标下交换链接,这导致浏览器忽略点击。
修复方法是将
key
属性添加到我的链接中,以便react可以重用相同的DOM元素。字符串
krcsximq4#
我也遇到了这个问题。对我有效的是这个弗兰肯斯坦式的解决方案:
字符串
相当丑陋,但它的工作!希望它有助于其他一些可怜的灵魂困惑这一点。
i34xakig5#
我也有类似的问题,这里的建议都不太合适,所以我最终使用了
setTimeout
来稍微延迟blur
事件。在我的例子中,我使用的是一个输入组件,它在右边有一个可点击的“提交”按钮。只有当父对象被悬停在其中,和/或输入本身接收到焦点时,输入和按钮才会呈现。点击按钮会导致输入的
onBlur
触发,从而停止点击处理程序的运行。添加一个小的setTimeout
解决了这个问题。字符串