@aLeXxX_03

Как сделать закрытие меню по нажатию на любую область экрана?

Проблема в следующем, по нажатию на кнопку Меню мне нужно, чтобы меню открывалось/закрывалось, но и так же нужно, чтобы меню закрывалось по нажатию на любом свободном месте страницы, в любом месте экрана.

Первое я сделал - меню открывается по нажатию на кнопке Меню(у которой класс catalog и внутри которой div в котором 3 div) и закрывается по ней же, но как сделать закрытие по нажатию на любое место на экрана? А не только по нажатию на кнопку Меню.

Вот код:
Главный файл со всеми вложенными компонентами
<template>
  <Header />
  <router-view></router-view>
  <Footer />
</template>

<script>
import Header from "./Header.vue";
import Footer from "./Footer.vue";

export default {
  components: {
    Header,
    Footer,
  },
};
</script>

<style>
.container {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 700;
  font-size: 20px;
  line-height: 27px;
  color: #000000;
  margin: 0 auto;
  width: 1291px;
}
.Slider {
  position: relative;
  top: 150px;
}
</style>


Header вложенный в главный файл
<template>
  <div>
    <div class="containerTitle">
      <img class="sale" src="/img/header-title-sale.png" alt="" />
      <p class="infoSale">
        ПИТАЙТЕСЬ РАЗНООБРАЗНО И КОПИТЕ <span>СКИДКУ</span> до 10%
      </p>
      <p class="buttonSale">Получить скидку</p>
    </div>
    <HeaderBottom />
  </div>
</template>

<script>
import HeaderBottom from "./HeaderBottom.vue";
export default {
  components: {
    HeaderBottom,
  },
};
</script>

<styles lang="scss">
.containerTitle {
  position: relative;
  max-width: 1950px;
  margin: 0 auto;
  .infoSale {
    position: absolute;
    top: -13px;
    left: 640px;
    width: 355px;
    height: 52px;
    font-style: normal;
    font-weight: 900;
    font-size: 22px;
    line-height: 120%;
    text-transform: uppercase;
    color: #fff;
    span {
      padding-right: 8px;
      padding-left: 8px;
      border: 1px solid #ffa900;
      background: #ffa900;
      border-radius: 8px;
      color: red;
    }
  }
  .buttonSale {
    cursor: pointer;
    position: absolute;
    width: 189px;
    height: 43px;
    display: flex;
    align-items: center;
    padding-left: 22px;
    top: -5px;
    left: 1030px;
    border: 1px solid #ffffff;
    border-radius: 31px;
    font-style: normal;
    font-weight: 600;
    font-size: 20px;
    line-height: 27px;
    color: #ffffff;
  }
}
</styles>



вложенный в Header компонент HeaderBottom
<template>
    <div>
    <div class="Header">
      <div class="logo">
        <router-link to="/">
          <img src="/img/logo.png" alt="" />
        </router-link>
      </div>
      <div
        v-bind:class="{ catalogOpen: boolean }"
        class="catalog"
        v-on:click="menu"
      >
        <div>
          <div />
          <div />
          <div />
        </div>
        <p>Каталог</p>
        <div class="menuCatalog menuCatalogOpen">
          <ul class="menu">
            <li class="salesfirst">
              Акции
              <ul class="salesOpen">
                <li>Напитки</li>
                <li>Мучное</li>
                <li>Спиртные напитки</li>
                <li>Соки</li>
                <li>Десерт</li>
              </ul>
              <div class="arrowcreate">
                <div class="arrowbottom"></div>
                <div class="arrowtop"></div>
              </div>
            </li>
            <li class="popular">
              Популярные
              <ul class="popularOpen">
                <li>Мясо</li>
                <li>Спиртные напитки</li>
                <li>Морепродукты</li>
                <router-link to="/Catalog/Bread">
                  <li>Выпечка</li>
                </router-link>
                <router-link to="/Catalog/Pizza">
                  <li>Пицца</li>
                </router-link>
                <router-link to="/Catalog/Salad">
                  <li>Салаты</li>
                </router-link>
              </ul>
              <div class="arrowcreate">
                <div class="arrowbottom"></div>
                <div class="arrowtop"></div>
              </div>
            </li>
            <li class="supermarkt">
              Супермаркет
              <ul class="supermarktOpen">
                <li>Вода и напитки</li>
                <li>Молоко и яйца</li>
                <li>Снэки и сухофрукты</li>
                <li>Кофе, чай, сладости</li>
                <li>Макароны и крупы</li>
                <li>Хлеб и выпечка</li>
              </ul>
              <div class="arrowcreate">
                <div class="arrowbottom"></div>
                <div class="arrowtop"></div>
              </div>
            </li>
            <li class="cooking">
              Кулинария
              <ul class="cookingOpen">
                <Link to="lists/bread">
                  <li>Хлеб и выпечка</li>
                </Link>
                <li>Продукция к чаю</li>
                <li>Снэки</li>
              </ul>
              <div class="arrowcreate">
                <div class="arrowbottom"></div>
                <div class="arrowtop"></div>
              </div>
            </li>
            <li class="freezing">
              Заморозка
              <div class="arrowcreate">
                <div class="arrowbottom"></div>
                <div class="arrowtop"></div>
              </div>
            </li>
            <li class="anthr">
              Другое
              <div class="arrowcreate">
                <div class="arrowbottom"></div>
                <div class="arrowtop"></div>
              </div>
            </li>
            <li>
              Продукция от «Ильинского
              <div class="arrowcreate">
                <div class="arrowbottom"></div>
                <div class="arrowtop"></div>
              </div>
            </li>
          </ul>
        </div>
      </div>
       </div>       
            
</template>

<script>
export default {
  data() {
    return {
      boolean: false,
    };
  },
  methods: {
    menu() {
      this.boolean = !this.boolean;
    },
  },
};
</script>

<style lang="scss">

.menuCatalog {
  display: none;
  position: absolute;
  top: 50px;
  left: -197px;
  color: #fff;
  background: #ffffff;
  box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25);
  border-radius: 14px;
  width: 688px;
  transition-duration: 0.5s ease;
  .menu {
    width: 308px;
    border-right: 3px solid #e0e0e0;
    padding-right: 10px;

    li {
      margin: 10px;
      display: flex;
      justify-content: space-between;
      font-style: normal;
      font-weight: 100;
      font-size: 20px;
      line-height: 27px;
      color: #0a0a0a;
      list-style: none;
      position: relative;
      left: -15px;
      right: 25px;
      img {
        width: 7px;
        height: 11px;
        position: relative;
        top: 7px;
      }
    }
  }
}
.catalogOpen {
  transition-duration: 0.1s;
  transform: scale(1.06);
  cursor: pointer;
  .menuCatalogOpen {
    position: absolute;
    top: 48px;
    display: block;
    li:hover {
      color: red;
      .arrowbottom {
        background-color: red;
      }
      .arrowtop {
        background-color: red;
      }
    }
  }
}



</style>
  • Вопрос задан
  • 205 просмотров
Пригласить эксперта
Ответы на вопрос 3
@oexlkinq
можно, например, слушать клики на document и проверять, является ли элемент меню родителем для event.target
Ответ написан
v-click-outside
Ответ написан
Комментировать
@LJ322
Создайте свою директиву или установите готовую
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы