Добавить класс диву при наведении, а у других дивов удалить на чистом JS

Есть родитель с тремя дивами, а также два класса - стандартный для всех 150 и класс который дает ширину 300 пикселей. При загрузке страницы у первого дива стоит класс на 300, а у остальных по 150 пикселей.

При наведении мышки на другой див, див в фокусе получает класс на 300 пикселей, а у первого класс на 300 удаляется и он становится 150.


Ответы (2 шт):

Автор решения: De.Minov

При желании такое можно сделать и на чистом CSS.

.hover {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  max-width: 600px;
}

.hover__item-wrap {
  display: block;
  width: 100%;
  transition: all .3s ease;
}

.hover__item-wrap:not(:last-child) {
  padding-right: 10px;
  box-sizing: border-box;
}

.hover__item {
  height: 150px;
  background: lightblue;
}

/* ---- */

.hover:hover .hover__item-wrap:nth-child(1) {
  flex-shrink: initial;
  width: 100%;
}

.hover__item-wrap:nth-child(1),
.hover:hover .hover__item-wrap:hover {
  flex-shrink: 0;
  width: 300px;
}
<div class="hover">
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
</div>

Но если так сильно хочется, то вот на JS.

var hover = document.querySelector('.hover'),
    elemHover = false;

hover.addEventListener('mouseover', function(e) {
  if(elemHover) return;
  var target = e.target.closest('.hover__item-wrap');
  if(!target) return;

  elemHover = target;
  
  var parent = target.closest('.hover'),
      old = parent.querySelector('.hover__item-wrap--fill')
  if(old) old.classList.remove('hover__item-wrap--fill')
  target.classList.add('hover__item-wrap--fill')
})

hover.addEventListener('mouseout', function(e) {
  if(!elemHover) return
  var target = e.target.closest('.hover__item-wrap')

  target.classList.remove('hover__item-wrap--fill');
  
  elemHover = null;
})

hover.addEventListener('mouseleave', function(e) {
  var def = e.target.querySelectorAll('.hover__item-wrap')[0];
  if(!def.classList.contains('hover__item-wrap--fill')) def.classList.add('hover__item-wrap--fill');
})
.hover {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  max-width: 600px;
}

.hover__item-wrap {
  display: block;
  width: 100%;
  transition: all .3s ease;
}

.hover__item-wrap:not(:last-child) {
  padding-right: 10px;
  box-sizing: border-box;
}

.hover__item-wrap--fill {
  flex-shrink: 0;
  width: 300px;
}

.hover__item {
  height: 150px;
  background: lightblue;
}
<div class="hover">
  <div class="hover__item-wrap hover__item-wrap--fill">
    <div class="hover__item"></div>
  </div>
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
</div>


Жёсткие размеры блоков

CSS:

.hover {
  display: inline-flex;
  justify-content: space-between;
  align-items: center;
  max-width: 100%;
}

.hover__item-wrap {
  display: block;
  width: 150px;
  transition: all .3s ease;
}

.hover__item-wrap:not(:last-child) {
  padding-right: 10px;
  box-sizing: border-box;
}

.hover__item {
  height: 150px;
  background: lightblue;
}

/* ---- */

.hover:hover .hover__item-wrap:nth-child(1) {
  flex-shrink: initial;
  width: 150px;
}

.hover__item-wrap:nth-child(1),
.hover:hover .hover__item-wrap:hover {
  flex-shrink: 0;
  width: 300px;
}
<div class="hover">
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
</div>

JS:

var hover = document.querySelector('.hover'),
    elemHover = false;

hover.addEventListener('mouseover', function(e) {
  if(elemHover) return;
  var target = e.target.closest('.hover__item-wrap');
  if(!target) return;

  elemHover = target;
  
  var parent = target.closest('.hover'),
      old = parent.querySelector('.hover__item-wrap--fill')
  if(old) old.classList.remove('hover__item-wrap--fill')
  target.classList.add('hover__item-wrap--fill')
})

hover.addEventListener('mouseout', function(e) {
  if(!elemHover) return
  var target = e.target.closest('.hover__item-wrap')

  target.classList.remove('hover__item-wrap--fill');
  
  elemHover = null;
})

hover.addEventListener('mouseleave', function(e) {
  var def = e.target.querySelectorAll('.hover__item-wrap')[0];
  if(!def.classList.contains('hover__item-wrap--fill')) def.classList.add('hover__item-wrap--fill');
})
.hover {
  display: inline-flex;
  justify-content: space-between;
  align-items: center;
  max-width: 100%;
}

.hover__item-wrap {
  display: block;
  width: 150px;
  transition: all .3s ease;
}

.hover__item-wrap:not(:last-child) {
  padding-right: 10px;
  box-sizing: border-box;
}

.hover__item-wrap--fill {
  flex-shrink: 0;
  width: 300px;
}

.hover__item {
  height: 150px;
  background: lightblue;
}
<div class="hover">
  <div class="hover__item-wrap hover__item-wrap--fill">
    <div class="hover__item"></div>
  </div>
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
</div>


Сохранение активного класса

var hover = document.querySelector('.hover'),
    elemHover = false;

hover.addEventListener('mouseover', function(e) {
  if(elemHover) return;
  var target = e.target.closest('.hover__item-wrap');
  if(!target) return;

  elemHover = target;
  
  var parent = target.closest('.hover'),
      old = parent.querySelector('.hover__item-wrap--fill')
  if(old) old.classList.remove('hover__item-wrap--fill')
  target.classList.add('hover__item-wrap--fill')
})

hover.addEventListener('mouseout', function(e) {
  if(!elemHover) return
  var target = e.target.closest('.hover__item-wrap')
  
  elemHover = null;
})
.hover {
  display: inline-flex;
  justify-content: space-between;
  align-items: center;
  max-width: 100%;
}

.hover__item-wrap {
  display: block;
  width: 150px;
  transition: all .3s ease;
}

.hover__item-wrap:not(:last-child) {
  padding-right: 10px;
  box-sizing: border-box;
}

.hover__item-wrap--fill {
  flex-shrink: 0;
  width: 300px;
}

.hover__item {
  height: 150px;
  background: lightblue;
}
<div class="hover">
  <div class="hover__item-wrap hover__item-wrap--fill">
    <div class="hover__item"></div>
  </div>
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
  <div class="hover__item-wrap">
    <div class="hover__item"></div>
  </div>
</div>

→ Ссылка
Автор решения: Rudi

Можно что-то такое сделать..

document.querySelectorAll('.item').forEach(e=>{
  e.addEventListener('mouseover',function(){
    this.classList.add('active_item')
  })
  e.addEventListener('mouseout',function(){
    this.classList.remove('active_item')
  })
})
.item {
  width: 150px;
  height: 50px;
  background: green;
  border: solid 1px yellow;
  transition: 0.5s;
}
.active_item{
  width: 300px;
}
<div>
  <div class="item active_item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

→ Ссылка