简体   繁体   中英

how to make an accordion constructor function with pure JavaScript?

i am trying to make a constructor function for an accordion with pure javaScript but it dosen't work... i guess it has something to do with the "this" keyword misbehaving.. I have written the code with a normal function and it did work but it dosen't with the constructor below.

 function Accordion(accordionId) { this.container = document.getElementById(accordionId); this.headers = this.container.getElementsByClassName("accordion-header"); this.sections = this.container.getElementsByClassName("accordion-section"); for (var i = 0; i < this.headers.length; i++) { this.headers[i].addEventListener("click", this.toggleSections); } this.toggleSections = function() { var toggeld = this.nextElementSibling.className; for (var i = 0; i < this.sections.length; i++) { this.sections[i].className = "accordion-section"; } if (toggeld === "accordion-section") { this.nextElementSibling.className = "accordion-section-displayed"; } else { this.nextElementSibling.className = "accordion-section"; } } } var newAccordion = new Accordion("accordion-wrapper"); 
 <div id="accordion-wrapper"> <h3 class="accordion-header">First Section</h3> <div class="accordion-section"> . </div> <h3 class="accordion-header">Second Section</h3> <div class="accordion-section"> </div> <h3 class="accordion-header">Third Section</h3> <div class="accordion-section"> </div> </div> 

I see a few things wrong here.

  1. You are setting the click handler to this.toggleSections before you define what this.toggleSections is. You should define it before setting the click handlers.
  2. Your this context in the click handler will be the element that was clicked, not your Accordion instance. There are a few way around this. You can either set another variable, self to equal this outside of the click handler and change this.sections to self.sections in the click handler (and any other instance variables you need). My preferred method, however, is to bind this to your click handler instead: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
  3. If you decided to go down the bind avenue, you will have to update your this.nextElementSibling references because the this context is no longer the clicked element. You can get the clicked element by adding an event paraemeter to your click handler and reference event.target instead of this .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM