2015-11-26 63 views
2

这是我现有的工作代码。这样做的效果很好,除了如果我点击子菜单之外,当它打开时,子菜单仍然打开。我想在React中做一个下拉菜单。点击一个按钮应打开一个子菜单。点击子菜单外应关闭它

class UserTypeDropdown extends React.Component 
    constructor: (props) -> 
    super(props) 
    @state = 
     display_submenu: false 
    @propTypes: 
    selected: React.PropTypes.string.isRequired 

    submenu_display:-> 
    if @state.display_submenu 
     'block' 
    else 
     'none' 
    button_class_names:-> 
    classNames(
     'select-btn ': true, 
     'user_role ': @props.selected is 'user', 
     'admin_role ': @props.selected is 'admin' 
     ) 

    selected_text:-> 
    if @props.selected == 'user' 
     'User' 
    else 
     'Administrator' 

    render:-> 
    div {className: 'user-type-dropdown'}, 
     button { className: @button_class_names(), onClick: @_toggleSubmenu }, 
     @selected_text() 
     ul {className: 'submenu submenu_content access_submenu', style: {display: @submenu_display()}}, 
     li {onClick: @select_admin}, 
      a {}, 
      'Administrator' 
     li {onClick: @select_user}, 
      a {}, 
      'User' 
    _toggleSubmenu: => 
    @setState display_submenu: [email protected]_submenu 
    select_admin: => 
    @_toggleSubmenu() 
    actions.setUserRole('admin') 
    select_user: => 
    @_toggleSubmenu() 
    actions.setUserRole('user') 

我想在子菜单打开之后实现该点击,关闭它。

我读到如何做到这一点的反应,我遇到了很多的建议,说因为这意味着降我应该使用的onfocus和的onblur代替的onClick

这对我来说很有意义只有当它在浏览器中处于焦点时,它才能打开。所以我的渲染函数&成为。

render:-> 
    div {className: 'user-type-dropdown'}, 
     button { className: @button_class_names(), onFocus: @_toggleSubmenu, onBlur: @_toggleSubmenu }, 
     @selected_text() 
     ul {className: 'submenu submenu_content access_submenu', style: {display: @submenu_display()}}, 
     li {onClick: @select_admin}, 
      a {}, 
      'Administrator' 
     li {onClick: @select_user}, 
      a {}, 
      'User' 
    _toggleSubmenu: => 
    @setState display_submenu: [email protected]_submenu 
    select_admin: => 
    actions.setUserRole('admin') 
    select_user: => 
    actions.setUserRole('user') 

然而,随着onFocus:onBlur:button元素, 现在按下其中一个li的的不会触发@select_admin@select_user它只是触发@_toggle_submenu和点击似乎并不propigate /泡到li下面的元素..

从阅读React Event DocumentationThis Focus and hotkeys guide我可以看到,事件应该泡沫下来,但对我而言,他们根本不是。

我是新来的React Coffescript/JS世界,所以原谅任何不正确的命名约定。

我认为我的理解必须是有缺陷的,因为我无法在这个问题的任何地方找到答案。

任何帮助将不胜感激。

回答

2

你的问题是:只要你点击一个项目,onBlur事件首先触发。这会导致重新渲染(因为你做了setState)。因此,您的onClick事件永远不会运行。

解决这个(用的onfocus和的onblur)的方式,是重新排列你的HTML设置:

  • 确保你的主菜单中的项目可以有焦点(<button>已经是OK)
  • 确保您的子菜单不能有焦点(<li>是OK)
  • 确保你子菜单内,您的主菜单组件(你需要改变这种)

那如果您点击其中一个子项目,您的主菜单项目不会失去焦点。

你可以找到一个简单的(仅HTML和javascript)JSBIN example here

+0

这非常有道理。 我继承了我们以前的非反应设计的html结构,从来没有想过要改变它。 我会在明天更新结构,让你知道我如何继续!谢谢:) –

+0

这工作完美,非常感谢你@wintvelt! –

相关问题