Run a function when another function is called - javascript

I'm wondering how to run a function when another function is called. addEventListener only runs events like "click", "mouseover", etc. However, I'd like to listen for a function call.
EXAMPLE:
Function 1 is called. Afterwards, Function 2 runs because it saw that Function 1 was called.
Is there an addEventListener alternative for simple functions and not events? I can't seem to find any.
My goal was to simply run a function everytime a user did something like call for when something was hidden in jQuery or by another JavaScript library or just simply another external JavaScript file with some code I added in.

Introducing a very hacky way
Since what you are trying to achieve is basically hacking some existing system (you shouldn't run into this problem if you have control over both sides and design your code properly).
It looks like your function is declared globally as well. In that case:
1. store the existing function in a variable
2. overwrite that function with your implementation
3. call the function variable at the start
function myFunction(){
//This is the main function
alert('Hello, this is part of the message!');
}
var tempfunc = myFunction;
window.myFunction = function() {
tempfunc();
// do what you need to do in the event listener here
alert('Hello, this is the other part of the message!');
}
EDIT:
The original question had the requirement that the original function cannot be modified, hence my solution. Since they it appears the question has changed.

You will have trigger an event inside myFunction and listen to that event.
function myFunction(){
//This is the main function
alert('Hello, this is part of the message!');
// trigger the event
var event = new CustomEvent("event", { "detail": "Example of an event" });
document.dispatchEvent(event);
}
// handle here;
document.addEventListener("event", function(){
//This is the secondary function
//or the function I need to run after the main function is called
alert('Hello, this is the other part of the message!');
});
// call main
myFunction();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Simple test!</p>
<p>Long story short, you get message 1, but message 2 never pops up!</p>

Is there an addEventListener alternative for simple functions and not
events? I can't seem to find any.
My goal was to simply run a function everytime a user did something
like call for when something was hidden in jQuery or by another
JavaScript library or just simply another external JavaScript file
with some code I added in.
You can use jQuery.Callbacks()
var callbacks = $.Callbacks();
function handleCallback1(message) {
console.log(message, this)
};
function handleCallback2(message) {
if (this.tagName === "DIV") {
this.style.color = "green";
} else {
this.nextElementSibling.style.color = "blue";
}
};
$("button, div").on("click", function() {
callbacks.fireWith(this, ["called from " + this.tagName])
});
callbacks.add(handleCallback1, handleCallback2);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<button>click</button>
<div>click</div>

Related

Is there a way to call function defined inside onload from an external file

Following is a sample code created based on the scenario. showData() function is defined inside a javascript load function. I wanted to call showData() from another file maybe on a button click. I know this will work if the showData is made global. It's not possible to make the function global, as in this scenario it's a dynamically generated code. Is there anyway in JS that allows to call such functions ?
// Not possible to change the structure of this file as its coming dynamically
window.addEventListener("load", function() {
showData(); // 1st time call
function showData() {
console.log('starting execution')
}
});
// Calling from another file
showData(); // 2nd time call - not possible
No.
The function is declared inside another function. Its scope is that function.
Unless you change that code to make it a global, it isn't accessible from outside the containing function at all.
If the structure of the code can't be changed, perhaps you could try attaching your function to the global window object, like:
window.addEventListener("load", function() {
// attached to window
window.showData = function() {
console.log('starting execution')
};
window.showData(); // 1st time call
});
// Calling from another file
window.showData();
But make sure the second call (from the other file) has a little bit of a delay (remember the eventListener has to be attached to the window first, before the function becomes available).
You could try:
// second call
setTimeout(function() {
window.showData();
}, 1000);

Javascript - Is it possible to make a function call itself after definition and then be referenced as a function elsewhere in scope

Consider the following:
(function () {
var _searchUsers = function () {
console.log("Searching...");
};
var search = (function () {
_searchUsers();
this = function () {
_searchUsers();
}
})();
//Some onclick event handler
function click () {
search();
}
})();
Is there a more concise way of achieving this feature in javascript? I want to declare a function and have it execute straight away and that's why I've made it an IIFE (self executing function) but I also want to reference that function elsewhere in scope later on the in the lifetime of the script, say when a user clicks a button and the "click" function is invoked above.
Example use-case:
I have a table of users, on page load I want to make an AJAX request to go and fetch the users immediately, I also want the user's to be able to load the users at a click of a button, let's say I have a search box which sends that text up to my API and returns user's who's name matches the given text.
The above snippet handles this requirement, I'm just wondering if there is a more concise method to achieve this, and i'm also just interested to see what people post as an answer.
This is another option:
(function () {
var _searchUsers; // Declare the variable like you did already
(_searchUsers = function (){ // Assign the function, and immediately call it.
console.log("Searching...");
})();
//Some onclick event handler
function click () {
_searchUsers();
}
})();
Mostly I see this being implemented like a named IIFE function that returns it self after the execution. So that it can be used later on scope because it is a named function.
(function () {
onClick(function MyFunction(){
// logic code goes here
return MyFunction;
}());
})();

Javascript : Replace Event Listener

I am listening to an event and want to call different methods. For example, I am listening to animation end event and the code is something like this:
this.inAnimationCallback = function() {
console.log('In');
_this.elem.className = _this.settings.className;
};
this.outAnimationCallback = function() {
console.log('Out');
_this.elem.parentNode.removeChild(_this.elem);
};
this.elem.addEventListener(animationEvent, this.inAnimationCallback);
setTimeout(function() {
_this.elem.addEventListener(animationEvent, _this.outAnimationCallback);
// Call some animation here.
}, 3000);
What happens here is that instead of replacing the method attached to the event, JS adds the method and when animation ends, both methods are called. Console looks like this:
(2) In
Out
I'm writing this answer for those like me, who is just started learning JS. And this thread came up first in google to "js replace event listener"..
Although, I am not disagreeing with the answers to use removeEventListener(), but mozilla warns that this function is not always successful. So use it with care. not willing to go that road i have found two other ways to do it.
Use something like GlobalEventHandlers which is simple as target.onclick = functionRef;. Mozilla even warns:
Only one onclick handler can be assigned to an object at a time.
Within listener function add external function call to action function, and then replace reference to another external action function. For example this code will call firstAction(), then seconAction(), then first again...:
const buttonOne = document.getElementById('buttonOne');
buttonOne.addEventListener('click', listenerFunction);
let doAction = firstAction; //assigning doAction to firstAction
function listenerFunction() {
doAction(); //external function call
}
function firstAction() {
doAction = secondAction; //assigning doAction to secondAction
console.log('first action clicked');
}
function secondAction() {
doAction = firstAction; //assigning doAction to firstAction
console.log('second action clicked');
}
<button type="button" id="buttonOne" name="button">button1</button>
I wrote this answer to broaden solution scope: would have saved at least 6 hours of my time. If I had this in the first place...
You can just remove the event listener before adding the new one :
setTimeout(function() {
_this.elem.removeEventListener(animationEvent, _this.inAnimationCallback);
_this.elem.addEventListener(animationEvent, _this.outAnimationCallback);
// Call some animation here.
}, 3000);

Ending an Event Driven Function in JavaScript

I am using JavaScript with HTML5. When the user clicks on a button, an event-driven JavaScript function starts up. When the user clicks on the button again, another instance of this function starts up. So I have two instances of the same function handling a event. However I only want the new instance to be running. How do I end the first instance of the?
An example is a function with the following code
Canvas.paper = Raphael(xOffset,yOffset,imageWidth,imageHeight);
masterBackground = Canvas.paper.rect(0,0,imageWidth,imageHeight);
window.onkeydown=function(e){
// Event handler code
}
document.addEventListener('keydown', function(event) {
// Event handler code
}
masterBackground.mousemove(function(e){
// Event handler code
}
Seems apparent that something asynchronous and long-running is happening.
To prevent concurrent instances from running, just use a flag that is set when one starts so that others can't begin. Then when the current one finishes, reset the flag so that another can start.
// Immediately invoked function, makes a variable and returns the handler
// that uses the variable as a flag.
button.onclick = (function() {
// local variable, only accessible to the returned handler
var running = false;
// This is your event handler.
return function(e) {
if (running === false) {
running = true;
// run your asynchronous operation
// after it's complete, set `running = false;`
}
};
})();
There are several solutions to this, some of them library dependent, but "nicer" to look at:
For example, using jQuery:
<button>Click me</button>
<script>
$('button').on('click', handleButtonClick);
function handleButtonClick() {
$(this).off('click', handleButtonClick); //disable click event
//do various things you don't want duplicated
$(this).on('click', handleButtonClick); //reattach handler
}
</script>
OR:
<button>Click me</button>
<script>
$('button').once('click', handleButtonClick); //attach one-time handler
function handleButtonClick() {
//do various things you don't want duplicated
$(this).once('click', handleButtonClick); //attach one-time handler
}
</script>
Most libraries support similar methods, if you'd rather do it vanilla JS, that is definitely possible of course as well. "am not i am" provided a nice example for that: https://stackoverflow.com/a/15976888/622129
var buttonView = document.getElementById('buttonView');
buttonView.handleEvent = function(event) {
window.alert(this.id);
//this.onclick = null;
};
buttonView.onclick = buttonView.handleEvent;
Try it out: http://jsfiddle.net/KHQ4y/
Edit: I posted this before you supplied your specific code, but you get the idea.
If you want to make sure a function only runs once:
example based on benny's example
function onlyOnce(proc){
return function () {
var result = proc.apply(this,arguments);
proc = function () {};
return result;
}
}

Why is function() needed sometimes in JavaScript?

HTML
<button id='hello'>Click Me!</button>
JavaScript (wrong)
$('#hello').click(alert('Hello, World!'));
JavaScript (correct)
$('#hello').click(function() {
alert('Hello, World!');
}
I'm wondering why the first JS code triggers on the event load instead of click. Can anyone tell me why function() { [code] } is needed for the script to work properly?
In this example, I used jQuery events, but this is not specific to it, for example, I need to use it with setTimeout, too.
The click function expects another function as a parameter.
In the first case you would be passing the result of calling alert('hello world');, which is null.
The second is just a shorthand for:
$('#hello').click(callback);
function callback(){
alert('hello world');
}
Because .click() is a handler. The first argument is a function to assign. But if you actually pass the function with arguments then it will call the function (in this case alert) and then pass it's return value.
Writing $('#hello).click( function() { } )` is basically a short hand for writing:
var myfunction = function() {
// code
};
$('#hello').click( myfunction );
As you can see in the long hand way, it's passed as a reference to the function instead of the function's return value.
Your first example says "evaluate
alert('Hello, World!')
right now, and pass the result as an argument to click. "
The second says "Define a function which will do the alert when I call it, and pass that whole function as an argument to click.
The function() { ... } syntax is how you declare an anonymous function in Javascript. jQuery uses lots of these to specify that some action will be performed later, like when an event occurs. You can think of it as delaying the execution of your function until necessary. Without this syntax, whatever code you place there is evaluated immediately, which is not what you want for an event handler.
You might think, "why isn't JavaScript smart enough to know the difference?" Consider this:
function returnCallback(linkId, data) {
return function(e) {
alert('Clicked on ' + linkId + '. Here is some data: ' + data);
// Maybe do some stuff with e, the event parameter
}
}
$('#some-link').click(returnCallback('some-link', 'some-data'));
$('#other-link').click(returnCallback('other-link', 'different-data'));
This is a contrived example, but it illustrates the power of anonymous functions and closures. This works since returnCallback returns a function.
In the first instance, "JavaScript wrong", you're actually calling alert('Hello, World!') at the point that the script is loaded. Now, the reason you pass the .click function a function is because it can call it at any point. Essentially, you're packing code together to be run (or not run at all) at any point when you put it in a function.
$('#hello').click(alert('Hello, World!')); is attempting to run alert('...') and pass its return value to the .click() function which will not work as expected.
This is because JavaScript evaluates everything and during this process your alert is invoked. You can use anonymous function or you can also use your own custom function as implemented below:
<script language="javascript" type="text/javascript">
$("#mybutton").click(clickFired);
function clickFired() {
alert('click fired');
}
</script>
The parameter required for the .click() function is a Function. Therefore $("#hello").click(function { [code] }); is required. Because there's nothing to return by alert().
The click function here assigns a value to the event handler.
With the first ("wrong") code you're assigning a value of alert('Hello, World!') which is itself a function call, so it's going to be immediately evaluated and hence appear at load.
With the second ("correct") code you're now assigning a new anonymous function which is not executed itself, just instantiated at load. Hence this will work as expected later.
somefunction(alert('hello! world'));
this would mean you want to pass to somefunction the return value of alert("hello! world").
jquery click expects a callback that it should fire upon click on the element. so you put it in a function which does not execute unless someone (here jquery) calls it explicitly.

Categories