React - Internet Explorer 11 输入在第一次 onchange 后失去焦点

Posted

技术标签:

【中文标题】React - Internet Explorer 11 输入在第一次 onchange 后失去焦点【英文标题】:React - Internet explorer 11 input loses focus after first onchange 【发布时间】:2019-05-15 18:37:58 【问题描述】:

我遇到了一个非常奇怪的问题,我无法解决。 我目前正在使用 react 16.3 和 Antd 3.11 框架使用 create-react-app 并创建了一个表,该表在其标题列内呈现一个附加了 onChange 事件的组件。

当我第一次关注输入时,问题就出现了。

我失去了对第一个关键事件的关注,然后当我再次单击该字段时,它一直保持焦点,直到我单击其他内容。

这是我一直在使用的示例: https://ant.design/components/table/

以及后面的代码。

import 
  Table, Input, Button, Icon,
 from 'antd';

const data = [
  key: '1',
  name: 'John Brown',
  age: 32,
  address: 'New York No. 1 Lake Park',
, 
  key: '2',
  name: 'Joe Black',
  age: 42,
  address: 'London No. 1 Lake Park',
, 
  key: '3',
  name: 'Jim Green',
  age: 32,
  address: 'Sidney No. 1 Lake Park',
, 
  key: '4',
  name: 'Jim Red',
  age: 32,
  address: 'London No. 2 Lake Park',
];

class App extends React.Component 
  state = 
    searchText: '',
  ;

  handleSearch = (selectedKeys, confirm) => () => 
    confirm();
    this.setState( searchText: selectedKeys[0] );
  

  handleReset = clearFilters => () => 
    clearFilters();
    this.setState( searchText: '' );
  

  render() 
    const columns = [
      title: 'Name',
      dataIndex: 'name',
      key: 'name',
      filterDropdown: (
        setSelectedKeys, selectedKeys, confirm, clearFilters,
      ) => (
        <div className="custom-filter-dropdown">
          <Input
            ref=ele => this.searchInput = ele
            placeholder="Search name"
            value=selectedKeys[0]
            onChange=e => setSelectedKeys(e.target.value ? [e.target.value] : [])
            onPressEnter=this.handleSearch(selectedKeys, confirm)
          />
          <Button type="primary" onClick=this.handleSearch(selectedKeys, confirm)>Search</Button>
          <Button onClick=this.handleReset(clearFilters)>Reset</Button>
        </div>
      ),
      filterIcon: filtered => <Icon type="smile-o" style= color: filtered ? '#108ee9' : '#aaa'  />,
      onFilter: (value, record) => record.name.toLowerCase().includes(value.toLowerCase()),
      onFilterDropdownVisibleChange: (visible) => 
        if (visible) 
          setTimeout(() => 
            this.searchInput.focus();
          );
        
      ,
      render: (text) => 
        const  searchText  = this.state;
        return searchText ? (
          <span>
            text.split(new RegExp(`($searchText)`, 'gi')).map((fragment, i) => (
              fragment.toLowerCase() === searchText.toLowerCase()
                ? <span key=i className="highlight">fragment</span> : fragment // eslint-disable-line
            ))
          </span>
        ) : text;
      ,
    , 
      title: 'Age',
      dataIndex: 'age',
      key: 'age',
    , 
      title: 'Address',
      dataIndex: 'address',
      key: 'address',
      filters: [
        text: 'London',
        value: 'London',
      , 
        text: 'New York',
        value: 'New York',
      ],
      onFilter: (value, record) => record.address.indexOf(value) === 0,
    ];
    return <Table columns=columns dataSource=data />;
  


ReactDOM.render(<App />, mountNode);

以及随之而来的 css:

.custom-filter-dropdown 
  padding: 8px;
  border-radius: 6px;
  background: #fff;
  box-shadow: 0 1px 6px rgba(0, 0, 0, .2);


.custom-filter-dropdown input 
  width: 130px;
  margin-right: 8px;


.custom-filter-dropdown button 
  margin-right: 8px;


.highlight 
  color: #f50;

快速总结一下我理解的内容。

表格重新呈现 filterDropDown 道具,filterIcon 在每个 击键。 表所在的类组件不会重新呈现或 触发器(componentDidUpdate) 这在 Chrome、FireFox、Edge 中完美运行,并且示例适用于 antds网站上的IE11。但不在我的应用中。 在我自己的组件中渲染的所有antd字段和常规字段在任何浏览器中都没有这个问题。 在渲染函数之外渲染输入组件不会 工作,因为它不是我的组件重新呈现它是触发它自己的更新事件的表组件 我还尝试将 -ms-user-select: 设置更改为不同的属性,以查看影响与否的天气。事实上,这只会让情况变得更糟。 我尝试将输入值设置为状态值以使其成为受控组件,但是当 componentDidUpdate 触发并且我以编程方式将 .focus 设置在我的输入上时,它会设置 caretIndex lenght-1 而不是文本后面。 (我手动尝试覆盖 selectionStart 和 SelectionEnd 但没有成功

我的想法有点用完了,因为我了解到其他一些组件正在窃取我输入框的焦点,但是即使我使用过,我也无法找到该元素 document.activeElement 在我能想到的几乎所有方法和生命周期事件中。所有事件都指向具有焦点的“a”输入字段(不确定这是旧的还是新创建的,但我认为它是旧的)。

我已尽力解释我的情况,我希望世界上有人遇到过类似的问题。

更新: antd 合理地改变了他们的表格组件,所以网页上的例子有点不同,但是问题仍然是一样的。

【问题讨论】:

我建议在CodeSandbox 中重新创建此问题,这样用户就可以自己重新创建问题。 CodeSandBox 无法在 Internet Explorer 中显示示例。浪费时间。 stackblitz、plnkr、repl 等呢 Phix 我会检查一下。谢谢大家的建议。 还是没有答案? 【参考方案1】:

我在 IE11 上也有同样的行为。

可以通过在 Input 字段上附加一个 onBlur 来修复它,只需将焦点设置到 currentTarget。

onBlurHandler = (e: React.FocusEvent<htmlInputElement>) => 
    e.currentTarget.focus();
;

【讨论】:

以上是关于React - Internet Explorer 11 输入在第一次 onchange 后失去焦点的主要内容,如果未能解决你的问题,请参考以下文章

React - Internet Explorer 11 输入在第一次 onchange 后失去焦点

React useRef 将平滑滚动添加到除 Internet Explorer 之外的所有浏览器都支持的 div

在 Internet Explorer 11 中通过 fetch-api 发布 FormData-object 时为空值

在同一台计算机上运行 Internet Explorer 6、Internet Explorer 7 和 Internet Explorer 8

对于某些情况,如 Internet Explorer 特定的 CSS 或 Internet Explorer 特定的 JavaScript 代码,如何仅针对 Internet Explorer 10?

如何从 Internet Explorer 11 降级到 Internet Explorer 10?