Как закрыть это меню по любому клику? - PullRequest
3 голосов
/ 28 марта 2020

Пока мне удалось успешно открыть и закрыть меню через значок меню. Но я хотел бы закрыть его на любой клик. Я поражен тем, как справиться с этим. Я попытался добавить прослушиватель событий щелчка в окне / документе / заголовке / навигации ... но, кажется, он сразу закрывает меню, прежде чем что-либо будет выбрано. Как бы вы подошли к этому?

let nav = document.querySelector(".header__nav");

function toggleNavOn() {
  if (nav.style.visibility === "") {
    nav.style.visibility = "visible";
  } else {
    nav.style.visibility = "";
  }
  navToggle.classList.toggle("header__nav_toggle--toggled")
}

let navToggle = document.querySelector(".header__nav_toggle");
navToggle.addEventListener("click", toggleNavOn);
* {
  margin: 0;
  padding: 0;
}

:root {
  --color-white: #fffff0;
  --color-black: #000;
  --color-primary: #5f5e63;
  --color-primary-light: #8c8b90;
  --color-primary-dark: #353439;
  --color-primary-dark-2: #131313;
  --color-secondary: #ca3722;
  --color-secondary-light: #ff6a4c;
  --color-secondary-dark: #920000;
  --cells: 40;
  --cellSize: calc(100vw / var(--cells));
}

.header {
  -ms-grid-column: 1;
  -ms-grid-column-span: 40;
  grid-column: 1 / span 40;
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 10;
  margin: 0 auto;
  -webkit-box-shadow: 0 0.9rem 1.8rem rgba(0, 0, 0, 0.25), 0 0.625rem 0.625rem rgba(0, 0, 0, 0.22);
  box-shadow: 0 0.9rem 1.8rem rgba(0, 0, 0, 0.25), 0 0.625rem 0.625rem rgba(0, 0, 0, 0.22);
  padding: 1.1rem 1.4rem;
  width: 100%;
  background: var(--color-primary-dark-2);
}

.header__container {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
  z-index: 11;
}

.header__container_logo {
  z-index: 1;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-direction: row;
  flex-direction: row;
}

.header__logo_link {
  -webkit-box-flex: 2;
  -ms-flex-positive: 2;
  flex-grow: 2;
}

.header__logo_img {
  margin: 0 auto;
  max-height: 1.3rem;
  width: 2.6rem;
}

.header__nav_toggle {
  display: block;
  height: 24px;
  width: 24px;
}

.header__nav_toggle span {
  display: inline-block;
  height: 100%;
  width: 100%;
}

.header__nav_toggle span::before {
  content: "";
  position: relative;
  display: block;
  top: 6px;
  height: 2px;
  width: 100%;
  background-color: var(--color-white);
  -webkit-transition: all 0.15s ease-in-out;
  transition: all 0.15s ease-in-out;
}

.header__nav_toggle span::after {
  content: "";
  position: relative;
  display: block;
  top: 12px;
  height: 2px;
  width: 100%;
  background-color: var(--color-white);
  -webkit-transition: all 0.15s ease-in-out;
  transition: all 0.15s ease-in-out;
}

.header__nav_toggle--toggled span::before {
  top: 13px;
  -webkit-transform: rotate(45deg);
  transform: rotate(45deg);
  -webkit-transition: all 0.15s ease-in-out;
  transition: all 0.15s ease-in-out;
}

.header__nav_toggle--toggled span::after {
  -webkit-transform: rotate(-45deg);
  transform: rotate(-45deg);
  -webkit-transition: all 0.15s ease-in-out;
  transition: all 0.15s ease-in-out;
}

.header__nav_link:hover,
.header__logo_link:hover,
.header__logo_img:hover,
.header__nav_toggle:hover {
  opacity: 0.8;
  -webkit-transition: all 0.1s ease;
  transition: all 0.1s ease;
}

.header__nav_link {
  display: none;
  color: var(--color-white);
  font-size: 0.9rem;
  font-weight: 400;
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.1rem;
}

.header__nav {
  visibility: hidden;
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
  margin-bottom: -0.9rem;
  padding-top: 16px;
  text-align: center;
  background-color: var(--color-primary-dark);
}

.header__nav_link {
  display: block;
  border-top: 2px solid;
  -o-border-image: linear-gradient(to right, rgba(0, 0, 0, 0), var(--color-primary-dark), rgba(0, 0, 0, 0)) 1;
  border-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0)), color-stop(var(--color-primary-dark)), to(rgba(0, 0, 0, 0))) 1;
  border-image: linear-gradient(to right, rgba(0, 0, 0, 0), var(--color-primary-dark), rgba(0, 0, 0, 0)) 1;
  padding: 0.5rem 0;
}
<header class="header">
  <div class="header__container">
    <div class="header__container_logo">
      <a class="header__logo_link" href="#"><img class="header__logo_img" src="img/vtol-logo.svg" alt="Vtol Logo"></a>
      <a class="header__nav_toggle" href="javascript:void(0);">
        <span></span>
      </a>
    </div>

    <nav class="header__nav" id="nav-bar">
      <a class="header__nav_link" href="#video-container">Watch</a>
      <a class="header__nav_link" href="#features">Features</a>
      <a class="header__nav_link" href="#about">About</a>
    </nav>

  </div>
</header>

Ответы [ 3 ]

1 голос
/ 28 марта 2020

вы можете взглянуть на события 'focus' и 'blur'.

https://developer.mozilla.org/en-US/docs/Web/API/Element/blur_event

0 голосов
/ 28 марта 2020

Чтобы понять, почему вы видите, что меню закрывается сразу при добавлении обработчика события щелчка в окне / документе / (независимо от родительского элемента), необходимо начать с обсуждения захвата и всплытия событий. Порядок переходит в режим захвата -> щелчок захвачен -> размножается .. Вы щелкаете элемент, и он сначала захватывается в окне и проходит вниз по DOM до самого определенного c элемента DOM. Затем по пути «всплывают» резервные копии обработчиков событий. Вот еще немного информации по теме: https://javascript.info/bubbling-and-capturing

В вашем сценарии происходит то, что событие щелчка в меню запускает обработчики не только для этого элемента, но и для каждого родителя. хорошо. Одним из возможных решений является добавление event.stopPropagation() в ваш обработчик событий щелчка меню, чтобы событие щелчка там не всплыло ни к какому родительскому элементу DOM, к которому вы присоединяете функцию «закрыть меню». https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

0 голосов
/ 28 марта 2020

https://jsfiddle.net/f21vnq5s/1/

Вы должны сначала установить высоту меню, а затем в документе проверить, щелкните, если в заголовке или нет

Это должно работать с jquery

$(document).mouseup(function (e)
{
    var searchcontainer = $(".header");

    if (!searchcontainer.is(e.target) // if the target of the click isn't the container...
        && searchcontainer.has(e.target).length === 0) // ... nor a descendant of the container
    {
           nav.style.visibility = "";
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...