我想在React中下拉。单击按钮应打开子菜单。单击子菜单外部应该关闭它

时间:2015-11-26 13:43:24

标签: javascript coffeescript reactjs refluxjs

这是我现有的工作代码。除了如果我点击子菜单外部,当它打开时,子菜单保持打开状态,这样做的效果很好。

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: !@state.display_submenu
  select_admin: =>
    @_toggleSubmenu()
    actions.setUserRole('admin')
  select_user: =>
    @_toggleSubmenu()
    actions.setUserRole('user')

我希望在子菜单打开时单击子菜单外部,然后将其关闭。

我已经读过如何在React中执行此操作,并且我遇到了很多建议,说我应该使用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: !@state.display_submenu
  select_admin: =>
    actions.setUserRole('admin')
  select_user: =>
    actions.setUserRole('user')

但是onFocus:元素上有onBlur:button, 现在点击li中的任何一个都不会触发@select_admin@select_user它只会触发@_toggle_submenu并且点击似乎不会提示/冒泡到{下面的{1}}元素..

通过阅读React Event DocumentationThis Focus and hotkeys guide我可以看到事件应该消失,但对我来说,他们根本就没有。

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

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

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

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

解决此问题的方法(使用onFocus和onBlur)是重新排列HTML设置:

  • 确保您的主菜单项可以具有焦点(<button>已经正常)
  • 确保您的子菜单无法获得焦点(<li>可以)
  • 确保您的子菜单位于主菜单组件中(您需要更改此项)

这样,如果单击其中一个子项,则主菜单项不会失去焦点。

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