Изменения классов JS

234
03 марта 2017, 01:29

При изменении class="main main-active", block active меняется в диве main, а не main-active. Как исправить что бы active в div.block изменялся в main-active, а не в первом элементе main?

var main_active = document.querySelector('.main-active'), 
  btn_blocks = document.querySelector('.btn-blocks'), 
  btn_main = document.querySelector('.btn-main'), 
  blocks = Array.from(main_active.querySelectorAll('.block')), 
  main = Array.from(document.querySelectorAll('.main')), 
  pointer = 0; 
pointer_main = 0; 
 
btn_blocks.addEventListener('click', function() { 
  blocks[pointer].classList.remove('active'); 
  if (pointer + 1 >= blocks.length) 
    pointer = 0; 
  else 
    pointer++; 
  blocks[pointer].classList.add('active'); 
}); 
 
btn_main.addEventListener('click', function() { 
  main[pointer_main].classList.remove('main-active'); 
  if (pointer_main + 1 >= main.length) 
    pointer_main = 0; 
  else 
    pointer_main++; 
  main[pointer_main].classList.add('main-active'); 
});
<button class="btn-blocks">button blocks</button> 
<br> 
<button class="btn-main">button main</button> 
<div class="main main-active"> 
  <div class="block red active"></div> 
  <div class="block black"></div> 
  <div class="block green"></div> 
</div> 
<div class="main"> 
  <div class="block red active"></div> 
  <div class="block black"></div> 
  <div class="block green"></div> 
</div>

https://jsfiddle.net/b6312wvt/

Answer 1

Например, можно при переключении main-active переопределять переменные main_active и blocks, над которыми делается манипуляция.

btn_main.addEventListener('click', function() {
  main[pointer_main].classList.remove('main-active');
  if (pointer_main + 1 >= main.length)
    pointer_main = 0;
  else
    pointer_main++;
  main[pointer_main].classList.add('main-active');
  // look here
  main_active = document.querySelector('.main-active')
  blocks = Array.from(main_active.querySelectorAll('.block'))
});
Answer 2

Суть вашей проблемы в том, что функции вроде querySelector не отслеживают изменения классов. Они возвращают соответствующие элементы на момент вызова.

Поэтому, вам необходимо, каким-либо образом обновлять ссылки(переменные) на активные элементы.

Также замечу, что вы не можете иметь общий pointer для нескольких блоков.
В сниппете я получаю текущую позицию активного элемента с помощью indexOf.

var btn_blocks = document.querySelector('.btn-blocks'), 
  btn_main = document.querySelector('.btn-main'); 
 
btn_blocks.addEventListener('click', function() { 
  var main = Array.from(document.querySelectorAll('.main')); 
  var main_active = document.querySelector('.main-active');  
  var blocks = Array.from(main_active.querySelectorAll('.block')); 
  var block_active = main_active.querySelector('.block.active'); 
  var pointer = blocks.indexOf(block_active); 
   
 blocks[pointer].classList.remove('active'); 
  if (pointer + 1 >= blocks.length) 
    pointer = 0; 
  else 
    pointer++; 
  blocks[pointer].classList.add('active'); 
}); 
 
btn_main.addEventListener('click', function() { 
  var main = Array.from(document.querySelectorAll('.main')); 
  var main_active = document.querySelector('.main-active');  
  var pointer_main = main.indexOf(main_active); 
   
  main[pointer_main].classList.remove('main-active'); 
  if (pointer_main + 1 >= main.length) 
    pointer_main = 0; 
  else 
    pointer_main++; 
  main[pointer_main].classList.add('main-active'); 
});
.red{background-color: red;} 
.black{background-color: black;} 
.green{background-color: green;} 
 
.main{display: inline-block;} 
 
.main-active{outline: 5px solid yellow;} 
.active{outline: 5px solid blue; outline-offset: -5px;} 
 
.block{ 
  width: 30px; 
  height: 30px; 
}
<button class="btn-blocks">button blocks</button> 
<br> 
<button class="btn-main">button main</button> 
<hr/> 
<div class="main main-active"> 
  <div class="block red active"></div> 
  <div class="block black"></div> 
  <div class="block green"></div> 
</div> 
<div class="main"> 
  <div class="block red active"></div> 
  <div class="block black"></div> 
  <div class="block green"></div> 
</div> 
<div class="main"> 
  <div class="block red active"></div> 
  <div class="block black"></div> 
  <div class="block green"></div> 
</div> 
<div class="main"> 
  <div class="block red active"></div> 
  <div class="block black"></div> 
  <div class="block green"></div> 
</div> 
<div class="main"> 
  <div class="block red active"></div> 
  <div class="block black"></div> 
  <div class="block green"></div> 
</div>

READ ALSO
Hover-эффект в навигации bootstrap

Hover-эффект в навигации bootstrap

Не могу найти, где задается hover-эффект для элементов навигацииПри наведении на элемент меню появляется белый бэкграунд (см

310
fancybox не применяется слайдер к галерее

fancybox не применяется слайдер к галерее

пытаюсь применить плагин fancybox для галереи, чтобы при клике на одну из картинок открывалось модальное окно, в котором будет слайдер

226
Баг MarionetteJs в хроме?

Баг MarionetteJs в хроме?

Здравствуйте! У меня проблема, и еще страннаяЕсть CollectionView

250