-1

I have three panels, one by another in a row. When I click on one of them, its width increases. When I click on any of other two, the panel which previously increased width shrinks and the newly clicked panel widens. However, I would like to be able to shrink the just widened panel by clicking on it. I am struggling to find the solution but with no effect.

This is my code:

var panels = document.querySelectorAll('.panel'),
  activePanel = document.querySelectorAll('.panel.open');

function toggleOpen() {
  panels.forEach(function(item) {
    if (item.classList.contains('open')) {
      item.classList.remove('open');
      item.classList.add('closed');
    }

  });

  this.classList.remove('closed');
  this.classList.add('open');
}

function closeActivePanel() {
  if (activePanel.length > 0) {
    activePanel.removeClass('open');
    activePanel.addClass('closed');
  }
}

panels.forEach(function(panel) {
  panel.addEventListener('click', toggleOpen);
});

activePanel.forEach(function(aPanel) {
  aPanel.addEventListener('click', closeActivePanel);
});
<div class="panel panel1">
  <div class="panel__overlay"></div>
  <p>Lorem ipsum dolor sit amet</p>
  <p>Lorem ipsum</p>
  <p>Lorem ipsum dolor sit amet</p>
</div>
<div class="panel panel2">
  <div class="panel__overlay"></div>
  <p>Lorem ipsum dolor sit amet</p>
  <p>Lorem ipsum</p>
  <p>Lorem ipsum dolor sit amet</p>
</div>
<div class="panel panel3">
  <div class="panel__overlay"></div>
  <p>Lorem ipsum dolor sit amet.</p>
  <p>Lorem ipsume</p>
  <p>Lorem ipsum dolor sit amet</p>
</div>

The function closeActivePanel just does not fire. And there is no error message.

bakrall
  • 217
  • 3
  • 12
  • Your addEvent6Listener is getting called. Try adding log in `toggleOpen` – Rajesh Dec 12 '17 at 13:01
  • Sorry, PaneladdEventListener was a typing mistake. I've just corrrected it. – bakrall Dec 12 '17 at 13:03
  • `activePanel` will only contain those elements which have the class `open` when `document.querySelectorAll('panel.open')` is executed. Use [event delegation](https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation) – Andreas Dec 12 '17 at 13:07
  • @Andreas I did not know such mechanism. Thanks a lot for the tip! I will try it out. – bakrall Dec 12 '17 at 13:29

2 Answers2

0

The Time you query the DOM for the .panel.open elements they don't exist. You have to add the listener after you've added the class "open" to the element or implement a toggle logic in the click handler for the .panel elements.

Siggy
  • 194
  • 1
  • 11
  • Then you would have to remove the event handler when "closing" a panel... – Andreas Dec 12 '17 at 13:05
  • @Andreas Yes that's correct if you don't want to do it this way you could use a more general event handler which handles this toggle behavior. – Siggy Dec 12 '17 at 13:06
  • This is exactly what I am trying to do. I came up with four ideas till now, but none works. – bakrall Dec 12 '17 at 13:10
  • @bakrall Use [event delegation](https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation) – Andreas Dec 12 '17 at 13:14
0

Finally I found the solution for my problem. I think it would be very useful for accordion element for example. The goal was to have the possibility to increase width of one of elements by clicking on it (class 'open' produces this effect). And then to shrink it either by clicking on this element of any of other two beside it. Having the effect of shrinking the wide element by clicking on other two elements was easy. But to add functionality to shrink it by clicking on itself was quite a gymnastics. Event delegation turned out not to be helpful as I needed to know exact target of the event. Here is what I found working:

var panels = document.querySelectorAll('.panel');

function togglePanels(event) {
    var target = event.target;

    panels.forEach(function(item) {
        if(item != target) {
            item.classList.remove('open')
        };
    });
    target.classList.toggle('open');    
}

panels.forEach(function(panel) {
    panel.addEventListener('click', togglePanels);
});
bakrall
  • 217
  • 3
  • 12