Reputation: 109
I have two classes, one of which is a subclass of the other. What I want to do is have one of the functions, step, invoked when the subclass is instantiated. This will cause the subclass to blink. I can see how to do it with functional instantiation but not with pseudoclassical. I've attached the jquery and javascript. Basically, when the button is clicked, I want the blinky dancer to blink, this should happen via the step function. Maybe I'm calling it incorrectly in the dancer superclass?
$(document).ready(function() {
window.dancers = [];
$('.addDancerButton').on('click', function(event) {
var dancerMakerFunctionName = $(this).data('dancer-maker-function-name');
console.log(dancerMakerFunctionName);
var dancerMakerFunction = window[dancerMakerFunctionName];
var dancer = new dancerMakerFunction(
$("body").height() * Math.random(),
$("body").width() * Math.random(),
Math.random() * 1000
);
$('body').append(dancer.$node);
});
});
var makeBlinkyDancer = function(top, left, timeBetweenSteps) {
makeDancer.call(this, top, left, timeBetweenSteps);
};
makeBlinkyDancer.prototype = Object.create(makeDancer.prototype);
makeBlinkyDancer.prototype.constructor = makeBlinkyDancer;
var oldStep = makeBlinkyDancer.prototype.step;
makeBlinkyDancer.prototype.step = function() {
oldStep();
this.$node.toggle();
};
var makeDancer = function(top, left, timeBetweenSteps) {
this.$node = $('<span class="dancer"></span>');
};
makeDancer.prototype.step = function() {
setTimeout(step.bind(this), timeBetweenSteps);
};
makeDancer.prototype.setPosition = function (top, left) {
var styleSettings = {
top: top,
left: left
};
this.$node.css(styleSettings);
};
// makeDancer.prototype.setPosition();
Upvotes: 0
Views: 807
Reputation: 1380
You can call the method when the subclass is instantiated by calling init
in the constructor. In the example and demo I called this method makeBlink
rather than step
or oldStep
. Hope that makes it clear.
// the subclass BlinkyDancer
var BlinkyDancer = function (top, left, height, width, timeBetweenSteps) {
// ... get props from parent class
// make blink when sublcass instantiated
this.init = this.makeBlink();
};
Demo: https://codesandbox.io/s/call-method-when-class-instantiated-mnesxt
<body>
<div id="app">
<button id="make-blink">Make Blink</button>
<button id="stop-blink">Stop Blink</button>
</div>
</body>
import $ from "jquery";
var Dancer = function (top, left, height, width) {
this.$node = $('<div class="dancer"></div>');
this.top = top;
this.left = left;
this.height = height;
this.width = width;
this.bg = "blue";
};
Dancer.prototype.putDancerOnScreen = function () {
this.$node.height(this.height).width(this.width);
this.$node.css("background-color", "blue");
this.$node.css("position", "absolute");
$("body").append(this.$node);
};
Dancer.prototype.setPosition = function () {
this.$node.css("top", this.top);
this.$node.css("left", this.left);
};
var myDancer = new Dancer(
Math.floor(Math.random() * 500),
Math.floor(Math.random() * 500),
50,
50
);
myDancer.putDancerOnScreen();
myDancer.setPosition();
// the subclass BlinkyDancer
var BlinkyDancer = function (top, left, height, width, timeBetweenSteps) {
Dancer.call(this, top, left, height, width); // get the props set up by Dancer
this.timeBetweenSteps = timeBetweenSteps;
this.blinkerId = null;
// make blink when sublcass instantiated
this.init = this.makeBlink();
};
// set inheritance and Dancer constructor function
BlinkyDancer.prototype = Object.create(Dancer.prototype);
BlinkyDancer.prototype.constructor = Dancer;
// add subclass methods
BlinkyDancer.prototype.makeBlink = function () {
if (this.blinkerId !== null) {
return;
}
let count = 0;
let blinkerId = setInterval(() => {
// do whatever thing you want to indicate blinking/dancing
if (count % 2 === 0) {
this.$node.css("background-color", "red");
} else {
this.$node.css("background-color", "blue");
}
count++;
}, this.timeBetweenSteps);
this.blinkerId = blinkerId;
console.log("blinkder id set: ", this.blinkerId);
};
BlinkyDancer.prototype.stopBlink = function () {
if (this.blinkerId === null) {
// already blinking
return;
}
if (this.blinkerId !== null) {
clearInterval(this.blinkerId);
console.log("blink id cleared: ", this.blinkerId);
this.blinkerId = null;
}
};
// instantiate a new subclass
let myBlinkyDancer = new BlinkyDancer(
Math.floor(Math.random() * 500),
Math.floor(Math.random() * 500),
50,
50,
25
);
// use parent class methods to put the element on screen
myBlinkyDancer.putDancerOnScreen();
myBlinkyDancer.setPosition();
const makeBlinkButton = document.getElementById("make-blink");
const stopBlinkButton = document.getElementById("stop-blink");
makeBlinkButton.addEventListener("click", function () {
myBlinkyDancer.makeBlink();
});
stopBlinkButton.addEventListener("click", function () {
myBlinkyDancer.stopBlink();
});
The Dancer
class takes some props related to positioning and dimensions. It gets a blue background and has two methods for adding the element to the DOM and setting the position on screen.
BlinkyDancer
is a subclass that inherits all the props of Dancer
as well as two new props and two new methods.
What I want to do is have one of the functions, step, invoked when the subclass is instantiated.
When a new BlinkyDancer
is instantiated, we call makeBlink
right away with init
so the element starts blinking.
// make blink when sublcass instantiated
this.init = this.makeBlink();
I used an alternating background color to demonstrate the blinking effect.
The makeBlink
and stopBlink
methods work in tandem with the new props timeBetweenSteps
and blinkerId
.
when the button is clicked, I want the blinky dancer to blink, this should happen via the step function.
Buttons are wired up to trigger starting and stopping the blinking effect. I've replaced step
in your example with simple and declarative methods for making the blink and stopping it.
makeBlinkButton.addEventListener("click", function () {
myBlinkyDancer.makeBlink();
});
The blinking effect uses setInterval
to toggle the background color using the timeBetweenSteps
prop as the interval duration. startBlink
starts the interval and sets blinkerId
to the corresponding interval ID. To stop the blinking effect, clearInterval
is passed the blinkerId
to clear it (stopping the blinking effect) before resetting it to null.
BlinkyDancer.prototype.makeBlink = function () {
if (this.blinkerId !== null) {
return;
}
let count = 0;
let blinkerId = setInterval(() => {
// do whatever thing you want to indicate blinking/dancing
if (count % 2 === 0) {
this.$node.css("background-color", "red");
} else {
this.$node.css("background-color", "blue");
}
count++;
}, this.timeBetweenSteps);
this.blinkerId = blinkerId;
console.log("blinkder id set: ", this.blinkerId);
};
BlinkyDancer.prototype.stopBlink = function () {
if (this.blinkerId === null) {
// already blinking
return;
}
if (this.blinkerId !== null) {
clearInterval(this.blinkerId);
console.log("blink id cleared", this.blinkerId);
this.blinkerId = null;
}
};
Maybe I'm calling [
step
] incorrectly in the dancer superclass?
It looks like you were on the right track but missing parens to call the method. In your example code, rather than:
makeBlinkyDancer.prototype.step;
You would do:
makeBlinkyDancer.prototype.step();
Upvotes: 1