function overriding, onload precedence - javascript

I'm developing some library and created this buggy code:
//-------------------
Gmaps = {};
Gmaps.map = new Gmaps4RailsGoogle(); //there exists a default callback function in the created object
function load_map() {
Gmaps.map.callback();
};
window.onload = load_map();
//--------------------
Gmaps.map.callback = function(){ alert('ok'); }
I thought, because the whole page is loaded, that callback would have been changed and alert message displayed.
But it's not the case and I haven't any error message in firebug.
If I then execute Gmaps.map.callback() in console, it works fine.
Is there any reason why the callback isn't overriden?
For context sake, code between --------- is created by the library but developers would be able to override some functions in his html.

You're not executing load_map onload. You're executing it immediately here:
window.onload = load_map();
and storing it's return value inside window.onload, so nothing is happening onload. Just change that line to:
window.onload = load_map;

Related

Add event listener of a method present in another js file

I am accessing few methods written in another js file. So i'm accessing them like this:
file1:
function minit() {
this.addval = function(val1, val2) {
return val1 + val2;
}
function autoexecute(d) {
//do something here//
//raise event//
}
};
file2:
var con = new minit();
var result = con.addval(2, 3);
/*
con.autoexecute(function(d) { //Wanna do something like this
alert(d);
});
*/
Above things are working as expected, getting result..
Now, Suppose autoexecute(d) method is invoking automatically after a time interval. How can i know if the method is executed ?
So that, I want to create an event(in file2) of autoexecute(d)(in file1).
UPDATE:
I hope this example will help you to understand the issue..
company.js //this is the main file which will be used as a reference in ui.html
function hello(personname) { //this method will invoke automatically after 1 minute..
}
ui.html
<script src="company.js"></script>
<script>
$(document).ready(function() {
function bye(personame) { //this method will be called automatically if hello method invoked.... personame is the argument passed from hello method//
alert("comany.js -> hello function is executed");
}
});
</script>
You can only do this if the functions have the same scope (global scope is the best case scenario). If the autoexecute function has local scope then you cannot to do it.
In essence, override the original function like this...
// keep a reference to the original function
var _autoexecute = autoexecute;
// override the original function with your new one
function autoexecute(d) {
alert("before autoexecute"); // fired before the original autoexecute
_autoexecute(d); // call the original autoexecute function
alert("after autoexecute"); // fired after the original autoexecute
}
Now, whenever autotexecute is called it will call your new function which can handle both before and after events, as well as calling the original function. Just remove the (horrible) alerts and replace with event handlers as required.
To my knowledge, and someone should correct me if I am wrong, there is no way (at least without some library) to detect a function being fired in javascript. Function executions do not fire an event that other functions can 'handle' in that that sense.
In your example you wanted a function to automatically fire after the other function has fired, all you need to do is call the function you want to fire at the end of the one that was "fired" in the first place. Confusing but hope this helps.
function handler(){
alert("main function was fired!");
}
function main(){
//Code of main goes here and then at the end just add:
handler();
}
Now when your "main" has finished its work it will call upon the handler function.
Regardless of where you define the handler function, which can be a different file or same file, so long as it is reachable from within the main's scope, it will be fired at the end of it. It can even be declared after main has been declared, so long as it is declared before main is fired.

Function is not being loaded unless resize or click function is used

I want to execute a function which was defined in the start of the script, lets call this function initialize. This function also uses a variable, lets call it login, which is defined by a php file that includes my jquery script file after defining the variable login.
php/html:
<script type="text/javascript">
login = '<?php echo $login; ?>';
...
</script>
<!-- script is included -->
<script type="text/javascript" src="script.js"></script>
jquery:
function initialize(){
$("." + login).remove();
}
jQuery.moreContent = function moreContent()
{
//more content is loaded
...
initialize();
}
the moreContent function is then loaded, I can see more content appearing on my screen but initialiye is not loaded. only if I use a function like resize (in the end of the script.js file) it works
jquery (in the end of script):
//load function initialize
initialize();
//this function doesnt work too, I tested if it even loads and it does (used a number that was increased by one whenever function was loaded which actually happened...)
//however the wished element with the class of variable login is not removed
//resize function
$(window).resize(initialize);
//this one suddenly works
...
I have no idea why it suddenly works with the other function and why it doesnt work in the other cases
You need to wrap your code and make it run once the document is ready, like this:
$(document).ready (function(){
// run all your functions here
});
Maybe the variable login is empty in the other function, or you are giving thst a different value.
Try with a global variable to test it, like
window.login = script_php
And try again, in this ways, the login variable is global, or pass this variable as a parameter in the function.
the moreContent function is then loaded, I can see more content appearing on my screen but initialize is not loaded.
That is not exactly what happened. You have attached a function as method directly to jQuery object but did not invoke it,
jQuery.moreContent = function moreContent()
{
//more content is loaded
...
initialize();
}
You won't get any fruitful benefit from doing it this way. You have just added a method to an object (jQuery in this case) which is not invoked yet. In any case you do not need to add it as a method to jQuery object itself. You can do it easily without this as following.
function initialize(){
$("." + login).remove();
}
// this is a global function right now, use it anywhere you want.
function moreContent()
{
//more content is loaded
...
initialize();
}
// document ready...
$(function(){
moreContent();
});
You can rearrange the code and remove the unnecessary function layers (depends upon your code structure) and use it like this.
$(function(){
// more content...
initialize();
});
if I use a function like resize (in the end of the script.js file) it works
It worked because it is attached directly to window by jQuery on resize event.
$(window).resize(function(){
// The code inside will work whenever user resizes the window.
// It does not need to be hooked up inside document ready.
});
I have no idea why it suddenly works with the other function and why it doesnt work in the other cases
The reason it worked inside event handlers is because you hooked up your functions to run as a callback function to them. You have set it up correctly in click or resize event but not in load event. In load event you just created a function and added the it as a method to jQuery object but did not invoke it. The only and only way a function runs inside JavaScript is when you suffix parenthesis.
function demo()
{
// do something...
return "Done";
}
// a named function "demo" got created, but not invoked.
demo; // returns the whole function literal, not invoked yet.
demo(); // invoked, returns Done
So continuing from this, adding it as a method to jQuery will not load it, until you invoke it e.g.
jQuery.myNewMethod = function myNewMethod() {
return "Hey there :)";
}
// jQuery loaded, but where is my method ?? (#__#)
// let's invoke it then...
jQuery.myNewMethod(); // invoked the function using parenthesis!
// returns "Hey there :)"
// Now i can see you go (^__^)

Javascript: Call global function from within Self-Invoking Anonymous Function / Immediately-Invoked Function Expression (IIFE)

I am trying to create a chrome extension. I have the following function in my content script to handle downloads of files:
function handleDownloadFile(urlVal){
console.log("handleDownloadFile called");
}
Then I have the following code to inject a function into the DOM (taken from here: https://stackoverflow.com/a/11811558/3778854):
function injectScript(source) {
var elem = document.createElement("script"); //Create a new script element
elem.type = "text/javascript"; //It's javascript
elem.innerHTML = source; //Assign the source
document.documentElement.appendChild(elem); //Inject it into the DOM
}
injectScript("("+(function(window) {
// functions here
console.log("successfully injected content script"); // works
function foo(url){
$("#downloadPdfButton").click(handleDownloadFile(url));
}
foo("http://url.com/doc.pdf"); // breaks here
}).toString()+")(window)");
upon calling foo("http://url.com/doc.pdf") , it will break saying that handleDownloadFile is undefined. As you can see, I even tried passing window, and then setting window.handleDownloadFile(url) as the click event handler, with no success.
I hope someone can give me some pointers, if this is even possible.
While declaring the handleDownloadFile can you try this -
window.handleDownloadFile = function(urlVal){
console.log("handleDownloadFile called");
}

Explain this JavaScript onload function

Here's an example for registering a function on document load (most of it taken from JavaScript: The Definitive Guide):
"use strict";
//run function f when document is loaded
function onLoad(f) {
if (onLoad.loaded) // If already loaded
window.setTimeout(f, 0);
else if (window.addEventListener)
window.addEventListener("load", f, false);
}
onLoad.loaded = false;
onLoad(function() { onLoad.loaded = true; });
onLoad(myfunc);
function myfunc() {
console.log("Hello, world!");
}
I'm getting confused with the line onLoad(function() { onLoad.loaded = true; });. I can tell that it's self-invocation, but using the function name again baffles me. Why is it needed? I find that if I do only (function() { onLoad.loaded = true; }); then also the output is the same.
Finally, I can get the same output by using:
function myfunc() {
console.log("Hello, world!");
}
window.onload = (function() {window.setTimeout(myfunc, 0);});
How is my code better/worse?
Thanks in advance!
I'm getting confused with the line onLoad(function() { onLoad.loaded = true; });. I can tell that it's self-invocation, but using the function name again baffles me.
It isn't a self-invocation.
It is a call to the function onLoad (previously defined) with one argument (which is a function expression).
Finally, I can get the same output by using… How is my code better/worse?
Your code will:
Only support a function function to be called when the load event fires. If you try to assign another function, it will overwrite the previous one instead of setting up two functions to be called when the event fires.
Won't call the function immediately (or at all) if the load event has already fired (so you can't use it in a script that can be dynamically added to the page as well as being used normally)

How do you access a function inside an anonymous function from outside

I am writing some useful functions for my webpage for my webpage. The functions will be inside an anonymous function and will be called from outside the function. When I try to call the functions I get an error. This is how I am constructing it:
(function(){
var fx ={
pop : function(msg){
alert(msg);
}
};
fx = window.fx;
})();
window.onload = fx.pop('hi');
Does anyone know how I might do this? I know this is possible because jQuery and other javascript libraries are written like that.
When you do fx = window.fx; you are overwriting the fx which is in local scope of anonymous function. If you want access to it outside in the global scope you would need to do
window.fx = fx;. And Seems like you want to invoke the function pop on load and not when registering on load, Which is what you are trying to do here window.onload = fx.pop('hi'); This will invoke pop immediately and set the result of method as callback for load event (which is undefined as your method doesn't return anything; unless the method return another function that needs to be invoked after load this becomes useless). Instead you may want to try this way.
window.onload = fx.pop.bind(this, 'hi'); //Now this will get invoked only after load event is completed, it bind the current context to the function pop with the argument `hi`
or
window.onload = function(){
fx.pop('hi'); //Now this gets invoked only after load event is completed
};
So you can try:
(function(){
var fx ={
pop : function(msg){
alert(msg);
}
};
window.fx = fx;
})();
window.onload = function(){
fx.pop('hi')
};
are you sure jquery and other javascript libraries are written like that? I don't know of a simple way to gain access to the scope of a function, from outside that function. this seems like an unusual objective so please explain what problem you are attempting to solve with this technique, perhaps there is a more appropriate strategy.
For instance you could try:
var fx;
(function(){
fx ={
pop : function(msg){
alert(msg);
}
};
fx = window.fx; // this will probably overwrite your previous object with undefined
})();
window.onload = fx.pop('hi');

Categories

Resources