javascript object prototype call - javascript

b2 and b3 are not triggering the prototype functions and no errors are generated? How does one accomplish calling prototype functions in the fashion?
<html>
<head>
<script type="text/javascript">
function newObj(){
this.obj_val= 7;
}
var trigger_f0 = function(){
alert("here 0"); // trigger FINE! (ok)
}
newObj.prototype.trigger_f2 = function (){ // no triggering off click event
alert("here 2");
}
newObj.prototype.trigger_f3 = function (){ // not triggering off click event
alert("obj value:" + newObj.obj_val);
}
var init = function(){
b3.addEventListener('click', newObj.trigger_f3, false);
b2.addEventListener('click', newObj.trigger_f2, false);
b1.addEventListener('click', trigger_f0, false);
}
window.addEventListener('DOMContentLoaded', init, false);
</script>
</head>
<body>
<button id="b1">B1</button>
<button id="b2">B2</button>
<button id="b3">B3</button>
</body>
</html>

You need to create an instance like to get an object out of the constructor function
var a=new newObj()
and then access the properties.
and change newObj.obj_val to
new newObj().obj_val
function newObj() {
this.obj_val = 7;
}
var trigger_f0 = function() {
alert("here 0"); // trigger FINE! (ok)
}
newObj.prototype.trigger_f2 = function() { // no triggering off click event
alert("here 2");
}
newObj.prototype.trigger_f3 = function() { // not triggering off click event
alert("obj value:" + new newObj().obj_val);
}
var a = new newObj();
b3.addEventListener('click', a.trigger_f3, false);
b2.addEventListener('click', a.trigger_f2, false);
b1.addEventListener('click', trigger_f0, false);
<body>
<button id="b1">B1</button>
<button id="b2">B2</button>
<button id="b3">B3</button>
</body>

When you create a function and add properties to its .prototype, the function doesn't receive them.
Instead, when you create an instance/object using that function as constructor, that object will get the functions.
function foo() {}
foo.prototype.fn = function(){}
var x = new foo()
console.log(foo.fn) // undefined
console.log(x.fn) // function (){}
In your case,
// ...
var obj = newObj();
var init = function(){
b3.addEventListener('click', obj.trigger_f3, false);
b2.addEventListener('click', obj.trigger_f2, false);
b1.addEventListener('click', trigger_f0, false);
}
window.addEventListener('DOMContentLoaded', init, false);

Related

Vanilla Javascript how override added function on event listener?

I have a bootstrap modal that has some custom events, like hidden.bs.modal, depending on where the user does, I want the function in this event to be replaced, maybe it's better to understand with a simple example, consider:
const currentModal; // imagine an any modal here.
window.addEventListener('load', () => {
currentModal.addEventListener('hidden.bs.modal', standardFunction );
});
function standardFunction(){
alert('hi there');
// this is standard output to modal closed
}
function buttonClickedChange(){
// Here, i need override standardFunction
this.standardFunction = function(){
alert('modal event hidden.bs.modal changed with success!');
// this must be override previous output
};
}
What happens is that regardless of the redeclaration of the function, the output for the method is still standard, this is because the eventlistener does not refer to the stored function but only "copy" its content and creates its scope only inside.
The problem you have is when you bind the event, you are referencing that function. When you replace it does not update the reference to that function. You can clearly see that this will not work with the example
var btn = document.querySelector("button");
function myFunc () {
console.log(1);
}
btn.addEventListener("click", myFunc);
myFunc = function() {
console.log(2);
}
<button>Click Will Show 1</button>
Just remove the event listener and bind a new event.
currentModal.removeEventListener('hidden.bs.modal', standardFunction );
currentModal.addEventListener('hidden.bs.modal', myUpdatedFunction );
function myFunc () {
console.log(1);
}
var btn = document.querySelector("button");
btn.addEventListener("click", myFunc);
function myFunc2() {
console.log(2);
}
btn.removeEventListener("click", myFunc);
btn.addEventListener("click", myFunc2);
<button>Click</button>
If for some reason you can not remove the event, the only way around it would not to bind directly to the function, but to have another function call that function.
var btn = document.querySelector("button");
var myFunc = function() {
console.log(1);
}
function clickFunction () {
myFunc();
}
btn.addEventListener("click", clickFunction);
myFunc = function() {
console.log(2);
}
<button>Click</button>
Or how most people would do it is to add the logic into the function on what to do
var btn = document.querySelector("button");
var state = 0;
var myFunc = function() {
if (state===0) {
console.log(1);
} else {
console.log(2);
}
}
state = 1;
btn.addEventListener("click", myFunc);
<button>Click</button>
You used function expressin instead of function declaration. When you use function yourFunction it is moved to the top with all of the other declared functions. When you use var yourFunction = function () it is right there where you declared it. This means that hidden.bs.modal is searching for the top most function with that name which in this case is the first one you declared or the standard one. One of the ways is that you can declare your function in the global scope: function standardFunctionOverride() and add that to the listener.

Function inside event listener triggers only on it's initialization

var init = true;
$('#btn').on('click', delay(function() {
$('#text').append('click');
init = false;
}, 100));
function delay(fn, ms, enabled = true) {
$('#text').append(init);
// if(init) disable delay
let timer = 0;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(fn.bind(this, ...args), ms || 0);
}
}
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<button id='btn'> TRIGGER </button>
<div id="text"></div>
Init is a global variable which is meant to be used inside delay function to disable delay (init true/false) only on event listener initialisation.
The problem is that the delay function is triggered only once and ignores the change (to false) of the init variable.
For example, try clicking the trigger button. The init variable value is printed only for the first time.
You are calling the delay function in a wrong way in the click handler. You have to call it like so:
$('#btn').on('click', function () {
delay(function() {
$('#text').append('click');
init = false;
}, 100);
});
You will have to check for the value of init inside the function, like this:
$('#btn').on('click', delay(function() {
if(init) {
$('#text').append('click');
init = false;
}
}, 100));
At the moment I don't know why append is not working but with a little workaround you can obtain what you want. Concatenate the original text and the actual one and use text() to set it again:
var init = true;
$('#btn').on('click', function() {
$('#text').text(init);
setTimeout(myDelay, 5000);
});
function myDelay() {
let originalText = $('#text').text();
init = false;
console.log("init is false");
console.log("original text displayed: " + originalText);
$('#text').text(originalText + " " + init);
}
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<button id='btn'> TRIGGER </button>
<div id="text"></div>

javascript: toggle event listener with onclick

I have this JS function which I'm trying to toggle on and off when clicked on the object with the myFunc() function on it. The trouble I'm having is that by the time the code reaches the first if(myVar)/else part and tries to do the handler it has already switched the myVar variable to false. What should I change to correct my logic error?
<script type="text/javascript">
var myVar = true;
function myFunc(myElement) {
var ele = myElement;
var myHandler = function(event) {
if(myVar) {
// do something
} else {
// do something else
}
}
if(myVar) {
window.addEventListener('mousemove', myHandler, false);
myVar = false;
} else {
window.removeEventListener('mousemove', myHandler, false);
myVar = true;
}
}
</script>
...
<body>
<div id="div1" onclick="myFunc(this)"></div>
</body>
I think this is what you are looking for:
var myVar = false;
function myHandler(event) {
if (myVar) {
console.log('do something');
}
}
function myFunc(myElement) {
var ele = myElement;
myVar = !myVar;
if (myVar) {
window.addEventListener('mousemove', myHandler, false);
} else {
window.removeEventListener('mousemove', myHandler, false);
}
}
<button onclick="myFunc(this)">click me</button>
Tell me if there is something you're not understanding in this code.
Why does myHandler need to check the value of myVar? According to your logic, myVar will always be false when myHandler runs, because you're always setting it to false when you add the event listener. myVar will only ever be set to true when you remove the event listener, so myHandler will never run when myVar is true.
You can remove the if(myVar)/else from myHandler since myVar will always be false there.
you can achieve this by 2 methods
method 1:
<body>
<div id="div1">div</div>
</body>
<script type="text/javascript">
var myVar = false;
var myHandler = function() {
myVar = !myVar;
}
document.getElementById('div1').addEventListener('click', myHandler);
</script>
method2:
<body>
<div onClick="myHandler()">div</div>
</body>
<script type="text/javascript">
var myVar = false;
var myHandler = function() {
myVar = !myVar;
}
</script>
hope you have found what you are looking for.

How to unbind document keypress event with anonymous function

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>

one button calls two different functions on different clicks

<script>
function one() {
blah blah blah
}
function two() {
blah blah blah
}
</script>
<button onclick="one(); two()">Click Me</button>
This will call the two functions at the same time. What I want is to call function one() on the first click and then call function two() on the second click. Calls function three() on 3rd click and so on until 7th click
I would prefer to not use jQuery if possible
You can use an IIFE to accomplish this:
var fn3 = (function() {
var first = true;
return function() {
first ? fn1() : fn2();
first = !first;
}
})();
function fn1() {
console.log(1);
};
function fn2() {
console.log(2);
};
<button onClick="fn3()">click</button>
The solution is not too complex, you can just one() and two() from another function.
var callOne = true;
function one() {
alert('Call one');
}
function two() {
alert('Call two');
}
function call(){
if(callOne) one();
else two();
callOne = !callOne;
}
<button onclick="call();">Click Me</button>
One simple way of doing this is to reassign the onclick value:
<button id="clickme">Click Me</button>
<script>
function one() {
alert('one clicked');
document.getElementById('clickme').onclick = two;
}
function two() {
alert('two clicked');
}
document.getElementById('clickme').onclick = one;
</script>
Using this trick you have the option to disable the button after calling two():
document.getElementById('clickme').onclick = null;
Toggle the click handler back to one():
document.getElementById('clickme').onclick = one;
Or do anything else you want.
I'll do it like bellow
On click of the button have a function which decides which function to call according to number of times.
<button onclick="decideFunction()">Click Me</button>
var times = 0;
var one = function(){
alert('first time');
}
var two = function(){
alert('After first');
}
var decideFunction = function(){
if(times == 0){
one();
times++;
}
else{
two();
}
}
So first time it will execute function one and second time onwards it will execute function two.
The simplest way is defining an extra variable to false(or true, of course). While our variable is false, clicking button calls first function and changes the variable to true. On second click, our onclick function checkes the variable value and calls the function which we defined for true value.
var button = document.getElementById('button');
var x = false;
button.addEventListener('click', function(){
if(!x){
alert('function 1');
x = true;
}else{
alert('function 2');
x = false;
}
})

Categories

Resources