Как скрыть элемент при нажатии на другой элемент, который разделяет те же классы в vanilla JavaScript? - PullRequest
0 голосов
/ 17 апреля 2019

Я создал меню переключения, используя vanilla javaScript , потому что я пытаюсь не использовать jQuery в качестве зависимости. Пока я добился успеха, но я хочу отключить видимость других элементов при нажатии и открытии содержимого меню.

HTML-код для разметки :

<div class="menu-link">Menu 1</div>

<p class="menu-content animated">Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed quas odio facere sunt ullam quo ex amet sint in vitae.</p>

<br>

<div class="menu-link">Menu 2</div>

<p class="menu-content animated">Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed quas odio facere sunt ullam quo ex amet sint in vitae.</p>

<br>

<div class="menu-link">Menu 3</div>

<p class="menu-content animated">Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed quas odio facere sunt ullam quo ex amet sint in vitae.</p>

<br>

<div class="menu-link">Menu 4</div>

<p class="menu-content animated">Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed quas odio facere sunt ullam quo ex amet sint in vitae.</p>

CSS-код для оформления эффекта включения / выключения содержимого меню:

menu-link {
    display: inline-block;
    cursor: pointer;
    padding: 10px;
}

.menu-content {
    display: none;
}

.show {
    display: block;
    -webkit-animation-name: show;
    animation-name: show;
}

/* Show Animation */
@-webkit-keyframes show {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes show {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.animated {
    -webkit-animation-duration: 1.3s;
    animation-duration: 1.3s;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
}

JavaScript-код для включения / выключения класса:

// var declaration
var menuLinks = document.querySelectorAll('.menu-link');

// Loop through the array & add a click event to toggle "show" class
for (var i = 0; i < menuLinks.length; i++ ) {
    menuLinks[i].addEventListener('click', function() {
        if(this.nextElementSibling.className.match("show") ) {
            this.nextElementSibling.classList.remove("show");
        } else {
            this.nextElementSibling.classList.add("show");
        }
    });
};

Это jsfiddle пример

Ответы [ 4 ]

1 голос
/ 17 апреля 2019

Для этого вам нужно скрыть другие элементы в DOM. Один из способов сделать это:

JSFiddle

// var declaration
var menuLinks = document.querySelectorAll('.menu-link');

// Loop through the array & add a click event to toggle "show" class
for (var i = 0; i < menuLinks.length; i++ ) {
    var el = menuLinks[i]
  el.addEventListener('click', function() {
    var itemId = i;

      var allMenuLinks = document.querySelectorAll('.menu-link');

    if(this.nextElementSibling.className.match("show") ) {
      this.nextElementSibling.classList.remove("show");
    } else {
      this.nextElementSibling.classList.add("show");
    }

    for(var j=0; j<allMenuLinks.length; j++) {
        if(this==allMenuLinks[j]) {
        continue;
      }
      allMenuLinks[j].nextElementSibling.classList.remove("show");
    }
  })
}
1 голос
/ 17 апреля 2019

Внутри функции обратного вызова вы можете перебрать свой массив menuLinks , удалить класс show из всех братьев и сестер и, наконец, добавить его к брату, родитель которого инициировал событие click.Что-то вроде:

// var declaration
var menuLinks = document.querySelectorAll('.menu-link');

// Loop through the array & add a click event to toggle "show" class
for (var i = 0; i < menuLinks.length; i++) {
  menuLinks[i].addEventListener('click', function(e) {

    for (var a = 0; a < menuLinks.length; a++) {
      if (menuLinks[a] != e.target) {
        menuLinks[a].nextElementSibling.className = "menu-content animated";
      }

    }
    e.target.nextElementSibling.className = "show";
  });
};
menu-link {
  display: inline-block;
  cursor: pointer;
  padding: 10px;
}

.menu-content {
  display: none;
}

.show {
  display: block;
}

/* Show Animation */

@-webkit-keyframes show {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes show {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.show {
  -webkit-animation-name: show;
  animation-name: show;
}

.animated {
  -webkit-animation-duration: 1.3s;
  animation-duration: 1.3s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
<div class="menu-link">Menu 1</div>

<p class="menu-content animated">Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed quas odio facere sunt ullam quo ex amet sint in vitae.</p>

<br>

<div class="menu-link">Menu 2</div>

<p class="menu-content animated">Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed quas odio facere sunt ullam quo ex amet sint in vitae.</p>

<br>

<div class="menu-link">Menu 3</div>

<p class="menu-content animated">Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed quas odio facere sunt ullam quo ex amet sint in vitae.</p>

<br>

<div class="menu-link">Menu 4</div>

<p class="menu-content animated">Lorem ipsum dolor sit amet consectetur adipisicing elit. Sed quas odio facere sunt ullam quo ex amet sint in vitae.</p>
1 голос
/ 17 апреля 2019

Краткий ответ: Вы можете просто получить ссылку на элемент, который был нажат непосредственно на слушателе событий, и изменить видимость всех элементов, кроме того, который был нажат.

for (var i = 0; i < menuLinks.length; i++ ) {
  menuLinks[i].addEventListener('click', function(event) {
    const clickedElement = event.target;
    // remove show class from all elements but clicked element
    menuLinks.forEach(function(linkEl) {
      if (linkEl !== clickedElement) {
        linkEl.classList.toggle("show", false);
      } else {
        linkEl.classList.toggle("show", true);
      }
    });
  });
};

Одна проблема, которую я вижу здесь, заключается в том, что вы регистрируете списки кликов по всем элементам. Это можно оптимизировать, добавив прослушиватель одним щелчком к родительскому узлу DOM вместо каждого отдельного узла.

0 голосов
/ 17 апреля 2019

Сначала вы создаете новую функцию каждый раз в цикле, поэтому вам лучше объявить такую ​​функцию снаружи.Весь код может выглядеть так:

var menuLinks = document.querySelectorAll('.menu-link');
var onClick = function () {
  var target = this;
  for (var i = 0, j = menuLinks.length; i < j; i++) {
    if (target === menuLinks[i]) {
      target.classList.add("show");
    } else {
      target.classList.remove("show");
    }
  }
};
// Loop through the array & add a click event to toggle "show" class
for (var i = 0, j = menuLinks.length; i < j; i++) {
    menuLinks[i].addEventListener('click', onClick);
}

...