Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
131 views
in Technique[技术] by (71.8m points)

javascript - How to Remove Event Listener from Function

I am utilizing the accordion build from W3 Schools. It works great, but I would like to clean things up a bit by creating a function for this in my JS file (rather than inline <script> tags). The problem is that I need to tweak it a little by removing the event listener, but I have had little luck (still learning JS). How Can I achieve this?

Below is what I want to do, but need to remove the event listener because it makes the user have to double click in order to activate the accordion.

HTML:

<button class="accordion" onclick="faqsAccordion()">Section 1</button>
<div class="panel">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

JS

function faqsAccordion() {
  var acc = document.getElementsByClassName("accordion");
  var i;

  for (i = 0; i < acc.length; i++) {
    acc[i].addEventListener("click", function() {
      this.classList.toggle("faqs-active");
      var panel = this.nextElementSibling;
      if (panel.style.maxHeight) {
        panel.style.maxHeight = null;
      } else {
        panel.style.maxHeight = panel.scrollHeight + "px";
      } 
    });
  }
}
question from:https://stackoverflow.com/questions/65945141/how-to-remove-event-listener-from-function

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The Gist

Keep a version of the function you're using as an event listener, e.g

function MyHandler(){
    console.log("clicked!");
}
document.getElementById("MyButton").addEventListener("click", MyHandler);

then you can later remove it by just using the same function name.

document.getElementById("MyButton").removeEventListener("click", MyHandler);

If you insist on using the onclick property, you can also set it to null manually in code; however I don't recommend it. onclick in HTML is confusing, it executes the code inside of the string rather than just setting the "click" event handler to the function with that name.

document.getElementById("MyButton").onclick = null;

Oddly enough, changing it to a different string doesn't work. A lot of these old HTML attributes glued to JS work in counter-intuitive ways. It doesn't work because the onclick property takes a function pointer and refuses anything else meanwhile the onclick attribute takes a string that executes.

What you want to do

You want to turn this

function faqsAccordion() {
  var acc = document.getElementsByClassName("accordion");
  var i;

  for (i = 0; i < acc.length; i++) {
    acc[i].addEventListener("click", function() {
      this.classList.toggle("faqs-active");
      var panel = this.nextElementSibling;
      if (panel.style.maxHeight) {
        panel.style.maxHeight = null;
      } else {
        panel.style.maxHeight = panel.scrollHeight + "px";
      } 
    });
  }
}

Into this

<button class="accordion" id="faqsAccordian">Section 1</button>
<div class="panel">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
document.getElementById("faqsAccordian").addEventListener("click",faqsAccordian);
function myfunc(e){ // Added the "event" parameter for you, for future use :)
  this.classList.toggle("faqs-active");
  var panel = this.nextElementSibling;
  if (panel.style.maxHeight) {
    panel.style.maxHeight = null;
  } else {
    panel.style.maxHeight = panel.scrollHeight + "px";
  } 
}
function faqsAccordion() {
  var acc = document.getElementsByClassName("accordion");
  var i;
  
  for (i = 0; i < acc.length; i++) {
    acc[i].addEventListener("click", myfunc);
  }
}
// ... some time later...
var acc = document.getElementsByClassName("accordion");
const whichever = 0;

// Randomly remove an event listener... muahuahua...
acc[whichever].removeEventListener("click", myfunc);

However...

What if you want to use anonymous functions because you want many of the same function to act as an event listener? Let's say we want one more alert box to pop up from clicking MyButton below.

<html>
<body>
<button id="MyButton">Add alert to the bottom button</button><br>
<button id="MyAlertButton">Popup please!</button>

<script>
var MyAlertButtonFunctionPointers = [];
function MyAlertButtonClickWrapper(e){
    MyAlertButtonFunctionPointers.forEach(f=>f(e))
}
document.getElementById("MyAlertButton").addEventListener("click", MyAlertButtonClickWrapper);

document.getElementById("MyButton").addEventListener("click", function(e){
  MyAlertButtonFunctionPointers.push(e=>{
    alert("Hi! I'm a button with the name " + this.id + "
The event that lead to me being clicked happened at (" + e.screenX + ", " + e.screenY + ")"); 
  })
})
</script>
</body>
</html>

You can then remove selectively any event listener you want by just popping it out of the array.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...