从自动完成内起React Material UI打开模式失去焦点 [英] React Material UI open modal from within autocomplete lose focus

查看:39
本文介绍了从自动完成内起React Material UI打开模式失去焦点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用material-ui lib,我需要具有一个自动完成功能,其中可以单击该自动完成功能中的每个项目并打开一个模式.

通常的结构是:

  const ModalBtn =()=>{...返回 (<><按钮...(在点击时将模式设置为打开)<模态...</>);}const AutoCompleteWithBtns =()=>{返回 (<自动完成renderTags = {(value,getTagProps)=>value.map((option,index)=>< ModalBtn/>)}.../>);} 

请注意,ModalBtn是不能分为Button和Modal两个组件的组件.

问题是,当您单击模式内的按钮时-焦点将保留在自动完成功能内,而模式将永远不会获得焦点(如果我在模式内有输入-我无法在其中输入任何内容).

尝试了所有与自动完成/模式焦点相关的标准道具( disableEnforceFocus disableEnforceFocus 等),但没有任何效果.

这是一个

解决方案

Autocomplete 内部呈现 Modal 的问题是事件从传播>模式自动完成.特别是,单击和鼠标按下事件均由 Autocomplete 处理,从而导致您遇到的问题.这主要是为了在您与自动完成的不同部分进行交互时将焦点保持在正确的位置.

下面(来自

相关答案:working codesandbox example. As you can see - if you click on the button that is not inside the autocomplete component - everything works (you can add text inside the input field). If you click on the button that is inside the autocomplete - the input field inside the modal is not editable (you lose focus).

Here is an example of the issue:

解决方案

The problem with having the Modal rendered from within the Autocomplete is that events propagate from the Modal to the Autocomplete. In particular, click and mouse-down events are both handled by Autocomplete in a manner that causes problems in your case. This is primarily logic intended to keep focus in the right place as you interact with different parts of the Autocomplete.

Below (from https://github.com/mui-org/material-ui/blob/v4.9.11/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js#L842) is the portion of the Autocomplete code that is getting in your way:

  // Prevent input blur when interacting with the combobox
  const handleMouseDown = (event) => {
    if (event.target.getAttribute('id') !== id) {
      event.preventDefault();
    }
  };

  // Focus the input when interacting with the combobox
  const handleClick = () => {
    inputRef.current.focus();

    if (
      selectOnFocus &&
      firstFocus.current &&
      inputRef.current.selectionEnd - inputRef.current.selectionStart === 0
    ) {
      inputRef.current.select();
    }

    firstFocus.current = false;
  };

The default browser behavior when a mouse down event occurs on a focusable element is for that element to receive focus, but the mouse-down handler for Autocomplete calls event.preventDefault() which prevents this default behavior and thus prevents a focus change from the mouse-down event (so focus stays on the Modal itself as indicated by its blue focus outline). You can however successfully move focus to the Modal's TextField using the tab key, since nothing is preventing that mechanism of focus change.

The Autocomplete click handler is keeping focus on the input of the Autocomplete even if you click some other part of the Autocomplete. When your Modal is open, the effect of this is that when you click in the Modal, focus is moved briefly to the Autocomplete input element, but the focus is immediately returned to the Modal due to its "enforce focus" functionality. If you add the disableEnforceFocus property to the Modal, you'll see that when you click in the Modal (e.g. on the TextField) the cursor remains in the input of the Autocomplete.

The fix is to make sure that these two events do NOT propagate beyond the Modal. By calling event.stopPropagation() for both the click and mouse-down events on the Modal, it prevents the Autocomplete functionality for these two events from being executed when these events occur within the Modal.

      <Modal
        onClick={event => event.stopPropagation()}
        onMouseDown={event => event.stopPropagation()}
        ...

Related answer: How can I create a clickable first option in Material UI Labs Autocomplete

这篇关于从自动完成内起React Material UI打开模式失去焦点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆