0

so wrote a simple script:

function Component(renderTarget){  
  this.target = document.querySelector(renderTarget);

  this.number = 0;
  this.increment = 1;

  this.goUp = function(){
    this.number = this.number + this.increment;
    this.render();
  }

  this.goDown = function(){
    this.number = this.number - this.increment;
    this.render();
  }

  this.render = function(){    
   this.target.innerHTML = '';
   this.target.innerHTML += `
    <div class="container">
      <div class="number">${this.number}</div>
      <div class="selector">
        <div class="up"><i class="fa fa-chevron-up" aria-hidden="true"></i></div>
        <div class="down"><i class="fa fa-chevron-down" aria-hidden="true"></i></div>
      </div>
    </div>`;
  }

  this.init = function(that){
    that.render();
  }(this);
}

var myComponent = new Component('.target');

which basically renders some HTML to a div with the class "target". Now, I want to add an event listener to .up and .down and bind them to the component functions. Which is the correct way of doing this?

You can fork this codepen.

Thanks in advance! PS: I know I can use class and arrow functions, etc. but this is just for testing.

EDIT: Working version. This works but I don't know if it's the correct way of doing it.

3
  • Have you tried anything? Commented Mar 14, 2017 at 17:30
  • I can query the divs after I render them and store them in variables, and then bind them to function but maybe it's not the right way to do it, I just want to know what's the best way to do it, the good practice (: Commented Mar 14, 2017 at 17:32
  • @MatthewHerbst I edited the post with a working solution, but I want to know if it's correct to do it this way. I'd think the correct is binding the event directly from the template string or something like that, but I don't even know if it's possible Commented Mar 14, 2017 at 17:42

1 Answer 1

3

Everyone and their aunt has their own best practice

This would be my approach: codepen

this.target.querySelector('.up').addEventListener('click', this.goUp)
this.target.querySelector('.down').addEventListener('click', this.goDown)

You need to add eventlisteners after the render has taken place. Unless you want to attach events to the target and delegate events with custom logic.

I prefer binds to self/that for eventlisteners

In addition your working version fails with multiple components. Know that you can do .querySelector on an element

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I only have one question, suppose I have +1000 of this components, wouldn't be slow to have two event listeners for each component?
Not really. In practice javascript is fast enough to not be noticeable. If you want to have one even listener for all components you will cause a different problem: You have to listen to all click events then determine what was clicked. The slowest thing in javascript is modifying the DOM. So i suggest you simplify your rendering method of your component. I made some minor optimisations in my example: I moved the Component functions to the prototype so all instances share the same functions, and i updated incrementing functions to update only the div.number's value

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.