[英]Add event listener to items inside flex container
我有一個 flex 容器,其中包含幾個將flex-grow
屬性設置為 1 和某個max-width
項目。
我想向項目組添加一個事件偵聽器,但如果事件位置位於 flex 容器的空白空間中,我不希望事件觸發。 例如,對於click
事件,我希望僅在單擊下圖的藍色區域時觸發該事件。
如果我將事件偵聽器添加到父容器,即使我單擊紫色,事件也會觸發。 如果我將事件偵聽器添加到子項,則當我單擊項的邊距時不會觸發該事件。 此外,對於onmouseenter
或onmouseleave
等事件,如果我將鼠標移到所有項目上,該事件會觸發 3 次,而我希望它只觸發一次。
這是當前場景的一個片段:
$(".flex-container").on("mouseenter", () => { $("#hidden").show(); }) $(".flex-container").on("mouseleave", () => { $("#hidden").hide(); }) $(".flex-item").on("mouseenter", () => { $("#hidden2").show(); }) $(".flex-item").on("mouseleave", () => { $("#hidden2").hide(); })
.flex-container { display: flex; align-items: center; justify-content: center; border: 1px solid black; margin: 5px; padding: 5px; }.item-container { display: flex; align-items: center; width: 100%; justify-content: center; }.flex-item { padding: 5px; margin: 10px; outline: 1px solid black; flex: 1 1 auto; height: 24px; max-width: 24px; display: flex; align-items: center; justify-content: center; } #hidden, #hidden2 { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="flex-container"> <div class="flex-item"> 1 </div> <div class="flex-item"> 2 </div> <div class="flex-item"> 3 </div> </div> <div id="hidden"> Flex Container Hovered </div> <div id="hidden2"> Flex Item Hovered </div>
添加一個額外的 flex 容器作為包裝器可以實現接近預期的效果,但項目的flex-grow
屬性的意圖沒有保留,如下所示。
項目不會增長到項目的max-width
以填滿外框。 以下是上述場景的一個片段:
$(".flex-container").on("mouseenter", () => { $("#hidden").show(); }) $(".flex-container").on("mouseleave", () => { $("#hidden").hide(); }) $(".flex-item").on("mouseenter", () => { $("#hidden2").show(); }) $(".flex-item").on("mouseleave", () => { $("#hidden2").hide(); }) $(".extra-wrapper").on("mouseenter", () => { $("#hidden3").show(); }) $(".extra-wrapper").on("mouseleave", () => { $("#hidden3").hide(); })
.flex-container { display: flex; align-items: center; justify-content: center; border: 1px solid black; margin: 5px; padding: 5px; }.extra-wrapper { display: flex; }.item-container { display: flex; align-items: center; width: 100%; justify-content: center; }.flex-item { padding: 5px; margin: 10px; outline: 1px solid black; flex: 1 1 auto; height: 24px; max-width: 24px; display: flex; align-items: center; justify-content: center; } #hidden, #hidden2, #hidden3 { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="flex-container"> <div class="extra-wrapper"> <div class="flex-item"> 1 </div> <div class="flex-item"> 2 </div> <div class="flex-item"> 3 </div> </div> </div> <div id="hidden"> Flex Container Hovered </div> <div id="hidden2"> Flex Item Hovered </div> <div id="hidden3"> Extra Wrapper Hovered </div>
當項目具有flex-grow
和max-width
屬性時,如何向 flex 容器中的項目添加事件偵聽器?
它之所以有效,是因為由於 margin 不計入mouseleave
和mouseenter
事件,所以我們在flex-item
和wrap
周圍使用了一個包裝器元素。 然后為包裝器分配填充,並將事件偵聽器附加到包裝器。
通過這種方式,您可以將margin
模擬為填充並使其與事件偵聽器一起使用。
基於@ourmandave 的建議答案,我提出了以下解決方案。
在這個解決方案中,我為每個flex-item
添加了一個偽元素,以便我可以在事件的“熱點”中包含元素的邊距,因為它們被稱為。 然后我使用了額外的邏輯來防止事件處理程序通過使用事件的相關目標重復觸發。 通過檢查 cursor曾經在mouseleave
或mouseenter
事件時的位置,可以防止在鼠標從一個彈性項目移動到另一個彈性項目時再次觸發事件處理程序。 該解決方案仍然保留了flex-grow
和max-width
的預期效果。
$(".flex-container").on("mouseenter", () => { $("#hidden").show(); }) $(".flex-container").on("mouseleave", () => { $("#hidden").hide(); }) $(".flex-item").on("mouseenter", (e) => { if (e.relatedTarget.className === "flex-item") return; console.log('mouseenter fired'); $("#hidden2").show(); }) $(".flex-item").on("mouseleave", (e) => { if (e.relatedTarget.className === "flex-item") return; console.log('mouseleave fired'); $("#hidden2").hide(); })
.flex-container { display: flex; align-items: center; justify-content: center; border: 1px solid black; margin: 5px; padding: 5px; }.item-container { display: flex; align-items: center; width: 100%; justify-content: center; }.flex-item { padding: 5px; margin: 10px; outline: 1px solid black; flex: 1 1 auto; height: 24px; max-width: 24px; display: flex; align-items: center; justify-content: center; position: relative; }.flex-item::before { content: ''; position: absolute; inset: -10px -10px -10px -10px; } #hidden, #hidden2 { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="flex-container"> <div class="flex-item"> 1 </div> <div class="flex-item"> 2 </div> <div class="flex-item"> 3 </div> </div> <div id="hidden"> Flex Container Hovered </div> <div id="hidden2"> Flex Item Hovered </div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.