簡體   English   中英

點擊事件監聽器不會改變高度

[英]event listener on click does not change height

我想要構建的是:我有兩個 div,里面有兩個 div。 最初,內部 div 的高度為 0。 我已將事件偵聽器添加到外部 div,當我單擊 div 時,內部的高度變為 50px。 此外,我已將事件偵聽器添加到內部 div,當我單擊時,我希望內部潛水的高度再次變為 0,但它不起作用。 每個其他 css 屬性(如寬度或顏色)都有效。 下面是代碼。

 const mainContainer = document.querySelectorAll(".mainContainer"); const subMenu = document.querySelectorAll(".subMenu"); mainContainer.forEach(function(element, index) { element.addEventListener("click", function() { subMenu[index].style.height = "50px"; }) }) subMenu.forEach(function(element, index) { element.addEventListener("click", function() { this.style.height = "10px"; }) })
 * { margin: 0; padding: 0; } #container { border: 1px solid red; width: 50%; } #mainContainer { border: 1px solid; position: relative; width: 100%; }.subMenu { position: absolute; overflow: hidden; width: 100%; height: 0px; background-color: green; top: 0; left: 0; transition: height 0.5s; }
 <div id="container"> <div class="mainContainer"> <p>this is the main box</p> <p>tha provides the main categories</p> <div class="subMenu"> <p>This is the sub menu</p> <p>Lets build it</p> <p>Yes we do</p> </div> </div> <div class="mainContainer"> <p>this is the main box</p> <p>tha provides the main categories</p> <div class="subMenu"> <p>This is the sub menu</p> <p>Lets build it</p> <p>Yes we do</p> </div> </div> </div>

問題是您已將兩個事件偵聽器附加到元素並且同時觸發,並且擴展的處理程序覆蓋了折疊的處理程序: 在此處輸入圖像描述

原因是每當您單擊子元素時,它會將單擊事件傳遞給父元素,這也會再次更改屬性。 您可以在子單擊 function 中使用 stopPropagation() 來停止單擊事件的傳播。 檢查下面的更新代碼。 https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation (感謝@Himanshu Budhiraja)的精彩解釋

您沒有提到預期的行為,我根據您設置的屬性假設您希望它展開和折疊。 使用內聯樣式控制樣式並不是最佳實踐。 最好添加或刪除 class,例如在這里,我添加了 class “.expanded”,我使用 classList 來打開和關閉它

 const mainContainer = document.querySelectorAll(".mainContainer"); const subMenu = document.querySelectorAll(".subMenu"); mainContainer.forEach(function(element, index) { element.addEventListener("click", function() { subMenu[index].classList.toggle("expanded"); }); });
 * { margin: 0; padding: 0; } #container { border: 1px solid red; width: 50%; } #mainContainer { border: 1px solid; position: relative; width: 100%; }.subMenu { position: absolute; overflow: hidden; width: 100%; height: 0px; background-color: green; top: 0; left: 0; transition: height 0.5s; }.expanded { height: 50px; }
 <div id="container"> <div class="mainContainer"> <p>this is the main box</p> <p>tha provides the main categories</p> <div class="subMenu"> <p>This is the sub menu</p> <p>Lets build it</p> <p>Yes we do</p> </div> </div> <div class="mainContainer"> <p>this is the main box</p> <p>tha provides the main categories</p> <div class="subMenu"> <p>This is the sub menu</p> <p>Lets build it</p> <p>Yes we do</p> </div> </div> </div>

看來,您無法折疊它。 原因是每當您單擊子元素時,它會將單擊事件傳遞給父元素,這也會再次更改屬性。 您可以在子單擊 function 中使用 stopPropagation() 來停止單擊事件的傳播。 檢查下面的更新代碼。

https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

還有一件事,mainContainer 和 subMenu 是類 (html),但在您的 CSS 代碼中,您將它們用作 id。

 const mainContainer = document.querySelectorAll(".mainContainer"); const subMenu = document.querySelectorAll(".subMenu"); mainContainer.forEach(function(element, index) { element.addEventListener("click", function() { subMenu[index].style.height = "50px"; }) }) subMenu.forEach(function(element, index) { element.addEventListener("click", function(e) { e.stopPropagation(); this.style.height = "10px"; }) })

我建議嘗試使用已經完成的東西,例如multi-level menu 這里有更多的例子 除此之外,嘗試使用max-width設置動畫並將高度設置為自動。

 const mainContainer = document.querySelectorAll(".mainContainer"); const subMenu = document.querySelectorAll(".subMenu"); mainContainer.forEach( function(element, index) { element.addEventListener("click", function() { subMenu[index].style.maxHeight = "100px"; }) }) subMenu.forEach( function(element, index) { element.addEventListener("click", function() { this.style.maxHeight = "100px"; }) })
 * { margin: 0; padding: 0; } #container { border: 1px solid red; width: 50%; } #mainContainer { border: 1px solid; position: relative; width: 100%; }.subMenu { overflow: hidden; width: 100%; height: auto; max-height:0; background-color: green; top: 0; left: 0; transition: max-height 0.5s; }
 <div id="container"> <div class="mainContainer"> <p>this is the main box</p> <p>tha provides the main categories</p> <div class="subMenu"> <p>This is the sub menu</p> <p>Lets build it</p> <p>Yes we do</p> </div> </div> <div class="mainContainer"> <p>this is the main box</p> <p>tha provides the main categories</p> <div class="subMenu"> <p>This is the sub menu</p> <p>Lets build it</p> <p>Yes we do</p> </div> </div> </div>

這里有兩個真正的關鍵:

使用max-height而不是height以允許內容的height計算為auto ,然后max-height充當對height的潛在覆蓋。

在子菜單中,您必須阻止click事件冒泡,因為如果冒泡,它將到達主菜單,該click事件將觸發並導致沖突。

您也不應該使用相對或絕對定位來完成這項工作。

請參閱下面的其他內聯評論:

 const mainContainer = document.querySelectorAll(".mainContainer"); const subMenu = document.querySelectorAll(".subMenu"); mainContainer.forEach( function(element) { element.addEventListener("click", function() { // Simpler to find the child element within the parent // than to rely on idexes. Also, easier to work with // CSS classes than inline styles. this.querySelector(".subMenu").classList.toggle("open"); }) }) subMenu.forEach( function(element) { element.addEventListener("click", function(event) { // Since a sub-menu is a descendent of the mainContainer, // you have to stop the click event from bubbling up to the // ancestor otherwise it's click event will also trigger. event.stopPropagation(); // If someone clicks, it will be on a <p> withing // the sub menu, so you need to set the style on // the closest ancestor.submenu, not this. this.classList.toggle("open"); }) })
 * { margin: 0; padding: 0; } #container { border: 1px solid red; width: 50%; }.mainContainer { border: 1px solid; width: 100%; }.subMenu { overflow: hidden; max-height: 0px; background-color: green; transition: max-height 0.5s; }.open { max-height:50px; }
 <div id="container"> <div class="mainContainer"> <p>this is the main box</p> <p>tha provides the main categories</p> <div class="subMenu"> <p>This is the sub menu 1</p> <p>Lets build it</p> <p>Yes we do</p> </div> </div> <div class="mainContainer"> <p>this is the main box</p> <p>tha provides the main categories</p> <div class="subMenu"> <p>This is the sub menu 2</p> <p>Lets build it</p> <p>Yes we do</p> </div> </div> </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM