Вложенные переключатели
Доброго дня уважаемые коллеги. Столкнулся с очень непростой проблемой, самостоятельно решить не могу.
Суть: у меня есть много выпадающих элементов, чтобы вручную не вешать обработчик на каждую кнопку сделал универсальную схему. Создал класс, который получаю в 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, время: 16:25. |