<!DOCTYPE html> <html> <head> <title>Comp 86 Incdec1 example</title> <script> /* ************************************************** * Main class ************************************************** */ class Main { constructor () { // Create some Incdec's for testing this._id1 = new Incdec() maindiv.appendChild (this._id1.getPanel()) // Demonstrate our setBorderColor this._id2 = new Incdec() this._id2.setBorderColor("green") maindiv.appendChild (this._id2.getPanel()) // And a button to report the data from the Incdec's, for testing let b = document.createElement ("button") b.textContent = "Get data" maindiv.appendChild (b) b.addEventListener("click", //*6 New feature () => alert ("Values = " + this._id1.value + //*6 ", " + this._id2.value)) //*6 } } /* ************************************************** * Incdec widget as a class ************************************************** */ class Incdec { //*1 *Have* not *be* a panel constructor () { //*1 /* * We will *have* a captive HTML panel (div), not *be* a panel * also provide public access function to the panel */ this._panel = document.createElement ("div") //*1 /* * Our data, initialized inline here */ this._value = 0 //*2 Our "private" ivars this._min = 0 //*2 this._max = 100 //*2 this._incr = 1 //*2 // Put a border on our panel // default color, user can modify later this._panel.style.borderStyle = "solid" this._panel.style.borderColor = "red" this._panel.style.borderWidth = "1px" // And some spacing this._panel.style.width = "30px" this._panel.style.margin = "4px" this._panel.style.padding = "2px" /* * Our internal widgets, we will save them in ivars */ // Our up button this._upButton = document.createElement("button"); //*3 Create our internal HTML widgets this._upButton.textContent = "+" //*3 this._panel.appendChild (this._upButton); //*3 // Our label widget this._label = document.createElement("div"); //*3 this._refreshLabel (); this._panel.appendChild (this._label); //*3 // Our down button this._downButton = document.createElement("button"); //*3 this._downButton.textContent = "-" this._panel.appendChild (this._downButton); //*3 // Install our callback for both buttons. // Uses "=>" style function def so that "this" will be our object // rather than the HTML button element this._upButton.addEventListener("click", //*4 Callback for both buttons, using arrow syntax (e) => this._actionPerformed (e)) //*4 this._downButton.addEventListener("click", //*4 (e) => this._actionPerformed (e)) //*4 } getPanel () {return this._panel} //*2 /* * Common code fragment, extracted to here */ _refreshLabel () { this._label.textContent = this._value } /* * Common callback for both buttons, as an actual method * e = event, e.target = button widget, this = Incdec because we rigged it above */ _actionPerformed (e) { //*5 Callback method for both buttons if (e.target==this._upButton) this._value += this._incr; //*5 else if (e.target==this._downButton) this._value -= this._incr; //*5 // Clamp at bounds if (this._value > this._max) this._value = this._max; if (this._value < this._min) this._value = this._min; // Update our label widget to match this._refreshLabel (); //*5 } /* * Just as an example, we let user customize border color here * Public method, no "_" */ setBorderColor (color) { this._panel.style.borderColor = color } // New special "getter" syntax // (would work for getPanel() above also) get value () { return this._value; } //*6 } /* ************************************************** * Initialization ************************************************** */ window.onload = function () { new Main () } </script> </head> <body> <div id="maindiv" height="500px" width="100%"> </div> </body> </html>