Я использую Alpine JS как часть проекта TALL. У меня есть навигационное меню, которое для целей Stackoverflow я сильно сжал до минимума. Одновременно может быть открыт только один раскрывающийся список, и внутри него могут быть ссылки на другие пункты меню. Все хорошо.
Часть, с которой я борюсь, заключается в том, что я хочу, чтобы все раскрывающиеся списки закрывались при щелчке вдали от текущего раскрывающегося списка, ну, вы знаете, вдали от открытого элемента div. Я все еще хочу иметь возможность переключать раскрывающийся список с помощью кнопки. Но не уверен, как добиться результата из открытого раскрывающегося списка.
Вот моя разметка
<nav x-data = "{ openDropdown: null }">
<div class = "mx-auto h-20 max-w-7xl px-2 sm:px-6 lg:px-8">
<ul>
<li x-data = "{ id: 'products' }">
<button x-on:click = "openDropdown = openDropdown === id ? null : id" type = "button" class = "inline-block text-white hover:text-secondary-200 px-3 py-2 text-base font-medium">
Products
</button>
<template x-if = "openDropdown === id">
<div>
...
</div>
</template>
</li>
<li>
<a href = "/" class = "inline-block text-white hover:text-secondary-200 px-3 py-2 text-base font-medium">
Integrations
</a>
</li>
<li x-data = "{ id: 'features' }">
<button x-on:click = "openDropdown = openDropdown === id ? null : id" type = "button" class = "inline-block text-white hover:text-secondary-200 px-3 py-2 text-base font-medium">
Features
</button>
<template x-if = "openDropdown === id">
<div>
...
</div>
</template>
</li>
</ul>
</div>
</nav>



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Простое решение — использовать событие click.outside, примененное к элементу <ul>:
<ul @click.outside = "openDropdown = null">
<li x-data = "{ id: 'products' }">
.....
но если вы хотите закрыть текущий раскрывающийся список также при нажатии на элементы без раскрывающегося списка, вы должны сбросить переменную openDropdown также при нажатии на них (если они не открывают другую страницу):
<li @click = "openDropdown=null">
<a href = "/" class = ".....">
Integrations
</a>
</li>
Вместо x-if вы можете использовать директиву x-show, применяемую к элементу для отображения/скрытия:
<li x-data = "{ id: 'products' }">
<button @click = "openDropdown = openDropdown === id ? null : id"
type = "button"
class = "....."
>
Products
</button>
<div x-show = "openDropdown === id">
.....
</div>
Да, вы правы, мой пример был простым, но вы молодцы, что прояснили ситуацию. x-cloak позволяет избежать мерцания элементов, которые будут скрыты x-show при рендеринге страницы.
Это сработало. Спасибо за это. Просто заметка о переключении на
x-show, которая нужна элементамx-cloak