How to unbind document keypress event with anonymous function - javascript

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>

Related

Call function in prototype from other prototype

I have two prototypes in my jquery script :
script1.prototype.initScript = function() {
//first one
this.saveGrid = function () {
alert("here");
}
};
script1.prototype.otherFunction = function () {
//second
//script1.initScript.saveGrid ?
};
I'd like to call saveGrid in otherFunction. How can I do that?
Edit :
And there ?
script1.prototype.initScript = function() {
//first one
this.saveGrid = function () {
alert("here");
}
};
script1.prototype.otherFunction = function () {
//second
$('button').on("click", function(){
//call savegrid here
});
};
Thanks.
You can access the function over this, like you already did in you example while creating the function saveGrid.
You should instead ask yourself, if this is a good idea, to create a function in another function and re-use them elsewere. What will happen, if you call otherFunction before initScript?
function script1() {}
script1.prototype.initScript = function() {
this.saveGrid = function() {
alert("here");
}
};
script1.prototype.otherFunction = function() {
this.saveGrid();
};
var s = new script1();
s.initScript();
s.otherFunction();
For you second example you have to store this before creating your event listener.
function script1() {}
script1.prototype.initScript = function() {
this.saveGrid = function() {
alert("here");
}
};
script1.prototype.otherFunction = function() {
var that = this;
$('button').on("click", function(){
that.saveGrid();
});
};
var s = new script1();
s.initScript();
s.otherFunction();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>click me</button>
Prototype It depends on the type .
the correct way is defined as a prototype , so you can call them in different situations
script1.prototype.saveGrid=function () {
alert("here");
}
script1.prototype.initScript = function() {
//first one
this.saveGrid()
};
script1.prototype.otherFunction = function () {
//second
//this.saveGrid()
};`
or you can define an object which then associates the prototypes
var script1=(function () {
function initScript(){
this.saveGrid();
}
function otherFunction(){
this.saveGrid();
}
script1.prototype.saveGrid=function () {
alert("here");
}
});

Override (wrap) an existing jQuery click event with another in javascript

Say I have an existing button and attach a click to it via jQuery:
var $button = $('#test').click(function () { console.log('original function') });
Now, say I want to override that click so that I can add some logic to the function before and after it. I have tried binding and wrapping using the functions below.
Function.prototype.bind = function () {
var fn = this;
var args = Array.prototype.slice.call(arguments);
var object = args.shift();
return function () {
return fn.apply(object, args.concat(Array.prototype.slice.call(arguments)));
}
}
function wrap(object, method, wrapper) {
var fn = object[method];
return object[method] = function() {
return wrapper.apply(this, [fn.bind(this)].concat(
Array.prototype.slice.call(arguments)));
}
}
so I call wrap with the object that the method is a property of, the method and an anonymous function that I want to execute instead. I thought:
wrap($button 'click', function (click) {
console.log('do stuff before original function');
click();
console.log('do stuff after original function');
});
This only calls the original function. I have used this approach on a method of an object before with success. Something like: See this Plunker
Can anyone help me do this with my specific example please?
Thanks
You could create a jQuery function that gets the original event handler function from data, removes the click event, then adds a new event handler. This function would have two parameters (each functions) of before and after handlers.
$(function() {
jQuery.fn.wrapClick = function(before, after) {
// Get and store the original click handler.
// TODO: add a conditional to check if click event exists.
var _orgClick = $._data(this[0], 'events').click[0].handler,
_self = this;
// Remove click event from object.
_self.off('click');
// Add new click event with before and after functions.
return _self.click(function() {
before.call(_self);
_orgClick.call(_self);
after.call(_self);
});
};
var $btn = $('.btn').click(function() {
console.log('original click');
});
$btn.wrapClick(function() {
console.log('before click');
}, function() {
console.log('after click');
});
});
Here is a Codepen
After a long search I reached the same answer as #Corey, here is a similar way of doing it considering multiple events:
function wrap(object, method, wrapper) {
var arr = []
var events = $._data(object[0], 'events')
if(events[method] && events[method].length > 0){ // add all functions to array
events[method].forEach(function(obj){
arr.push(obj.handler)
})
}
if(arr.length){
function processAll(){ // process all original functions in the right order
arr.forEach(function(func){
func.call(object)
})
}
object.off(method).on(method, function(e){wrapper.call(object,processAll)}) //unregister previous events and call new method passing old methods
}
}
$(function(){
$('#test').click(function () { console.log('original function 1') });
var $button = $('#test').click(function () { console.log('original function 2') });
wrap($button, 'click', function (click,e) {
console.log('do stuff before original functions');
click()
console.log('do stuff after original functions');
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id='test'>click me</div>

Function overwritting

Is there any way to overwrite a function or event handling in function?
Using addEventListener, we can have as many event handlers on element as much we want
var test=document.getElementById("div");
test.addEventListener("click",function(){alert("im first");},false);
test.addEventListener("click",function(){alert("im second");},false); // alerts "im first" and after that "im second"
but what if we want to overwrite function/event for example based on client width for example something like this
function one() {
alert("first");
}
function two() {
alert("second");
}
window.onresize = function() {
var test = document.getElementById("div");
if (window.innerWidth > 500) {
test.onclick = one
} else {
test.onclick = two;
}
}
Is something like this possible in javascript?
In this case I would use very effective but very little known approach. addEventListener can accept an object with property handleEvent as event handler. In this case it's very easy to overwrite handler function, set it to null ot completely different function without messing with removeEventListener and addEventListener again and again.
In your case:
var test = document.getElementById("div");
var handlers = {
handleEvent: function () {
alert("im first");
}
};
test.addEventListener("click", handlers, false);
function one() {
alert("first");
}
function two() {
alert("second");
}
window.onresize = function() {
if (window.innerWidth > 500) {
handlers.handleEvent = one;
} else {
handlers.handleEvent = two;
}
}
Check the demo below, resize the pane to see how it dynamically picks up different handlers based on viewport width.
Demo: http://jsfiddle.net/dfsq/t4wrjkLa/
As long as you have a reference to the original handler function, you can call removeEventListener on it, and just add your own listener like normal.
function one()
{
alert('first');
}
var test = document.getElementById('test');
test.addEventListener('click', one);
// Later in your code
function two()
{
alert('second');
}
test.removeEventListener('click', one);
test.addEventListener('click', two);
Demo:
var button = document.getElementById('button');
button.addEventListener('click', function(event)
{
test.removeEventListener('click', one);
test.addEventListener('click', function()
{
alert('second');
});
event.target.parentNode.removeChild(event.target);
});
function one()
{
alert('first');
}
var test = document.getElementById('test');
test.addEventListener('click', one);
#test
{
background: #CCC;
border: solid 1px #666;
padding: 5px;
}
<div id="test">Click me</div> <button id="button">Exchange event listeners</button>
Look at this. You can remove the old event function then replace it with the new event function
function one() {
alert("first");
}
function two() {
alert("second");
}
window.onresize = function() {
var test = document.getElementById("div");
if (window.innerWidth > 500) {
try{
test.removeEventListener("click",two);
} catch{}
test.addEventListener("click",one,false);
}
else {
try{
test.removeEventListener("click",one);
} catch{}
test.addEventListener("click",two,false);
}
}
I would use a closure to reference the function currently set as the event handler:
var onResize = function () {
// references the current handler
var curr;
// removes/adds event handlers
function swap (curr, repl) {
var test = document.getElementById('div');
test.removeEventListener('click', curr);
test.addEventListener('click', repl);
}
// the "resize" event handler which will be
// assigned to the "onResize" variable
return function () {
if (window.innerWidth > 500) {
if (curr !== one) swap(curr, one);
curr = one;
}
else {
if (curr !== two) swap(curr, two);
curr = two;
}
};
}(); // IIFE
window.addEventListener('resize', onResize);
// run "onResize" at starting to
// set up one of the below handlers
onResize();
function one () { alert('first'); }
function two () { alert('second'); }
<div id="div">div</div>

JS - call a parent function

I found this JS code structure and I' wondering how to call the function move() from inside the function load:
JS
function Start(data) {
this.move= function() {
....
};
function load(){
// call move
}
}
function Start(data) {
var _this = this;
this.move = function() {
console.log('mode');
}
function load() {
_this.move();
}
// load();
}
Start();
new Start();
function Start(data) {
this.move = function() {
....
};
function load(obj) {
obj.move();
}
load(this);
}
This is a javascript closure. I've found this site to be helpful.
var move = function () {
alert("move");
};
load();
function load() {
move();
}
This code will alert Move only once.
The function Start() has to be instantiated as an object. So you would use:
function Start(data) {
this.move = function() {
....
};
this.load = function(){
// call move
this.move();
}
}
var s = new Start(foobar);
s.load();
By using closures, that can be acheived by stroing the parent reference;
function Start(data) {
var me = this;
this.move= function() {
....
};
function load(){
me.move();// call move
}
}
Good Luck.

Assign event listener from js class

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);

Categories

Resources