react仿百度模糊搜索

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

import { Row, Col, Spin } from "antd";
import Style from "./index.module.scss";
import res from "./data.json"

function SearchInput(props) {
    const [keyIndex, setKeyIndex] = useState(-1);//提示框上下按键顺序
    const [val, setVal] = useState("");//输入框内容
    const [infoArr, setInfoArr] = useState([]);//提示框提示数组
    const [visible, setVisible] = useState(false);//提示框显示和隐藏

    const refInput = useRef();//输入框dom
    const [searchLoading, setSearchLoading] = useState(false);//提示框loading效果


    const { len = 5, placeholder = "请输入搜索内容", inputClass, infoBoxClass, loadingBoxClass } = props

    // 点击文档隐藏提示框
    useEffect(() => {
        document.addEventListener('click', hideInfoBox)
        return () => {
            document.removeEventListener('click', hideInfoBox)
        }
    });
    // 隐藏提示框
    const hideInfoBox = () => {
        setVisible(false);
    };

    // 显示提示框
    const showInfoBox = (e) => {
        if (!val) {
            matchIndustry("");
        } else {
            setVisible(true);
            matchIndustry(e.target.value);

        }
        // 阻止冒泡
        e.nativeEvent.stopImmediatePropagation();
    };

    // 键盘弹起
    const handleKeyUp = (e) => {
        const keyCode = e.keyCode;
        // 如果没有内容了,或者是回车键案件,则隐藏提示框
        if (!(e.target.value) && keyCode === 8) {
            hideInfoBox();
            return;
        }
        if (keyCode === 13 || keyCode === 108) {
            refInput.current.blur()
            hideInfoBox()
            return
        }
        if (visible && (keyCode === 38 || keyCode === 40)) {
            if (keyCode === 38) {
                let newIndex = keyIndex - 1;
                if (newIndex < 0) {
                    newIndex = infoArr.length - 1;
                }
                setKeyIndex(newIndex);
                e.target.value = infoArr[newIndex];
                setVal(infoArr[newIndex]);
            } else if (keyCode === 40) {
                let newIndex = keyIndex + 1;
                // console.log(newIndex)
                if (newIndex > infoArr.length - 1) {
                    newIndex = 0;
                }
                setKeyIndex(newIndex);
                e.target.value = infoArr[newIndex];
                setVal(infoArr[newIndex]);
            }
        }


    };
    // 键盘下按,阻止光标默认前置
    const handleKeyDown = (e) => {
        if (e.keyCode === 38) {
            e.preventDefault();
        }
    };
    // 点击确定 内容
    const handleClick = (item) => {
        refInput.current.blur();
        refInput.current.value = item;
        setVal(item);
    };

    // 焦点改变时
    const handleChange = (e) => {
        setVal(e.target.value);

    };

    // 节流
    const preventShake = (fn, value) => {
        let timer = null; // 创建定时器id
        return () => {
            clearTimeout(timer); // input事件频繁触发,清除之前定时器 
            timer = setTimeout(() => { // 创建新定时器,保证限定时间间隔fn只执行一次
                fn(value);
            }, 2000);
        };
    }
    // input输入时
    const input = (e) => {
        setVal(e.target.value);
        preventShake(matchIndustry, e.target.value)()

    }

    // 查询数据
    const matchIndustry = (val) => {
        setSearchLoading(true);
        let modelList = res.data.modelList
        modelList = modelList.filter(item => item.indexOf(val) >= 0)
        if (modelList.length > len) {
            modelList = modelList.slice(0, len);
        }
        if (modelList.length) {
            setVisible(true);
        } else {
            setVisible(false);
        }
        setSearchLoading(false);
        setInfoArr(modelList);
    }

    // hover 高亮
    const showHeight = (innerIndex) => {
        setKeyIndex(innerIndex)
    }
    // 离开隐藏高亮
    const hideHeight = () => {
        setKeyIndex(-1)
    }

    return (
        
showInfoBox(event)} onKeyUp={handleKeyUp} onKeyDown={handleKeyDown} />
{searchLoading ? (
) : (visible ? (
    { infoArr.map((item, innerIndex) => { return
  • handleClick(item)} onMouseEnter={() => { showHeight(innerIndex) }} onMouseLeave={hideHeight} className={innerIndex === keyIndex ? Style.active : ""} key={innerIndex}>{item}
  • ; }) }
) : "")}
); } export default SearchInput;

你可能感兴趣的:(前端,react.js)