如何防止触发onBlur事件?

5

我正在尝试构建一个具有下拉框提供建议的输入框。我有一个使用 onBlur 的输入元素,当点击外部时,它会移除 ul 元素。当我点击 ul 元素时,它也会移除 ul 元素,这将触发输入框的 onBlur 事件。是否有一种方式可以实现 onBlur,以防止 ul 元素触发 onBlur 事件?

Note: 1. "input element" 翻译为 "输入元素" 2. "onBlur event" 翻译为 "onBlur 事件" 3. "ul element" 翻译为 "ul 元素" 4. "dropdown" 翻译为 "下拉框" 5. "suggestions" 翻译为 "建议"
import React, { useState, useEffect, useRef } from "react";

import "./styles.css";

const Autocomplete = (props) => {
  const [userInput, setUserInput] = useState("");

  const [listResults, setListResults] = useState([]);

  const [openModal, setOpenModal] = useState(false);

  useEffect(() => {
    const filteredResults = props.options.filter((option) =>
      option.includes(userInput)
    );

    setListResults(filteredResults);
  }, [userInput, props.options]);

  const handleInput = (event) => {
    setUserInput(event.target.value);
  };

  const handleInputClick = () => {
    setOpenModal(!openModal);
  };

  const handleClickOption = (data) => {
    setUserInput(data);
    setOpenModal(false);
    ulEl.current.focus();
  };

  return (
    <div className="container">
      <input
        name="search-input"
        value={userInput}
        onChange={handleInput}
        autoComplete="off"
        onFocus={handleInputClick}
        onBlur={handleInputClick}
      />
      <ul className="search-list">
        {openModal &&
          listResults &&
          listResults.map((data, key) => (
            <li
              key={key}
              onClick={() => {
                handleClickOption(data);
              }}
            >
              {data}
            </li>
          ))}
      </ul>
    </div>
  );
};

export default Autocomplete;

非常感谢您的帮助!

2个回答

13
简短回答,只需将此添加到您的元素中。
onMouseDown={(e) => e.preventDefault()}

在这种情况下,需要在 onMouseDown 事件上调用 event.preventDefault()。默认情况下,onMouseDown 会引起一个失去焦点事件, 当调用 preventDefault 后就不会触发失去焦点事件。接着,onClick 事件将有机会被调用。失去焦点事件仍然会发生,只是在 onClick 触发后才会发生。

非常好的答案。谢谢!我找到了另一种解决方案,可以将onClick函数改为onMouseDown,因为onBlur事件会在onMouseDown事件之后立即发生。 - Invisible_Q

-2
你可以使用 <datalist> 中的 list 属性,而不是使用 <ul>。希望这对你有帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接