当前位置: 首页 > 知识库问答 >
问题:

React-ul with onBlur事件阻止onClick在li上触发

鲜于谦
2023-03-14

我创建了一个移动下拉菜单,可以根据状态切换打开和关闭。一旦它被打开,我希望用户能够通过点击ul之外的任何地方来关闭下拉列表。

我正在将ul上的tabIndex属性设置为0,这将给出ul“焦点”。我还向ul添加了一个onBlur事件,触发隐藏ul的状态更改(dropdown Expanded=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,然后只需在该div上添加一个onClick即可改变状态,但是我读到了关于堆栈溢出的tabIndex/focus解决方案,我真的很想让它工作。

下面是代码的更完整视图(下拉列表供用户选择他们的祖国,这将更新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>
        )
    }
}

共有3个答案

翟学文
2023-03-14

我刚刚遇到了一个面包屑链接数组,其中一个onBlur处理程序正在引起重新渲染,阻止链接点击工作。实际的问题是,反应每次都会重新生成链接元素,所以当它重新渲染时,它会从鼠标下交换链接,这导致浏览器忽略点击。

修复方法是将key属性添加到我的链接中,以便响应将重用相同的DOM元素。

<ol>
    {props.breadcrumbs.map(crumb => (
        <li key={crumb.url}>
            <Link to={crumb.url} >
                {crumb.label}
            </Link>
        </li>
    ))}
</ol>
蒲坚
2023-03-14

关键是onBlur正在触发重新渲染,这似乎会导致浏览器不执行onClick:https://github.com/facebook/react/issues/4210

但是,如果您检查onBlur事件,您可以找到有关正在发生的事情的一些信息,event.relatedTarget将被填充,并且您可以使用这些信息来检测onBlur是何时由onClick和chain触发的,无论您需要做什么。

唐照
2023-03-14

尝试使用onMouseDown而不是onClick。

 类似资料:
  • 问题内容: 我正在使用reactjs路由器中的Link组件,但无法使onClickevent运行。这是代码: 这是做这件事的方式还是另一种方式? 问题答案: 您以字符串形式传递,也意味着立即执行。 尝试

  • 我在我的应用程序中使用MutableLiveData进行基于事件的通信。我有单一活动两个片段架构。 在ViewModel的帮助下,我正在使用Fragment-1中的LiveData事件。但是,当我使用菜单栏用Fragment-2替换这个Fragment-1并最终返回Fragment-1时,LiveData的旧值再次被捕获。 如何避免这个问题?非常感谢任何帮助/建议!谢谢你。

  • 问题内容: 我正在使用哈希链接的事件将a 作为弹出窗口打开。但是 ,单击中键不会触发事件,而只会获取链接的属性值并将URL加载到新页面中。如何使用中键打开弹出窗口? 问题答案: beggs的答案是正确的,但是听起来您想阻止默认的中间点击操作。在这种情况下,请包括以下内容 preventDefault()将停止事件的默认操作。

  • 问题内容: 我有一个叫做React的组件,有很多子组件(另一个React组件)。我希望能够从内部对每个事件声明一个事件。我尝试执行以下操作: 不用说,我没有得到任何“点击!” 出现在我的控制台中 Chrome中的React检查器会指示事件已注册,并应使用上述功能体进行注册。 因此,我得出结论,我无法在实际标签上注册事件(不过,我不确定为什么会这样)。我如何才能实现这一目标呢? 问题答案: 这取决于

  • 本文向大家介绍在React中怎么阻止事件的默认行为?相关面试题,主要包含被问及在React中怎么阻止事件的默认行为?时的应答技巧和注意事项,需要的朋友参考一下 event.preventDefault();阻止浏览器默认行为, 例如标签不跳转 event.stopPropagation();阻止冒泡; 例如上级点击事件不生效

  • 问题内容: 我已经与React互动了几个月了,但是遇到了一些奇怪的事情。 在移动设备上根本不会触发点击事件: http://jsbin.com/morarewelu/1/edit?html,js,输出 http://jsbin.com/morarewelu/1/-在您的设备上检查 您可以看到该点击从未触发。在iPhone上进行测试。 这是预期的行为,还是仅仅是一个错误? 问题答案: React的G