单击向下/向上键可在ul元素-React内部滚动

问题描述 投票:0回答:1

我在尝试使自己的自动完成组件反应时遇到问题。我创建了一个呈现结果的组件,并在其包装上设置max-height,我在输入元素上使用了onKeyDown事件来跟踪上/下键的按下。现在,我用它来标记活动项...但是当我设置的最大高度太小并且“活动项”超出div的高度限制时,在侧面有一个滚动条下去...我该如何解决?

import React, { useState, useEffect } from "react"

const Autocomplete = ({ options }) => {
  const [activeOption, setActiveOption] = useState(4)
  const [filteredOptions, setFilteredOptions] = useState([])
  const [showOptions, setShowOptions] = useState(false)
  const [userInput, setUserInput] = useState("")

  useEffect(() => {
    setShowOptions(userInput)
    setFilteredOptions([
      ...options.filter(
        option => option.toLowerCase().indexOf(userInput.toLowerCase()) > -1
      )
    ])
    setActiveOption(0)
  }, [userInput])

  const handleKeyDown = e => {
    if (e.key === "ArrowDown") {
      if (activeOption === filteredOptions.length - 1) return
      setActiveOption(activeOption + 1)
    }
    if (e.key === "ArrowUp") {
      if (activeOption === 0) return
      setActiveOption(activeOption - 1)
    }
  }

  return (
    <>
      <div className="search">
        <input
          type="text"
          className="search-box"
          value={userInput}
          onChange={e => setUserInput(e.target.value)}
          onKeyDown={handleKeyDown}
        />
        <ul className="options">
          {showOptions &&
            filteredOptions.map((option, i) => (
              <li className={activeOption === i ? `option-active` : ``} key={i}>
                {option}
              </li>
            ))}
        </ul>
      </div>
    </>
  )
}

export default Autocomplete

function App() {
  return (
    <div className="App">
      <Autocomplete
        options={[
          "Alligator",
          "Bask",
          "Crocodilian",
          "Death Roll",
          "Eggs",
          "Jaws",
          "Reptile",
          "Solitary",
          "Tail",
          "Wetlands"
        ]}
      />
    </div>
  )
}
.option-active {
  font-weight: bold;
  background: cornflowerblue;
}

.options {
  height: 100px;
  overflow: overlay;
}

下面的图片可以更好地说明我的问题:当第二项处于活动状态时:enter image description here

当第六个活动时:enter image description here

您可以看到滚动条保持不变,并且不会随着li元素而下降...衷心的感谢!

javascript reactjs autocomplete element
1个回答
0
投票
我认为您可以维护一个元素引用数组,以便在活动选项更改时调用该元素的scrollIntoView方法。

未经测试的代码:

// Use a ref container (we won't use `current`) const elmRefs = useRef() // Instead we build a custom ref object in each key of the ref for each option useEffect(() => { options.forEach(opt => elmRefs[opt] = {current: null} }, [options]) // Effect that scrolls active element when it changes useEffect(() => { // This is what makes element visible elmRefs[options[activeOption]].current.scrollIntoView() }, [options, activeOption]) // In the "render" section, connect each option to elmRefs <li className={activeOption === i ? `option-active` : ``} ref={elmRefs[option]} key={i}> {option} </li>

让我知道您的想法!
© www.soinside.com 2019 - 2024. All rights reserved.