I have code like below. I made Javascript class named "Car" and in constructor I add event to html "" tag. But this event can't fire.
Could somebody help me?
Thanks,
A.
function Car(model, brand) {
this.model = model;
this.brand = brand;
document.getElementById('button').addEventListener('onclick', this.info);
}
// method
Car.prototype.info = function() {
alert("It is " + this.model);
};
// define cariable
var car = new Car("RX7", "Mazda");
// Invoke method in html
//car.info();
// second way
window.onload = function() {
var car = new Car("RX7", "Mazda");
};
<button id="button">Click me</button>
The event should be click not onclick.
To bind the context use bind(this) on the event handler function reference.
function Car(model, brand) {
this.model = model;
this.brand = brand;
document.getElementById('button').addEventListener('click', this.info.bind(this));
// ^^^^^^^ ^^^^^^^^^^
}
// method
Car.prototype.info = function() {
alert("It is " + this.model);
};
// define cariable
var car = new Car("RX7", "Mazda");
// Invoke method in html
//car.info();
// second way
window.onload = function() {
var car = new Car("RX7", "Mazda");
};
<button id="button">Click me</button>
I hope this is just for the Demo purpose, if you want to use this in real project use following code.
function Car(model, brand) {
this.model = model;
this.brand = brand;
}
// method
Car.prototype.info = function() {
alert("It is " + this.model);
};
// define cariable
var car = new Car("RX7", "Mazda");
document.addEventListener('DOMContentLoaded', function() {
var car = new Car("RX7", "Mazda");
document.getElementById('button').addEventListener('click', car.info.bind(car));
});
<button id="button">Click</button>
#Tushar
Thank You very much. I wouldn't do this wihtout your help :-)
For someone, who wants have everything "more inside" a class, I prepared some changes in #Tushar code.
But I don't know if it is consistent in any programming standard.
function Car(model, brand) {
this.model = model;
this.brand = brand;
document.getElementById('button').addEventListener('click', this.info.bind(this));
}
// method
Car.prototype.info = function() {
alert("It is " + this.model);
};
document.addEventListener('DOMContentLoaded', function() {
var car = new Car("RX7", "Mazda");
});
<button id="button">Click</button>
Related
Forgot my initial typo in original snippet here is exaly want I trying to do:
How can I use prototyped variable in Dom element event?
Suppose :
function MyProto(){
this.valeur = "toto";
}
MyProto.prototype = {
func1: function() {
var t = document.createTextNode("func1 called ");
document.body.appendChild(t);
var br = document.createElement("br");
document.body.appendChild(br);
this.func2();
},
func2: function() {
var t = document.createTextNode("func2 called");
document.body.appendChild(t);
}
};
var proto = new MyProto();
document.getElementById("myButton").addEventListener("click",proto.func1);
<button id="myButton">Press here</button>
In this example, when I press button it throw me this.func2 is not a function. I must to mention that ultimately the Dom element will be generated by HtmlHelper from Asp.Net MVC.
First Problem
That's just a typo, you are calling funct1 instead of func1
Second Problem (Update)
The problem is when you add the listener your way:
.addEventListener("click",proto.func1)
this will be the clicked element, not your proto instance, to solve this problem you can wrap it in another function clause, like the snippet below.
function MyProto() {
this.valeur = "toto";
}
MyProto.prototype = {
func1: function() {
var t = document.createTextNode("func1 called ");
document.body.appendChild(t);
var br = document.createElement("br");
document.body.appendChild(br);
this.func2();
},
func2: function() {
var t = document.createTextNode("func2 called");
document.body.appendChild(t);
}
};
var proto = new MyProto();
document.getElementById("myButton2").addEventListener("click", function() {
proto.func1()
});
<button id="myButton1" onclick="proto.func1()">First Button</button>
<button id="myButton2">Second Button</button>
Answering the initial question: Fixing the typo works with your inline event
Answering SECOND question - how to use addEventListener and retain this:
Safe solution - wrap call in a function in the event handler:
function MyProto(){
this.valeur = "toto";
}
MyProto.prototype = {
func1: function() {
var t = document.createTextNode("func1 called ");
document.body.appendChild(t);
var br = document.createElement("br");
document.body.appendChild(br);
console.log(this)
this.func2();
},
func2: function() {
var t = document.createTextNode("func2 called");
document.body.appendChild(t);
}
};
var proto = new MyProto();
document.getElementById("myButton1")
.addEventListener("click",() => proto.func1() )
.as-console-wrapper {
height: 125px;
opacity: 0.3;
}
<button type="button" id="myButton1">addEventListener now works</button>
<hr/>
Trials to find how to retain the prototype this when using addEventlListener WITHOUT wrapping in a function.
NOTE button 2 shows the code I wrote which is now used by OP for followup question
function MyProto(){
this.valeur = "toto";
}
MyProto.prototype = {
func1: function() {
var t = document.createTextNode("func1 called ");
document.body.appendChild(t);
var br = document.createElement("br");
document.body.appendChild(br);
console.log(this)
this.func2();
},
func2: function() {
var t = document.createTextNode("func2 called");
document.body.appendChild(t);
}
};
var proto = new MyProto();
document.getElementById("myButton2").addEventListener("click",proto.func1)
document.getElementById("myButton3").addEventListener("click", proto.func1.bind(proto))
.as-console-wrapper {
height: 125px;
opacity: 0.3;
}
<button type="button" id="myButton1" onclick="proto.func1()">Here <i>this</i> is the prototype</button>
<button type="button" id="myButton2">addEventListener has unexpected <i>this</i></button>
<button type="button" id="myButton3">addEventListener bound <i>this</i></button>
<hr/>
I want to override HTMLElement's on-event handler method with Object.defineProperty.
here is the code.
var desc = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'onclick');
var originalGet = desc.get;
desc.get = function () {
console.log('get onclick');
return originalGet.apply(this, arguments);
}
var originalSet = desc.set;
desc.set = function() {
console.log('set onclick', arguments);
return originalSet.apply(this, arguments);
}
The code will work when I add event listener in this way,
var btn = document.getElementById("btn");
btn.onclick = function() {
console.log("button clicked");
}
But will not work when I define the onclick handler in html inline.
<button onclick="btnClick(event)">ok</button>
The getter is called, but setter is not called.
I can't figure out why?
This is page's code.
I can't modify this.
var Example = {};
Example.create = function() {
var obj = new Example.object();
return obj;
}
Example.object = function(){
this.initialize = initialize;
function initialize() {
window.addEventListener('load', activate);
}
function activate() {
document.addEventListener('keypress', keyPressed);
}
function keyPressed(e) {
alert("Hello!");
}
};
Example.defaultObject = Example.create();
Example.defaultObject.initialize();
I have tried many things...
document.onkeypress = null;
document.keypress = null;
document.removeEventListener('keypress');
$(document).unbind('keypress');
$(document).off("keypress");
$("*").unbind('keypress');
$(document).bind('keypress', function(e) { e.stopPropagation(); });
but all failed.
How can I unbind event of document keypress?
You have to pass the listener to remove it: (a variable pointing the function aka the function name)
document.removeEventListener('keypress', keyPressed);
https://developer.mozilla.org/de/docs/Web/API/EventTarget/removeEventListener
You will have to save it somewhere to remove it later
Root cause of the issue is removeEventListener method. This method expect second parameter which is listener method
document.removeEventListener('keypress', Example.defaultObject.keyPressed);
Here you go for Solution on your problem.
var Example = {};
Example.create = function() {
var obj = new Example.object();
return obj;
}
Example.object = function(){
this.initialize = initialize;
function initialize() {
window.addEventListener('load', activate);
document.getElementById('disable').addEventListener('click', deActivate);
}
function activate() {
document.addEventListener('keypress', keyPressed);
}
function deActivate() {
document.removeEventListener('keypress', keyPressed);
document.querySelector('h1').innerHTML = 'Page Key Press Listener Removed';
}
function keyPressed(e) {
alert("Hello!");
}
};
Example.defaultObject = Example.create();
Example.defaultObject.initialize();
<body>
<h1>Page has Key Press Listener</h1>
<input id="disable" type="button" value="deactivate">
</body>
I have a class (I think this is called) and created an object called peter in my code. I now want to level up Peter as follows:
// Define the class
function character(name, level){
this.name = name;
this.level = level;
}
// Create Peter at level 1
var peter = new character("Peter", 1);
// This will display the name of the character, level and a button to level him up
character.prototype.display = function() {
document.getElementById("name").innerHTML += this.name;
document.getElementById("level").innerHTML += this.level;
// This line calls `levelup()` on load which is not what I want
// and clicking the button no more calls `levelup`!
document.getElementById("levelupbutton").onclick = this.levelup();
// This line would call the function on click, but it looks like `this`
// is not being passed down to the function `levelup` so I get NaN on
// this.level down below?
//document.getElementById("levelupbutton").onclick = this.levelup;
};
character.prototype.levelup = function() {
alert("Level up in progress!");
this.level++;
alert(this.level);
}
peter.display();
jsfilldle
I'm probably incorrectly calling the function and I can't seem to figure out how to do it correctly. Can anyone give me some pointers? I'm new to OOP, so if the solution involves something OOP, could you please try to explain it as much as possible?
You need to bind this to levelup and not call it in line to get your desired behavior. Updated your fiddle with the correct answer.
levelupbutton.onclick = this.levelup.bind(this);
function character(name, level){
this.name = name;
this.level = level;
}
var peter = new character("Peter", 1); // Instantiate new objects with 'new'
character.prototype.display = function(){
document.getElementById("name").innerHTML += this.name;
document.getElementById("level").innerHTML += this.level;
document.getElementById("levelupbutton").onclick = this.levelup.bind(this);
};
character.prototype.levelup = function(){
alert("Level up in progress!");
this.level++;
alert(this.level);
}
peter.display();
<span>Character Name:</span> <span id="name"></span><br />
<span>Character Level:</span> <span id="level"></span><br />
<button id="levelupbutton">Level Up!</button>
When attaching a handler function to an element, the value of this inside of the handler is a reference to the element. It is the same as the value of the e.target property of the event argument that is passed to the handler.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#The_value_of_this_within_the_handler
You could use Function.prototype.bind() method which will create a new function that will have its this set to the provided value.
Just attach the click handler like this:
document.getElementById("levelupbutton").addEventListener('click',
this.levelup.bind(this)
);
Why use addEventListener?
addEventListener is the way to register an event listener as
specified in W3C DOM..
Fiddle: http://jsfiddle.net/abhitalks/sjfxorxz/6/
Snippet:
function character(name, level) {
this.name = name;
this.level = level;
}
character.prototype.levelup = function() {
this.level++;
document.getElementById("level").innerHTML += this.level;
}
character.prototype.display = function() {
document.getElementById("name").innerHTML += this.name;
document.getElementById("level").innerHTML += this.level;
document.getElementById("levelupbutton").addEventListener('click',
this.levelup.bind(this)
);
}
var peter = new character("Peter", 1);
peter.display();
<span>Character Name:</span> <span id="name"></span><br />
<span>Character Level:</span> <span id="level"></span><br />
<button id="levelupbutton">Level Up!</button>
Alternatively, you could also save the reference and use that inside an anonymous function call instead of inlining it.
For example:
character.prototype.display = function() {
var self = this;
document.getElementById("levelupbutton").addEventListener('click',
function () {
self.levelup();
});
}
Fiddle 2: http://jsfiddle.net/abhitalks/sjfxorxz/9/
Snippet 2:
function character(name, level) {
this.name = name;
this.level = level;
}
character.prototype.levelup = function() {
this.level++;
document.getElementById("level").innerHTML += this.level;
}
character.prototype.display = function() {
var self = this;
document.getElementById("name").innerHTML += this.name;
document.getElementById("level").innerHTML += this.level;
document.getElementById("levelupbutton").addEventListener('click',
function () {
self.levelup();
});
}
var peter = new character("Peter", 1);
peter.display();
<span>Character Name:</span> <span id="name"></span><br />
<span>Character Level:</span> <span id="level"></span><br />
<button id="levelupbutton">Level Up!</button>
I want to assign onclick event listener to an object from within a class
and then get some variable from the instance that created that onclick
function myclass() {
this.myvar;
this.myfunc = function()
{
alert(this.myvar);
document.onmousedown = this.mouseDown;
}
this.mouseDown = function(e)
{
alert(this.myvar); //does not work of course
//how could I access myvar from current myclass instance
}
}
var myclass_instance = new myclass();
myclass_instance.myvar = 'value'
myclass_instance.myfunc();
http://jsfiddle.net/E7wK4/
this in the mouseDown event is not the this of the instance.
Try this instead:
function myclass() {
var _this = this;
this.myvar;
this.myfunc = function()
{
alert(this.myvar);
document.onmousedown = this.mouseDown;
}
this.mouseDown = function(e)
{
alert(_this.myvar); //<<<<
}
}
Demo: http://jsfiddle.net/maniator/E7wK4/1/
As an alternative to #Neal you could bind this.
document.onmousedown = this.mouseDown.bind(this);