BenC has provided some great pointers. I will attempt to expand one implicit change and mention a couple other possible changes.
##DOM-ready function change
To be explicit about one thing changed, $(document).ready(function() {
was changed to $(function() {
because the documentation for .ready()
states:
jQuery offers several ways to attach a function that will run when the DOM is ready. All of the following syntaxes are equivalent:
$( document ).ready( handler )
$( "document" ).ready( handler )
$( "img" ).ready( handler )
$().ready( handler )
As of jQuery 3.0, only the first syntax is recommended; the other syntaxes still work but are deprecated.
Your sample code utilizes the 2.0 version of jQuery. Perhaps this is because the snippet lists 2.0 as the highest despite 3.1.1 being available in the same CDN, but if you are still using 2.0, it might be beneficial to upgrade to 3.0+ to take advantage of newer features.
##Closure/lambda function scope on click
BenC mentioned you could use an arrow function and not have to make a separate variable self
to point to this
in the Cat constructor. Another approach is to use Function.bind(). As is illustrated in the code below, call .bind()
after the closing curly-bracket and pass this
:
this.img.click(function() {
this.count++;
this.counter.text(`You clicked ${this.name} ${this.count} times.`);
this.counter.css("font-size", "+=0.5");
}.bind(this));
See this illustrated in the sample below.
##Accessing container div from DOM
BenC re-wrote the code to access the container (i.e. $('#catDiv')
) only once and went so far as to eliminate the Cat class. If you wanted to keep the Cat class, you could still assign that DOM reference once in the DOM ready callback. I would suggest declaring the variable var catDiv
outside the Class and DOm-ready callback:
var catDiv;
Class Cat {
Then it can be assigned in the DOM-ready callback:
$(document).ready(function() {
//now that the DOM is ready, set catDiv here instead of each time Cat constructor is called
catDiv = $('<div></div>');
And then it can be referenced with-in the constructor to add the image and counter elements.
//declare catDiv here so it can be used in the class and DOM ready callback
var catDiv;
class Cat {
constructor(name, picture) {
this.name = name;
this.picture = picture;
this.count = 0;
let mainDiv = $('#cats');
mainDiv.append(catDiv);
this.img = $(`<img src="${this.picture}">`);
catDiv.append(this.img);
this.counter = $('<p></p>');
catDiv.append(this.counter);
this.img.click(function() {
this.count++;
this.counter.text(`You clicked ${this.name} ${this.count} times.`);
this.counter.css("font-size", "+=0.5");
}.bind(this));
}
}
$(document).ready(function() {
//now that the DOM is ready, set catDiv here instead of each time Cat constructor is called
catDiv = $('<div></div>');
new Cat('Kimmy', 'http://newmediarockstars.com/wp-content/uploads/2014/07/femcat.png');
new Cat('Logan', 'http://svoctopussy.com/wp-content/uploads/2013/02/Grumpy-Cat.jpg');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<h1>Cat Clicker</h1>
<div id="cats"></div>