Вложенные переключатели
Доброго дня уважаемые коллеги. Столкнулся с очень непростой проблемой, самостоятельно решить не могу.
Суть: у меня есть много выпадающих элементов, чтобы вручную не вешать обработчик на каждую кнопку сделал универсальную схему. Создал класс, который получаю в js и каждому из них вешаю обработчик. Схема такова: <div class="selfSwitcher">My Delivery 14780 <div class="dropDown"> <ul> <li>My Delivery 14780</li> <li>My Delivery 14780</li> <li>My Delivery 14780</li> </ul> </div> </div> <!-- может быть еще такой вид <div class="selfSwitcher"><span>My Delivery 14780</span> --> Сделал так, чтобы при нажатии на всплывающий элемент - он не закрывался. var allSelfSwitchers = Array.prototype.slice.call(document.querySelectorAll('.selfSwitcher')); var selfSwitchersCount = allSelfSwitchers.length; var makeSelfSwitcherHandler = function(selfSwitcher){ return function(event){ var event = fixEvent(event,this); var target = event.target; if(!target.classList.contains('selfSwitcher')){ if(target.classList.contains('dropDown') || target.parentNode.classList.contains('dropDown')) { return; } } selfSwitcher.classList.toggle('opened'); }; }; for(var counter = 0; counter<selfSwitchersCount; counter++){ var selfSwitcher = allSelfSwitchers[counter]; selfSwitcher.addEventListener('click',makeSelfSwitcherHandler(selfSwitcher)); }; Проблема в том, что теперь, нужно чтобы у меня был выпадающий элемент, в нем еще выпадающий элемент и в нем еще один. (Вот такая закрученная схема). т.е. <div class="selfSwitcher">My Delivery 14780 <div class="dropDown"> <ul> <li>My Delivery 14780</li> <li>My Delivery 14780</li> <li>My Delivery 14780 <div class="selfSwitcher">My Delivery 14780 <div class="dropDown"> <ul> <li>My Delivery 14780</li> <li>My Delivery 14780</li> <li>My Delivery 14780</li> </ul> </div> </div></li> </ul> </div> </div> event.stopPropagation не помогает. Не могу придумать как сделать так, чтобы элемент открылся, ему добавился класс и при клике на такой же ДОЧЕРНИЙ элемент, чтобы родитель не закрывался, а вложенный открылся и т.д. Я могу добавить условие в проверку конкретно под этот случай через фиксированную проверку родителей на 2-3 уровня. Но это не очень хорошо. Можно ли как-то это систематизировать? Думал подниматься по древу родителей и проверять наличие класса opened , если есть - ничего не производить (но тогда, дочерний элемент также не открывается :( ) Буду благодарен за любую помощь. |
Выпадающее меню на чистом js
Velidan,
<!DOCTYPE HTML> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> .selfSwitcher > .dropDown { display: none; } .opened > .dropDown { display: block; } .selfSwitcher { border: 1px red solid; } </style> </head> <body> <div class="selfSwitcher">My Delivery 14780 <div class="dropDown"> <ul> <li>My Delivery 14780</li> <li>My Delivery 14780</li> <li>My Delivery 14780 <div class="selfSwitcher">My Delivery 14780 <div class="dropDown"> <ul> <li>My Delivery 14780</li> <li>My Delivery 14780</li> <li>My Delivery 14780</li> </ul> </div> </div></li> </ul> </div> </div> <script> Array.prototype.forEach.call(document.querySelectorAll(".selfSwitcher"), function(element) { element.addEventListener("click", function(event) { event.target == this && this.classList.toggle("opened") }) });</script> </body> </html> |
Рони, в который раз спасибо Вам огромное за помощь.
Решил самостоятельно вот таким образом, правда, как-то очень топорно вышло, но я очень рад, что у меня хоть как-то получилось. function SwitcherHandleBuilder(elementsClass,parentMode){ var parentMode = parentMode || false; var className = elementsClass; var elementsCollection = Array.prototype.slice.call(document.getElementsByClassName(className)); var collectionCount = elementsCollection.length; // alert(collectionCount) var makeSelfSwitcherHandler = function(element){ return function(event){ var event = fixEvent(event,this); var target = event.target; // alert(target.tagName+" "+target.classList.contains(className)+" "+className); if(!target.classList.contains(className)){ return; } else { if(!parentMode){ element.classList.toggle('opened'); } else{ element.parentNode.classList.toggle('opened'); } } event.stopPropagation(); }; }; for(var counter = 0; counter<collectionCount; counter++){ var element = elementsCollection[counter]; element.addEventListener('click',makeSelfSwitcherHandler(element)); }; }; // SwitcherHandleBuilder(@param - string, @param=false (boolean -> Optional)))(передаем класс для обработки и включаем "Родительский режим" когда класс opened присвоится родителю элемента SwitcherHandleBuilder("selfSwitcher"); SwitcherHandleBuilder("switchParent",true); SwitcherHandleBuilder("switcherLevel_1"); |
А что у Вас значит: с ?
c.addEventListener("click", function(a) {} Это элемент, насколько я понял? Почему такая странная форма? я знаю, что есть для event = e, для элемента не знал. Где можно посмотреть все возможные сокращения? |
Цитата:
|
Часовой пояс GMT +3, время: 11:30. |