[javscript] Event listener questions

Asked 1 years ago, Updated 1 years ago, 72 views

Hello. The codepen link below is the flex-panel code I wrote. https://codepen.io/w00kgod/pen/VgNaxW

There are three functions implemented by JS.

this.classList.add('open');
        setInterval(function(){item.classList.add('open-active');},400)  

This function was implemented by storing elements that occurred every time an event occurred using a global variable called proactiveE.

    const panel = document.querySelectorAll('.panel');
    var previousE = panel[0]; // initialization 

    panel.forEach(function(item){

      item.addEventListener('click',function(){
        if(previousE.className.split(' ')[2]){
        previousE.classList.remove('open');
        }

        this.classList.add('open');
        setInterval(function(){item.classList.add('open-active');},400)  

        PreviousE = this // Save the current event to PreviousE 

        this.addEventListener('click', function(){
          this.classList.remove('open','open-active'); 
        });

      });
    })

I added the code below to item.addEventListener.

   this.addEventListener('click', function(){
          this.classList.remove('open','open-active'); 
        });

But here's the problem.

If you receive this.addEventListener in the last item.addEventListener The panel opens and closes only once.

Question 1) This process should be repeated every time you click, but why doesn't it open again after it happens only once?

I thought open, open-active was not included in AddClass.List, or remove was not deleted, so I checked around this.classList.add('open';;

However, the console.log(this) above where classList.add was written contains an open class that was not even included.

질문2) console.log(this) 에서 open class가 들어가는 과정이 먼저 일어나는것은 호이스팅 때문인가요? 호이스팅이 어디에서 일어나는것인가요...? 질문3) console.log의 대상을 this가 아닌 다른것으로 해야할까요?

    console.log(this) // <div class="panel panel3 open open-active">
    this.classList.add('open')
    setInterval(function(){item.classList.add('open-active');},400) 

The open class has been deleted in this near remove. Maybe this was caused by deleting only the open from the initialization above.

   this.addEventListener('click', function(){
      console.log(this) //<div class="panel panel3 open-active">
      this.classList.remove('open','open-active'); 
      console.log(this) //div class="panel panel3 open-active">
    }

Question 3) It's not much different from question 1, but can you solve this problem by the way I wrote it (saving past events and attaching an event listener to the event listener)?Actually, I don't think it's a good way. Can this be solved in this way? That's why I'm asking this question.

Question 2 and question 3 are problems that arise from solving question 1.I would be more grateful if you could tell me a better way to solve question 1!

Thank you for reading the long question!

javascript event eventlistener

2022-09-22 11:33

2 Answers

I believe that the answer that fits each of the questions one, two, three will be given by someone who has more theory than me, and I just want to give you a practical answer... Since what you've just implemented is called accordion, it would be good to fundamentally consider the proper logic order of the implementation.

As you can see, this logic does not store what 'last pressed panel' is in a separate flag variable. I just specify two things, event.target panel and panel that occur each time a panel is pressed.

For example, in the markup given now, panel1~panel5 is subtracted from the ID instead of the class name, and then replaced like this.

const panel = document.querySelectorAll(".panel")
panel.forEach(function(item) {
  item.addEventListener('click', function () {
    var clickedItem = this
    var everythingElse = document.querySelectorAll('.panel:not(#'+clickedItem.id+')')
    everythingElse.forEach(function (el) {
      el.classList.remove('open-active', 'open')
    })
    if (clickedItem.classList.contains('open')) {
      clickedItem.classList.remove('open-active', 'open')
    } } else {
      clickedItem.classList.add('open')
      setInterval(function() {
        clickedItem.classList.add("open-active")
      }, 400)
    }
  })
})

I hope it's useful.

PS. In line 12, you are giving setInterval to item instead of this, but I doubt that this is the reason for the twisted .open-active that you see now.


2022-09-22 11:33

Unless it is specifically for additional control with JavaScript, other than the purpose of giving animation delay

(Based on codepen code) Do not use setTimeout in JavaScript Use transition-delay on the CSS.

CSS:

.panel {
  transition-delay: 0.4s;
  /*...hereinafter omitted...*/
}

javascript:

// setInterval(function(){item.classList.add('open-active');},400);
item.classList.add('open-active');

If you are in a situation where you need to manage the status with the class name of the element within the JavaScript code, the status will be twisted if you are not careful about using setTimeout.

The above code alone will not fix the entire functionality, but it will need to be refined.

generally safe for the status code. I like going in to delete an asynchronous logic and an alternative direction.


2022-09-22 11:33

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.