Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Вложенные переключатели (https://javascript.ru/forum/dom-window/54856-vlozhennye-pereklyuchateli.html)

Velidan 03.04.2015 16:44

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

Буду благодарен за любую помощь.

рони 03.04.2015 17:43

Выпадающее меню на чистом 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>

Velidan 03.04.2015 17:55

Рони, в который раз спасибо Вам огромное за помощь.

Решил самостоятельно вот таким образом, правда, как-то очень топорно вышло, но я очень рад, что у меня хоть как-то получилось.
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");

Velidan 03.04.2015 18:04

А что у Вас значит: с ?
c.addEventListener("click", function(a) {}


Это элемент, насколько я понял? Почему такая странная форма? я знаю, что есть для event = e, для элемента не знал.
Где можно посмотреть все возможные сокращения?

рони 03.04.2015 18:18

Цитата:

Сообщение от Velidan
Где можно посмотреть все возможные сокращения?

в голове -- но лучше переменным давать осмысленные названия. убрал чтоб вопросов не было :cray:


Часовой пояс GMT +3, время: 11:30.