关闭其他下拉菜单点击在苗条



这是我使用的一个简单的下拉组件。

<script>
let show = false;
</script>
<div>
<button on:click={() => show = !show }>Show Dropdown</button>
{#if show}
<div>
<a href="/">Option 1</a>
<a href="/">Option 2</a>
<a href="/">Option 3</a>
<a href="/">Option 4</a>
</div>
{/if}
</div>
<style>
a { display: block; }
</style>

我在parent中使用了这个组件三次,如下所示:

<script>
import Dropdown from './dropdown.svelte';
</script>
<div>
<Dropdown />
<Dropdown />
<Dropdown />
</div>

一旦我点击第一个下拉菜单,其各自的下拉内容打开,但在点击下一个下拉菜单,我如何关闭以前的下拉菜单,只打开一个被点击?

谢谢

通常的方法是在顶部添加一个click事件处理程序,并以这种方式触发关闭。你只需要排除点击发生在下拉菜单内的情况。

<script>
let show = false;
let container;

function onWindowClick(e) {
if (container.contains(e.target) == false)
show = false;
}
</script>
<svelte:window on:click={onWindowClick} />
<div bind:this={container}>
<button on:click={() => show = !show }>Show Dropdown</button>
...
</div>

REPL

(通过svelte:window添加的事件处理程序将自动清除)

基于可访问性的原因,使用正确的元素是很重要的。链接应该是a元素,否则可点击的东西应该是button元素。这允许适当的键盘交互,并为屏幕阅读器提供语义。

理想情况下,元素也应该提供正确的ARIA属性(如role),适当的键盘交互,如向上/向下箭头导航,关闭Escape等应该实现。(请参阅指南。)

我从来没有接触过苗条,但我知道如何做到这一点。

您可以使用focusblur事件

您将tabindex="0"添加到元素中,每当您打开它时,您都会聚焦元素。现在,当你点击元素外部时,模糊事件就会被触发。如果你在浏览器外点击,它甚至会被触发。

<script>
import { tick } from 'svelte';
let show = false;
let dropdownElement;
async function showDropdown() {
show = !show;
//we need to wait with tick, until DOM nodes have mounted
await tick();
dropdownElement.focus()
}
</script>
<div>
<button  on:click={ showDropdown }>Show Dropdown</button>
{#if show}
<div  on:blur={() => show = false} tabindex="0" bind:this={dropdownElement}>
<div>Option1</div>
<div>Option2</div>
<div>Option3</div>
</div>
{/if}
</div>

我使用div而不是a标签,因为当您单击a标签时,父级将失去焦点。

最新更新