Хитрый тумблер с активным движением с ванилью JavaScript - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть структура, как показано ниже, и я хочу toggle active текущий .item элемент. Я использую простую функцию Vanilla JavaScript, которую я обычно использую в ситуациях, похожих на щелчки, и она работает.

function myFunction(e) {
  var elems = document.querySelectorAll(".hover");
  [].forEach.call(elems, function(el) {
    el.classList.remove("hover");
  });
  e.target.classList.add("hover");
}
<div class="main-container">
  <div class="item hover" onmouseover="myFunction(event)">
    <a href="#">item 1</a>
  </div>
  <div class="item" onmouseover="myFunction(event)">
    <a href="#">item 2</a>
  </div>
  <div class="item" onmouseover="myFunction(event)">
    <a href="#">item 3</a>
  </div>
</div>

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

Я попробовал несколько тиков CSS, но мне не удалось заставить его работать, любые мысли будут высоко оценены

PS Я предпочитаю Ваниль JavaScript, чем jQuery

Ответы [ 4 ]

2 голосов
/ 08 апреля 2020

Вы можете использовать CSS для добавления и удаления наведения. Basi c код, показывающий это и добавленный код для переключения, чтобы он мог перемещаться.

const menu = document.querySelector(".main-container")
menu.addEventListener("click", function (evt) {
  const item = evt.target.closest(".item")
  if (item) {
    menu.querySelector(".item.active").classList.remove("active")
    item.classList.add("active")
  }
});
.main-container .item.active {
  background-color: green;
}

.item,
.main-container:hover .item.active {
  background-color: yellow;
  transition: background-color .3s;
}

.main-container:hover .item:hover {
  background-color: lime;
  transition: background-color .3s;
}
<div class="main-container">
  <div class="item active">
    <a href="#">item 1</a>
  </div>
  <div class="item">
    <a href="#">item 2</a>
  </div>
  <div class="item">
    <a href="#">item 3</a>
  </div>
</div>
1 голос
/ 08 апреля 2020

Вам не нужно JS для этого. Просто перезаписать стиль при наведении контейнера

.main-container:hover .item.hover {
  background-color: transparent;
}
.item.hover {
  background-color: red;
}
.item:hover {
  background-color: red !important;
}
<div class="main-container" >
  <div class="item hover">
    <a href="#">item 1</a>
  </div>
  <div class="item">
    <a href="#">item 2</a>
  </div>
  <div class="item">
    <a href="#">item 3</a>
  </div>
</div>

См. Jsfiddle: https://jsfiddle.net/hs2yfxm1/

1 голос
/ 08 апреля 2020

Если вы пытаетесь стилизовать это на основе события при наведении, вы должны использовать соответствующий псевдокласс. Вы упомянули, что вы всегда хотите, чтобы первый элемент был «активным», почему бы не установить класс .active, который соответствует стилю формата :hover? Например:

S CSS

.item {
  border-color: red;

  &.active,
  &:hover {
    border-color: blue;
  }
}

CSS

.item {
  border-color: red;
}

.item.active,
.item:hover {
  border-color: blue;
}

Примечание: Как правило, рекомендуется ограничить использование JS, когда это возможно. Если что-то достижимо просто с помощью HTML и CSS, это должно быть предпочтительной реализацией в большинстве случаев. прокомментируйте ваш JS. В вашем примере вы используете e.target, это может быть опасно, если у элемента есть дочерние элементы, а целью может быть дочерний элемент. Поскольку вы нацеливаетесь на каждый элемент индивидуально (много слушателей событий, которые вы, возможно, захотите рассмотреть для повторной работы), вы можете использовать e.currentTarget для других JS потребностей.

0 голосов
/ 08 апреля 2020

Это то, что вы ищете?

.active { background-color:grey; }
.item:hover { background-color:yellow; }
<div class="main-container" >
      <div class="item active">
         <a href="#">item 1</a>
      </div>
      <div class="item">
        <a href="#">item 2</a>
      </div>
      <div class="item">
        <a href="#">item 3</a>
      </div>
    </div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...