Así que tengo esta barra de búsqueda, que cuando el usuario escribe cualquier letra que ha estado contenida en cualquiera de mis artículos, aparece el div y muestra los artículos relacionados, pero luego, a menos que retroceda, por supuesto permanece allí, así que me gustaría que desaparece después de hacer clic en otro lugar. Mi proyecto está en React , por lo que encontré muchas soluciones en Vanilla JS, pero ninguna de ellas parece funcionar, al menos en mi proyecto
.autocom-box { position: absolute; right: 57vw; margin-top: 1vh; z-index: 9; color: white; background-color: rgb(41, 57, 85); width: 25vw; } .autocom-box li { width: 100%; list-style: none; display: flex; cursor: pointer; } .autocom-box li :hover { background-color: rgb(64, 89, 133) } .autocom-box li { height: 8vh; color: white; text-decoration: none; /*removes underline*/ width: 75%; font-size: 12px; text-align: center; padding-top: 3vh; } <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> export default function Header(){ const [articles,setArticles] = useState([]) const [search,setSearch] = useState('') const [searchResults,setSearchResults] = useState([]) useEffect(()=>{ const results = articles.filter((article) => ((article.title).toLowerCase()).includes(search.toLowerCase())); setSearchResults(results); },[articles,search]) const autocom = document.getElementById('autocom-box') const hideOnClickOutside = (e) =>{ if (e.composedPath().includes(autocom)) { alert('click insdide') }else{ alert('click outside') } } return( <div className="search"> <form onSubmit={(e)=>{e.preventDefault();}}> <input type="text" id="input" name="input" autoComplete='off' placeholder="Αναζήτηση..." value = {search} onChange={(e)=>{setSearch(e.target.value)}}/> </form> </div> <div className="autocom-box" id="autocom-box" > <ul onClick={hideOnClickOutside}> {searchResults.map( (item,index)=>{ if (search.length>0){ return (<li> {item.title}</li>) } })} </ul> </div> )¿Te ayuda esta respuesta ?
const outsideClickListener = event => { const deltaX = event.offsetX - lastMouseDownX; const deltaY = event.offsetY - lastMouseDownY; const distSq = (deltaX * deltaX) + (deltaY * deltaY); const isDrag = distSq > 3; const isDragException = isDrag && !lastMouseDownWasOutside; if (!element.contains(event.target) && isVisible(element) && !isDragException) { // or use: event.target.closest(selector) === null element.style.display = 'none'; removeClickListener(); document.removeEventListener('mousedown', mouseDownListener); // Or add this line to removeClickListener() } }Salud
Puede usar este enlace personalizado para ejecutar la función de devolución de llamada cuando hace clic fuera del elemento de destino.
Código con javascript
import { useEffect } from "react"; /** * Hook that alerts clicks outside of the passed ref */ export default (ref, callbackFunc) => { useEffect(() => { /** * Alert if clicked on outside of element */ function handleClickOutside({ target }) { if (ref.current && !ref.current.contains(target)) { callbackFunc() } } // Bind the event listener document.addEventListener("mousedown", handleClickOutside); return () => { // Unbind the event listener on clean up document.removeEventListener("mousedown", handleClickOutside); }; }, [ref]); }Código con mecanografiado
import { useEffect, RefObject } from "react"; /** * Hook that alerts clicks outside of the passed ref */ export default (ref: RefObject<HTMLElement>, callbackFunc: Function) => { useEffect(() => { /** * Alert if clicked on outside of element */ function handleClickOutside({ target }: MouseEvent) { if (ref.current && !ref.current.contains(target as Node)) { callbackFunc() } } // Bind the event listener document.addEventListener("mousedown", handleClickOutside); return () => { // Unbind the event listener on clean up document.removeEventListener("mousedown", handleClickOutside); }; }, [ref]); }El gancho acepta dos parámetros.
Por favor revise este ejemplo.