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);
Related
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'm using Mootools and I have two classes (class1, class2), class2 is used in class1
class2 get two methods (func1, func2)
func1 is used to display elements and is call in class1
func2 is used is one of the func1 displayed element is clicked.
I'd like to get an event in class1 if func2 is called but I don't know how.
Thanks for your help.
Edit: some code example
var Class1 = function(){
var class2 = new Class2();
class2.func1();
class2.onElementsHide(function(){
alert('elements are invisibles !!')
});
}
var Class2 = function(){
this.func1 = function(){
//show elements
elementOnClick(this.func2)
}
this.func2 = function(){
//hide elements
}
this.onElementsHide = function(callback){
//trigger callback when func2 is used
}
}
Take a look at MDN's article about creating and triggering events
Basically do something like the following:
var Class1 = function(){
var class2 = new Class2();
class2.func1();
class2.onElementsHidden(function(){
alert('elements are invisibles !!')
});
}
var Class2 = function(){
//Create a custom event
var ElementsHiddenEvent = new Event("ElementsHidden");
this.func1 = function(){
//show elements
elementOnClick(this.func2)
}
this.func2 = function(){
//hide elements
//Dispatch the event
document.dispatchEvent(ElementsHiddenEvent);
}
//Sets a listener for the event
this.onElementsHidden = function(callback){
//make sure the callback is a function
if(typeof(callback)!=="function") return;
//Set a listener for the custom event, and set it to execute callback
document.addEventListener("ElementsHidden",callback);
}
}
You mean this?
var Class1 = function(){
var class2 = new Class2();
class2.func1();
class2.onElementsHide(function(){
alert('elements are invisibles !!')
});
}
var Class2 = function(){
this.cb = function(){};
this.func1 = function(){
//show elements
elementOnClick(this.func2)
}
this.func2 = function(){
//hide elements
this.cb(); //<<Added
}
this.onElementsHide = function(callback){
//trigger callback when func2 is used
this.cb = callback; /// <<Added
}
}
I've this piece of code:
function ActivityDialog(_divId, _title) {
function addButton() {
var buttonElement = document.createElement('input');
buttonElement.setAttribute('type','button');
buttonElement.setAttribute('class','button');
buttonElement.setAttribute('id','updateButton-' + id););
buttonElement.onclick = this.updateAction;
};
function updateAction() {
var buttonId = this.id; // correct: this is the Button
this.sendUpdateRequest(stringUrl); // not defined: Need to reference the current ActivityDialog!!!
};
function sendUpdateRequest(url) {
// something...
};
}
As you can see the problem is when I call function sendUpdateRequest; how can I, at the same time, retrieve button infos and call a function?
You might try this...
function ActivityDialog(_divId, _title) {
// Store the ActivityDialog context
var self = this;
function addButton() {
var buttonElement = document.createElement('input');
buttonElement.setAttribute('type','button');
buttonElement.setAttribute('class','button');
buttonElement.setAttribute('id','updateButton-' + id););
buttonElement.onclick = this.updateAction;
};
function updateAction() {
var buttonId = this.id;
self.sendUpdateRequest(stringUrl); // <---------------------
};
function sendUpdateRequest(url) {
// something...
};
}
Because your using updateAction as a event handler, you correctly see that this will be the button that generates the event. Storing the initial context of the ActivityDialog will allow you to maintain access to it even within event handlers.
I have a pseudo-class in javascript that has a method to add and remove listeners to two buttons.
This is the code:
function FirstObj(secondObj){
this.loginButton = document.getElementById("login");
this.logoutButton = document.getElementById("logout");
this.secondObj = secondObj
}
FirstObj.prototype = {
manageListeners : function(state){ //state is a boolean
var self = this;
if (state) {
display += "none";
this.loginButton.addEventListener("click", function(){
self.seconfObj.makeSomething();
}, false);
this.logoutButton.removeEventListener("click", /*???*/ , false);
}
else {
this.logoutButton.addEventListener("click", function(){
self.logout();
}, false);
this.loginButton.removeEventListener("click", /*???*/ , false);
}
},
logout : function(){
//logout...
}
}
the question is: how i could modify this code to manage event listener correctly?
I don't think you can remove an event listener for an anonymous function. Use named functions instead:
var myEventListener = function() {
console.log("Hello World!");
};
myElement.addEventListener("click", myEventListener, false);
myElement.removeEventListener("click", myEventListener, false);
Here is a slightly modified version of your class that should manage the event listeners properly:
function FirstObj(secondObj){
var self = this;
this.loginButton = document.getElementById("login");
this.logoutButton = document.getElementById("logout");
this.secondObj = secondObj;
this.loginButtonClicked = function(){
self.secondObj.makeSomething();
};
this.logoutButtonClicked = function(){
self.logout();
};
}
FirstObj.prototype = {
manageListeners : function(state){
if (state) {
display += "none";
this.loginButton.addEventListener("click", this.loginButtonClicked, false);
this.logoutButton.removeEventListener("click", this.logoutButtonClicked, false);
}
else {
this.logoutButton.addEventListener("click", this.logoutButtonClicked, false);
this.loginButton.removeEventListener("click", this.loginButtonClicked, false);
}
},
logout : function(){
// Log out...
}
};
If you rewrite your class to take advantage of closures, though, you can simplify it to this:
function FirstObj(secondObj){
var self = this;
var loginButton = document.getElementById("login");
var logoutButton = document.getElementById("logout");
var loginButtonClicked = function(){
secondObj.makeSomething();
};
var logoutButtonClicked = function(){
self.logout();
};
this.manageListeners = function(state){
if (state) {
display += "none";
loginButton.addEventListener("click", loginButtonClicked, false);
logoutButton.removeEventListener("click", logoutButtonClicked, false);
}
else {
logoutButton.addEventListener("click", logoutButtonClicked, false);
loginButton.removeEventListener("click", loginButtonClicked, false);
}
};
this.logout = function(){
// Log out...
};
}
Here I've assumed that loginButton, logoutButton, and secondObj don't need to be accessed from outside the class. If they do, just make them properties of FirstObj and update the code that references them (using this in scope and self out of scope).