Форум программистов, компьютерный форум, киберфорум
React/ReactJS
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
69 / 61 / 11
Регистрация: 08.04.2019
Сообщений: 117

При клике на img, меню сначала убирается, потом появляется обратно

02.11.2023, 23:44. Показов 762. Ответов 0

Студворк — интернет-сервис помощи студентам
Всем привет! Пишу что-то типа dropdown menu: хочу, чтобы при клике на img у меня убиралось меню, если оно есть, и появлялось, если его нет, а также при клике, где-то не в зоне самого меню, оно исчезало.

Для этого я нашел кастомный хук, который вроде как на бумаге отрабатывает:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
const useClickOutside = (ref, callback) => {
    const handleClick = (e) => {
 
        if (ref.current && !ref.current.contains(e.target)) {
            callback()
        }
    }
 
    useEffect(() => {
        document.addEventListener("mousedown", handleClick)
        return () => document.removeEventListener("mousedown", handleClick)
    });
};
Но при попытке использовать его в компоненте появляется поведение, описаное в заголовке этого вопроса: клик вне меню срабатывает как ожидается, но клик на img, увы, нет:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const Header = () => {
    const [isAccMenuOpen, setIsAccMenuOpen] = useState(false);
    const modalRef = useRef(null);
 
    useClickOutside(modalRef, () => {
        setIsAccMenuOpen(false)
    })
 
    const rootClasses = [s.acc_menu_modal]
 
    if (isAccMenuOpen) {
        rootClasses.push('active');
    }
 
    return (
        <div className={styles.header}>
            <NavLink className={styles.logo} to='/'>TestTest</NavLink>
 
            <div className={styles.account_settings}>
                <img onClick={() => setIsAccMenuOpen(!isAccMenuOpen)} className={styles.account_icon}
                     src={default_user_logo} alt="user"/>
 
                <div ref={modalRef} className={rootClasses.join(' ')}>
                    Test
                </div>
 
            </div>
        </div>
    );
};
Я понимаю, что mousedown срабатывает раньше, чем click, поэтому сначала отрабатывает его поведение, а затем click возвращает все обратно. Даже был придуман костыль типа:
JavaScript
1
if (isAccMenuOpen) setTimeout(() => setIsAccMenuOpen(false), 150)
но эту задержку видно, а при меньшем таймауте опять появляется это нехорошее поведение.

Если есть идеи, как это можно исправить, помогите, пожалуйста

Добавлено через 3 часа 27 минут
Всем спасибо, все свободны!)
Достаточно было просто назначить чуть точнее границы, за которыми при клике меню должно скрываться: т.к. ref был назначен на уровне с img, img считался обьектом за менюшкой, а значит должен скрываться, но onclick у img не позволял этого сделать; значит, надо ref поставить на уровень выше, чтобы и onclick корректно отрабатывал, и mousedown работал:

JavaScript
1
2
3
4
5
6
7
8
<div ref={modalRef} className={styles.account_settings}>
       <img onClick={() => setIsAccMenuOpen(!isAccMenuOpen)} className={styles.account_icon}
                src={default_user_logo} alt="user"/>
 
        <div className={rootClasses.join(' ')}>
             Test
        </div>
</div>
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.11.2023, 23:44
Ответы с готовыми решениями:

Сдвигающееся вниз меню при клике. Как закрывать уже открытое меню при клике на другой пункт?
Добрый вечер. Есть меню Структура HTML: &lt;nav class=&quot;navbar navbar-inverse&quot; role=&quot;navigation&quot;&gt; &lt;!-- Brand and...

Сначала интернет быстрый, потом постепенно падает и не встает обратно
Люди добрые и умные, помогите пожалуйста! Мучаюсь уже на протяжении 3+ месяцев. Когда подключаюсь к интернету, изначально скорость такая,...

Во второй массив сначала переписать сначала положительные, потом 0, потом отрицательные
Не могу решить задачу, прямо застрял на ней. Помогите, пожалуйста. Нужно: заполнить массив из 10 элементов положительными и...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.11.2023, 23:44
Помогаю со студенческими работами здесь

При нажатии на кнопку появляется и убирается текст JS CSS
Добрый вечер! При нажатии на кнопку у меня появляется текст, при нажатии на вторую кнопку - текст появляется ниже первого. Подскажите,...

Не могу разобраться с сортировкой даты в Stringgrid, чтобы при вводе дд.мм.гггг сначала смотрело на год, потом на месяц, потом на день
Добрый вечер. Не могу разобраться с сортировкой даты в Stringgrid, чтобы при вводе дд.мм.гггг сначала смотрело на год, потом на месяц,...

При прокрутке вниз блок убирается а если прокрутить вверх то появляется
Вот на сайте http://samsonos.com шапка так организована как сделать что б убиралась шапка если прокрутка вниз но появлялась если прокрутка...

Упорядочить вектор так, что бы сначала шли числа кратные 3, потом с остатком 2 при делении на 3, потом с остатком 1.
Вектор длины N нужно заполнить случайными целыми числами(от X до Y) и сделать, чтобы сначала шли числа кратные 3, потом с остатком 2 при...

Работа с меню. При клике на кнопке меню или вне его, меню должно закрываться
Добрый вечер! Изучаю JQuery. Вот ради развития решил написать меню, практически такое же как на Хабре. Два дня ломаю голову над тем, как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru