Loading...
qvor.vasilev avatar qvor.vasilev 23 Точки

Няколко падащи менюта с общ JS код

Здравейте колеги,

Оптивам се да направя малко приложение за информация, което се състои от разгъващи и свиващи се менюта. Болката е следната - нагласих HTML-a, CSS-a така, че JS-a така че да работи за 1 (едно) меню и сега ако искам да го направя за следващото, или трябва копирам + преименувам вече написания код за всяко следващо меню, или да намеря по-умен начин да се справя със задачката. Моля ако някой има представа къде точно бъркам и какво мога да подобря, да бъде така добър и да ме светне. Вижте какво съм написал до момента:

HTML:

         <ul>    
            <li class="dropdown first">
                <a href="#" id="menu" class="menu">Networking</a>
                <ul class="dropdown-content" id="menu-content">        
                    <li>
                        <a href="#">dasd 1</a>
                    </li>                              
                </ul>
            </li>

            <li class="dropdown first">
                <a href="#" id="menu1" class="menu">Cloud Print</a>
                <ul class="dropdown-content" id="menu-content1">        
                    <li>
                        <a href="#">dasd 1</a>
                    </li>           
                </ul>
            </li>
        </ul>

CSS: 

.dropdown-content{
    display: none;
    background-color: #f9f9f9;
    min-width: 160px;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.show {
    display:block;
}

JS:

// drop-down menu
function dropdwn(){
    var menu = document.getElementById("menu-content");
    menu.classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
  if (!e.target.matches('.menu')) {

    var dropdowns = document.getElementsByClassName("dropdown-content");
    for (var d = 0; d < dropdowns.length; d++) {
      var openDropdown = dropdowns[d];
      if (openDropdown.classList.contains('show')) {
        openDropdown.classList.remove('show');
      }
    }
  }
}
document.addEventListener('DOMContentLoaded', function () {
        document.getElementById('menu').addEventListener('click', dropdwn);
});

0
JavaScript Fundamentals
gartin avatar gartin 73 Точки
Best Answer

 

Здравей, колега,

Опитах с най-малко намеса и без да променям подхода да постигна ефекта, който си описал като желан.
Можеш да видиш по-долу снипет с промените.

Използвах клас селектор ( querySelectorAll(class) ) за да таргетирам менютата, тъй като id, може да има само едно, а класове много.
След като ги събрах в колекция, обходих с един цикъл всиките и им закачих по един eventListener. Самия listener, промених да прави toggle с класа show на съседния ul елемент.

Така би работило с този маркъп. Може да се преработи и да е още по-прагматично, но за случая на демото работи :)
За такива случаи често използвам Codrops, където има доста туториали - http://tympanus.net/codrops/tag/dropdown/

    // drop-down menu
    function dropdwn() {
        this.nextElementSibling.classList.toggle("show");
    }
    // Close the dropdown if the user clicks outside of it
    window.onclick = function (e) {
        if (!e.target.matches('.menu')) {
            var dropdowns = document.getElementsByClassName("dropdown-content");
            for (var d = 0; d < dropdowns.length; d++) {
                var openDropdown = dropdowns[d];
                if (openDropdown.classList.contains('show')) {
                    openDropdown.classList.remove('show');
                }
            }
        }
    };

    document.addEventListener('DOMContentLoaded', function () {
        var lists = document.querySelectorAll('.menu');
        
        for (var i = 0; i < lists.length; i++) {
            lists[i].addEventListener('click', dropdwn);
        }
    });
1
08/03/2016 12:25:40
qvor.vasilev avatar qvor.vasilev 23 Точки

Колега благодаря ти много за помощта! Аз в крайна сметка днес успях да направя това което исках и сам, но кодът ми е много "селкси" ако мога така да се изразя. Твоята идея определено е по-чиста и по-практична. Само едно не усях да разбера обаче - защо използваш "nextElementSibling" а не "element.children" или нещо от сорта?

Още веднъж благодаря за помощта и елегантното решение!

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.