乐趣区

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"
import _ from "lodash"

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("");
}
if (!visible && val) {
setVisible(true);
}
阻止冒泡
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);
};

input 值扭转时
const handleChange = (e) => {
setVal(e.target.value);

matchIndustry(e.target.value)
* var timeout = null;
return function() {
if(timeout !== null) clearTimeout(timeout);
timeout = setTimeout(()=>{
console.log(1111111111)
}, 2000);
} *

};

查问数据
const matchIndustry = (val) => {
console.log(222)
setSearchLoading(true);
let modelList = res.data.modelList
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 (
<div>
<Row gutter={20}>
<Col span={21}>
<div >
<input placeholder={placeholder} className={`${Style.searchInput} ${inputClass}`} type="text" ref={refInput} defaultValue={val} onChange={handleChange}
onClick={(event) => showInfoBox(event)} onKeyUp={handleKeyUp} onKeyDown={handleKeyDown} >
<div className={`${Style.searchList} ${infoBoxClass}`} style={{border: ((infoArr.length < 0 || !visible) ? "none" : "1px solid rgba(227, 237, 246, 1)") }}>
<Spin spinning={searchLoading}>
{searchLoading ? (<div className={`${Style.loadingBox} ${loadingBoxClass}`}><div>) : (visible ? (<ul>
{
infoArr.map((item, innerIndex) => {
return <li onClick={() => handleClick(item)} onMouseEnter={() => { showHeight(innerIndex) }} onMouseLeave={hideHeight} className={innerIndex === keyIndex ? Style.active : ""}
key={innerIndex}>{item}

<li>;
})
}<ul>) : "")}

<Spin>
<div>

<div>
<Col>

<Row>

<div>
);
}

export default SearchInput;

退出移动版