jQuery.proxy() Function not being called in Chrome - javascript

I am facing an issue where a jQuery function is not being called even though the proxy has successfully loaded (from what I can tell). The call we are making works fine on first load, but when we try to load this script in via AJAX it calls the required $.proxy() to the Initialise function, but then doesn't actually call that function.
The dynamic loaded in code is:
<script language="JavaScript"><!--
var ctrl = new VideoControl({"Id":"bc1093c8290a4037846c2052695a7d3a"}, "...");
//-->
</script>
And the javascript to create the object is:
function VideoControl(controlIds, videoMarkUp) {
this.controlIds = controlIds;
this.videoMarkUp = videoMarkUp;
var thisControl = this;
$(function () { $.proxy(thisControl.Initialise(), thisControl); });
}
VideoControl.prototype.Initialise = function () {
// do stuff
}
So the main function is called, but the Initialise() is not called when this is loaded in via AJAX controls in Chrome or IE...this does however work in firefox.
There is a stackoverflow answer which explains why $function is not being called but how do I get it to a point it will call (similar to how firefox deals with it)
Is anyone aware of something that firefox does differently when working with jQuery vs the other browsers?
There are no errors showing on the chrome developer tools, is there anywhere else that could be looked at in order to diagnose this?
Thank you in advance.

So the main function is called, but the Initialise() is not called
when this is loaded in via AJAX
$(function() {}) is alias for .ready() ; handlers for .ready() should be called at most once . AJAX appear to occur after document is loaded ? , where .ready() has previously called , $.isReady set to true preventing handlers within subsequent .ready() or $(function(){}) from being called.
Try removing $(function() {}) wrapper surrounding
function VideoControl(controlIds, videoMarkUp) {
this.controlIds = controlIds;
this.videoMarkUp = videoMarkUp;
var thisControl = this;
$.proxy(thisControl.Initialise, thisControl);
}
use
$(document).ready(VideoControl)
Though , not certain why $.proxy is used here ? , as the context of thisControl.Initialise not appear to be changed to a different context : this ?
Note also that js at Question thisControl.Initialise() called function; where function should be referenced jQuery.proxy( function, context [, additionalArguments ] )

Related

How do you know when something is a Javascript function, and when its a jQuery function [duplicate]

Sometimes I make a function and call the function later.
Example:
function example { alert('example'); }
example(); // <-- Then call it later
Somehow, some functions cannot be called. I have to call those functions inside:
$(function() { });
What do $(function() {}); and (function() { }); mean, and what's the difference/purpose of these?
$(function() { ... });
is just jQuery short-hand for
$(document).ready(function() { ... });
What it's designed to do (amongst other things) is ensure that your function is called once all the DOM elements of the page are ready to be used.
However, I don't think that's the problem you're having - can you clarify what you mean by 'Somehow, some functions are cannot be called and I have to call those function inside' ?
Maybe post some code to show what's not working as expected ?
Edit: Re-reading your question, it could be that your function is running before the page has finished loaded, and therefore won't execute properly; putting it in $(function) would indeed fix that!
The following is a jQuery function call:
$(...);
Which is the "jQuery function." $ is a function, and $(...) is you calling that function.
The first parameter you've supplied is the following:
function() {}
The parameter is a function that you specified, and the $ function will call the supplied method when the DOM finishes loading.
It's just shorthand for $(document).ready(), as in:
$(document).ready(function() {
YOUR_CODE_HERE
});
Sometimes you have to use it because your function is running before the DOM finishes loading.
Everything is explained here: http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
Some Theory
$ is the name of a function like any other name you give to a function. Anyone can create a function in JavaScript and name it $ as shown below:
$ = function() {
alert('I am in the $ function');
}
JQuery is a very famous JavaScript library and they have decided to put their entire framework inside a function named jQuery. To make it easier for people to use the framework and reduce typing the whole word jQuery every single time they want to call the function, they have also created an alias for it. That alias is $. Therefore $ is the name of a function. Within the jQuery source code, you can see this yourself:
window.jQuery = window.$ = jQuery;
Answer To Your Question
So what is $(function() { });?
Now that you know that $ is the name of the function, if you are using the jQuery library, then you are calling the function named $ and passing the argument function() {} into it. The jQuery library will call the function at the appropriate time. When is the appropriate time? According to jQuery documentation, the appropriate time is once all the DOM elements of the page are ready to be used.
The other way to accomplish this is like this:
$(document).ready(function() { });
As you can see this is more verbose so people prefer $(function() { })
So the reason why some functions cannot be called, as you have noticed, is because those functions do not exist yet. In other words the DOM has not loaded yet. But if you put them inside the function you pass to $ as an argument, the DOM is loaded by then. And thus the function has been created and ready to be used.
Another way to interpret $(function() { }) is like this:
Hey $ or jQuery, can you please call this function I am passing as an argument once the DOM has loaded?
I think you may be confusing Javascript with jQuery methods. Vanilla or plain Javascript is something like:
function example() {
}
A function of that nature can be called at any time, anywhere.
jQuery (a library built on Javascript) has built in functions that generally required the DOM to be fully rendered before being called. The syntax for when this is completed is:
$(document).ready(function() {
});
So a jQuery function, which is prefixed with the $ or the word jQuery generally is called from within that method.
$(document).ready(function() {
// Assign all list items on the page to be the color red.
// This does not work until AFTER the entire DOM is "ready", hence the $(document).ready()
$('li').css('color', 'red');
});
The pseudo-code for that block is:
When the document object model $(document) is ready .ready(), call the following function function() { }. In that function, check for all <li>'s on the page $('li') and using the jQuery method .CSS() to set the CSS property "color" to the value "red" .css('color', 'red');
This is a shortcut for $(document).ready(), which is executed when the browser has finished loading the page (meaning here, "when the DOM is available"). See http://www.learningjquery.com/2006/09/introducing-document-ready. If you are trying to call example() before the browser has finished loading the page, it may not work.

Declared function seen as undefined by IE 11

I am having some problems with function declarations in IE. It appears, even if I link the function directly to the window object. I tried switching with document in stead of window, but with no success.
Here is the basic code that I am trying to use:
window.addEventListener('load', function () {
function initChart (id) {...}
//linking to window object
window.initChart = initChart;
});
As I said, I even tried to link it directly: window.initchart(id){...}. More that that, I even included the js file I declared the function inside the body(due to a rumor that says that IE doesn't see function declared in head section)
After that, inside script tags i call initChart() with a valid id and I get this error inside the IE console: 'initChart' is undefined.
<script>
initChart('chart');
</script>
The strange thing is that in Chrome, Firefox and Opera has no such problem. Any ideeas?
PS: If this is a duplicate, I did not found the question that covers this.
You also need to do initChart('chart'); inside of the window load event handler (this one or a later added one). Or you can do that in another event handler that you know for sure happens after this window load event handler.
As your code is processed by the browser, it knows to do something on the window load event, which is to set your window.initChart.
But then later on you are using it right away, without the event of window load happening yet.
If it doesn't happen in Chrome, I am wondering if everything is loaded, but even so, I'd think your window.initChart is set in the next event cycle. (let me try to do some experiments -- you are not doing any of these in the debugger but all inside an HTML file?). But it really shouldn't be ok in Chrome, because the load event handler doesn't occur before your <script> tag is parsed and executed, which does initChart('chart'); already.
But in any event, it is best to follow the event sequence: if you set window.initChart on window load event handler, then also only call window.initChart() in the same and later added event handler, or in an event handler that happens afterwards.
You can see in the following HERE 02 happens before HERE 01:
window.addEventListener('load', function() {
console.log("HERE 01");
});
console.log("HERE 02");
I am running the following in Chrome and I did get an error as expected:
window.addEventListener('load', function() {
function foo() {
console.log("HERE 01");
}
window.foo = foo;
});
foo();
But this one worked as expected:
window.addEventListener('load', function() {
function foo() {
console.log("HERE 01");
}
window.foo = foo;
});
window.addEventListener('load', function() {
foo();
});
The problem apparently was not the linkage between the function and the window object. In my load event I had some ES6 string interpolation(something like this: console.log(`#${id}`)) and IE falls short on this. He doesn't know what to do with it. So as a consequence, my window.initChart() was not even compiled. After I commented the code in matter, my initChart function was working fine. Thanks for help tho, #nopole!

window.onload function not running

I'm facing a weird issue. The console.log() outside the onload function works, but the console.log() inside doesn't work... Would it mean that my page never fully loads ? I had a look at the developer tools of Chrome and it shows me that the page is loaded, so I don't really understand... (here is a screen of the devtool)
Here is my code:
console.log("hello1");
window.onload = function()
{
console.log("hello2");
};
(I'm using this in a WordPress website, but I don't think it changes anything)
Thanks in advance,
ArbreMojo.
Some other code is probably assigning another function value to the window.onload method, so it basically overrides your assignment.
Instead of window.onload = function you can do:
window.addEventListener('load', function() {
console.log('loaded')
})
which allows attaching an arbitrary number of handlers for that event. This ensures nothing can override your callback function.
See: EventTarget.addEventListener for more info.

Javascript onload and script callback functions, which takes the precedence?

I'm loading an external script that uses callback function, which returns some specific data. If this data is not received error should be displayed.
Here is the code I've made:
<script>
//setting initial state so that function will only work once
var visitors_loaded=false;
var my_callback = function( data ) {
if (visitors_loaded) return 0;
if (data) {
//success: callback function is called and it has a proper data
visitors_loaded=true;
alert(JSON.stringify(data));
}
else alert ('error'); //something went wrong
};
</script>
<script onload="my_callback(null)" onerror="my_callback(null)"
src="https://api.clicky.com/api/stats/4?site_id=32020&sitekey=9a19b1a4d1171193&type=visitors&date=this-month&output=json&json_callback=my_callback"></script>
As you can see... many things that can go wrong with the script, so I naturally added an onerror event. This on error event actually fires if you change host name or domain of the script to something non-existent.
However, if you only make changes to the url of the script, it can still connects to the server and fires an onload event instead. My callback function will not be called for those invalid requests, so I added an onload handler as well.
Now the problem is, if all loaded normally and data was returned, it will fire both, callback function and onload. I have noticed that callback function is triggered before the onload and set the visitors_loaded variable so that the handler function is only called once.
So far it works perfectly in JS fiddle and my offline site but I wonder if this is an expected behavior? Will that json_callback function always have precedence before the onload handler?
https://jsfiddle.net/5sfk9ht5/4/
Will that json_callback function always have precedence before the onload handler?
If the external script calls my_callback synchronously then yes.
The scripting section in the official html5 specification describes how these things are supposed to work. The specification is quite general and has to deal with a lot of details conserning encoding, CORS, ignore-destructive-writes counter and so on. But for this question we don't care about these specifics.
In step 4 there is a note:
Note: This is where the script is compiled and actually executed.
And in step 7 the load event is fired:
fire a simple event named load at the script element.
So the specification defines that the load event is always fired after the script has been executed.
As you see the specification also tells us why the onerror event is not fired if you change the URL. The error event is only created if loading the script fails. But all requests to https://api.clicky.com/api/stats/ return a HTTP 200 status. The invalid URLs return XML and thus a SyntaxError is thrown. But this does not cause the onerror handler to be triggered.
As others have mentioned if the callback is called asynchronously they can call your callback after the onload event. But I don't see a reason why they would do this async in your external script.
onload in older IE might not work for you 'onload' handler for 'script' tag in internet explorer, if you want to run all browsers you might need something like this https://jsfiddle.net/e287523t/2/ and should work for all
function addScript(fileSrc, callback) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.onreadystatechange = function() {
if (this.readyState == 'complete') {
callback();
}
}
script.onload = callback;
script.src = fileSrc;
head.appendChild(script);
}
Then the rest is defining my_callback and calling addScript
my_callback = function(someData) {
alert(JSON.stringify(someData));
};
Now the problem is, if all loaded normally and data was returned, it will fire both, callback function and onload. I have noticed that callback function is triggered before the onload and set the visitors_loaded variable so that the handler function is only called once.
This is because the callback is launched from within the called script from api.clicky.com
So far it works perfectly in JS fiddle and my offline site but I wonder if this is an expected behavior?
I see what you are getting at, a related question about what happens when a script fails is here, but I did some tests for you and here are the results.
tester.html:
<script>
var onLoadTest = function() {
console.log("Onload Called!");
};
var callbacktest = function() {
console.log("Called from other script!");
};
var errortest = function() {
console.log("Callback OnError!");
};
</script>
<script onload="onLoadTest()" onerror="errortest()"
src="script.js"></script>
script.js:
function otherScriptFunc()
{
//call the function in the original script
callbacktest()
}
otherScriptFunc(); // first call to other script
setTimeout(otherScriptFunc, 0); // final call to other script
Results from the console log
Called from other script!
Onload Called!
Called from other script!
Your OnLoad will be called when the JS in the other place has finished being parsed (async functions will do their own thing). For example, otherScriptFunc(); will call before onload but setTimeout(otherScriptFunc, 0); will be called after onload
Your OnError will only be called if there is a GET request error. IE, the file cannot be found, or URL cannot be resolved - nothing about what is in the file. (I tested it separately, just mess with the file name)
Your callback passed to the other script could be called whenever the other script feels like it. It has a reference to it and could decide to hold onto it for a little while and call it later after it has played around. Which means it could be in an async call waiting for data elsewhere. Which means, theoretically, your onload could in fact be called before the callback, but it depends on the other script and there is not a lot you can do about it.
Will that json_callback function always have precedence before the onload handler?
It's not about precedence, it is just dependent upon when the other script decides to call it.

Clearing a jquery document.ready() call

How do I clear out anonymous functions that are set to trigger via a jQuery document.ready() call?
For example:
<script type="text/javascript">
//some code sets a doc ready callback
$(document).ready(function ()
{
alert('ready');
});
//my attempt to prevent the callback from happening
window.onload = null;
$(document).unbind("ready");
</script>
The alert happens regardless of my attempts to circumvent it. Is there any way to do this?
You'd probably get the most appropriate answer if you described what problem you're really trying to solve.
jQuery doesn't have a publicly documented way to undo or block document.ready() handlers. If you control the code, you can use a global variable and a conditional like this:
var skipReady = false;
$(document).ready(function ()
{
if (!skipReady) {
alert('ready');
}
});
// skip the document.ready code, if it hasn't already fired
skipReady = true;
Or, if you want to hack into jQuery a bit (beyond the documented interfaces), you can do this:
$(document).ready(function() {
alert("ready");
});
// stop the ready handler
$.isReady = true;
You can see this last one work here: http://jsfiddle.net/jfriend00/ZjH2k/. This works because jQuery uses the property: $.isReady to keep track of whether it has already fired the ready handlers or not. Setting it to true makes it think it has already fired them so it won't every do it again.
This works:
$(document).bind("ready", function () { alert("hey!"); });
$(document).unbind("ready");
Seems like a bug to me - all other events in jQuery are able to be unbound. Omitting this one is inconsistent.
Not a direct answer as to the omission, but here's some related info from jQuery docs:
All three of the following syntaxes are equivalent:
$(document).ready(handler)
$().ready(handler) (this is not recommended)
$(handler)
There is also $(document).bind("ready", handler). This behaves similarly to the ready method but with one exception: If the ready event has already fired and you try to .bind("ready") the bound handler will not be executed. Ready handlers bound this way are executed after any bound by the other three methods above.
$(document).ready() is dependent on the onLoad event which is triggered by the browser meaning you can not prevent it from happening. If the alert() is determined by some condition then I would use an if/else statement to decide whether it is called.
Super old question, but came across the need to do this recently to prevent document.ready code I didn't control from running in certain instances. This can be achieved by proxying jQuery's ready function, rather like a test spy. The following will work:
var ready = $.prototype.ready;
// proxy the ready function
$.prototype.ready = function ( fn, allowed ) {
allowed = allowed || false;
if ( allowed ) {
ready.call( this, fn );
}
};
All calls to $( document ).ready will now be ignored. You can override this behaviour by passing true as the second argument: $( document ).ready( fn, true )

Categories