I'm working in a really twisted environment in which I cannot handle this problem through the view logic of the MVC framework I'm using (Cakephp). It could happen because I have to load this piece of code inside a page which already has a jQuery script loaded in.
If I simply load jQuery in my piece of code, it works as long as there's no other jQuery scripts present. When there are 2 scripts, it doesn't work and says $ is not a function. Not really sure how this works but explanations could help.
Anyway I've got to the point of dynamically loading the script into the page.
So this is my code:
<script id="loadjq" type="text/javascript"></script>
<script id="loadcloud" type="text/javascript"></script>
<script type="text/javascript">
if(typeof jQuery=="undefined"){
document.getElementById('loadjq').src= 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js';
}
document.getElementById('loadcloud').src= '/js/jqcloud.js';
$(document).ready(function(){
$("#tagcloud").jQCloud(word_list,{});
});
</script>
This loads the script but when I try to load jqcloud.js, it can't find the other script, probably because it runs before the other script is loaded. With a few dirty tricks I could go through that, but the same problem happens when i reach $(document).ready(function()
Is there a clean way to do this? I need it to wait for the previous scripts to be loaded before executing, or at least, that's what the problem looks like. Not really sure if this is really my problem.
How about setting event handlers on the jquery script element to call the jqcloud script on load completion. Something like
if(typeof jQuery=="undefined"){
var loadjqScript = document.getElementById('loadjq').src =
'http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js';
// Code below handles browser that support script onload
// and ones that don't
var loadFunction = function()
{
if (this.readyState == 'complete' || this.readyState == 'loaded') {
loadJqCloud();
}
};
loadjqScript.onreadystatechange = loadFunction;
loadjqScript.onload = loadJqCloud;
}
function loadJqCloud() {
document.getElementById('loadcloud').src= '/js/jqcloud.js'
}
Related
Is it possible to call a javascript function when a user has successfully been redirected to a new view?
I have tried the following-
C#
if (Session["UserId"])
{
return RedirectToAction("LoggedIn");
}
cshtml
#if (Session["UserId"] != null)
{
<script>$('#btnTest').click();</script>
}
Fails with
JavaScript runtime error: '$' is undefined
I have referenced jquery in the project and tested it just with a button click and this works however the above is failing. How can I achieve this?
Most likely, this HTML is being inserted before jQuery is actually referenced. For example, if you're not referencing jQuery until the closing body tag (as you should), then this will be run before jQuery actually exists. The best way to handle this type of thing is with sections. You can defined a section in your layout for scripts and then ensure that that section is below required dependencies like jQuery.
_Layout.cshtml
<script src="/path/to/jquery.js"></script>
#RenderSection("Scripts", required: false)
</body>
AwesomeView.cshtml
#section Scripts
{
#if (Session["UserId"] != null)
{
<script>$('#btnTest').click();</script>
}
}
This will result in the following HTML being generated (assuming the session variable isn't null of course:
<script src="/path/to/jquery.js"></script>
<script>$('#btnTest').click();</script>
</body>
It's important to note that this only works with standard views. Partial views cannot define sections, so if you need to include some bit of script inside a partial, you'll have to take a different approach to deferring execution. Generally, the best method at that point is simply utilize window.onload directly:
var onload = window.onload
window.onload = function () {
onload();
// your code here
}
That should ensure that jQuery has already been loaded. However, it's really better to just not include JS code in partials, in the first place. There's a number of issues that can result from that and it makes your code very fragmented and brittle, in general.
In order to optimize the load of my document, I use to load jQuery async like that
<script async type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
Then I call a script using jQuery :
<script type="text/javascript">
jQuery(document).ready(function() {
App.init();
OwlCarousel.initOwlCarousel();
FancyBox.initFancybox();
StyleSwitcher.initStyleSwitcher();
});
</script>
It returns me that jquery is not defined.
I don't know what should I use, I though that .readyfunction would wait until all document is loaded before calling it.
The same for Bootstrap library, It tells me that jQuery is not defined.
I've tried to ask the script to be loaded at the end, but it still does not work properly.
Since jquery script is loaded asynchronously, jquery is not loaded on the moment your script is executing. So you need to wait for it to load by subscribing on load event like this:
<script async id="jquery" type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
Then listen for a load event on this element
<script type="text/javascript">
document.getElementById('jquery').addEventListener('load', function () {
App.init();
OwlCarousel.initOwlCarousel();
FancyBox.initFancybox();
StyleSwitcher.initStyleSwitcher();
});
</script>
But I don't know why someone wants to do things like this.
To optimize page loading speed it is better to put all you javascript at the end of the body, so content will be loaded first, and scripts won't delay page rendering event if it's synchronously loaded.
Edit: I agree with comment and consider previous paragraph not the best way of loading jQuery to the page
Question Script Tag - async & defer has good answer to your problem.
In a nutshell you cannot load jQuery, or other library, asyncronously when some other script depends on it without some additional asyncronous handling for executing the scripts depending on the library.
That is my solution:
<script async type="text/javascript" src="path_to_jquery" id="jquery_script_tag">
</script>
<script>
if ( !('jQuery' in window) )
{
window.jQueryQueue = [];
//define temporary jQuery function
window.jQuery = function(){
//just save function parameters to queue
jQueryQueue.push( arguments );
}
document.getElementById('jquery_script_tag').addEventListener('load', function(){
//call jQuery with parameters saved in queue, after it loaded
for ( var i in jQueryQueue )
jQuery.apply( document, jQueryQueue[i] );
});
}
</script>
This code defines a temporary jQuery function if it is yet not defined. The function saves all jQuery function calls to queue while the real jQuery has not yet loaded (instead of calling undefined jQuery function). And when jQuery has loaded, it calls the jQuery functions in the queue with the same parameters as called before.
jQuery, and all components that depend on jQuery (including Bootstrap), depend on hooking the DOMContentLoaded event to set up events.
This means jQuery (and anything that uses $(function() {...})) must be downloaded before DOMContentLoaded fires, or it never hooks up its events.
In turn, that means <script async ... will be unreliable, breaking whenever jQuery takes longer to download than the page content does.
Unfortunately <script defer ... doesn't work either thanks to jQuery trying to fire as soon as the document.readyState === "interactive".
You can load content and then load jQuery by putting the <script> at the end of the <body> but this will result in a noticeable pause between the page appearing and any of the jQuery firing - users won't be able to click on anything, visual components won't appear, and so on.
This way works just fine:
<script charset="utf-8" type="text/javascript">
var intervalID = window.setInterval(function(){
if(window.jQuery){
clearInterval(intervalID);
console.log('Loaded');
/* Your code here */
}
},1000);
</script>
You Used Async Loading When You Try Access Jquery It Not Loaded By Browser You Can Access Jquery After Page Loading Is Complete .
Load Jquery Normally To Fix Your Problem .
I'm attempting to get some jquery code to run after a sharepoint page loads, the code being:
$(".ms-commentcollapse-icon").click();
I've been using the following to load the code after the page loads, but it does not seem to be very reliable (it will work sometimes and other times it wont):
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script type="text/javascript">
$(window).load(function () {
$(".ms-commentcollapse-icon").click();
});
</script>
are there any other good methods for achieving this? I'm not sure what's going on, sharepoint could be at fault, but I figured I would try fiddling around with the script a bit more first.
You could use an auto-executing function:
<script type="text/javascript">
(function () {
$(".ms-commentcollapse-icon").click();
} ());
</script>
If this is SharePoint 2010 or above, you can use ExecuteOrDelayUntilScriptLoaded(yourfunction,"SP.JS") to keep your code from firing until after the SP.JS library has loaded (or you can put any other library in the second parameter for a similar effect).
If this is in a web part and you don't want it to execute until other web parts on the page are fully loaded, make sure the web part containing the script is below the other web parts.
As a last resort, you could execute it on a delay using setTimeout or setInterval, but that's ugly.
You can prevent the default behaviour by using e.preventDefault(); within the function.
<script type="text/javascript">
$(".ms-commentcollapse-icon").click(function(e) {
// We're going to stop the default behavior
e.preventDefault();
//some code here
});
</script>
From script within body I dynamically load jquery and SimpleModal into page header. I use callback to be sure jQuery is fully loaded before making calls into it--this works. However when I dynamically load the SimpleModal script file, I can't subsequently call its methods. It appears when the SimpleModal script lazy loads it is unable to reference the current document object. Any help would be greatly appreciated.
/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
jQuery = window.jQuery.noConflict(true);
main();
}
/******** Main function ********/
function main() {
jQuery(document).ready(function ($) {
var domain = 'http://qo.microssoftware.com';
/******* Load SimpleModal *******/
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src",
domain + "/js/simplemodal.js");
script_tag.onload = modalLoadHandler;
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
});
}
function modalLoadHandler() {
/******* Open Modal *******/
$.modal("<div><h1>SimpleModal</h1></div>", {});
}
Try:
<script type="text/javascript" src="http://qo.microssoftware.com/js/simplemodal.js"></script>
<script type="text/javascript">
jQuery(document).ready(function ($) {
$.modal("<div><h1>SimpleModal</h1></div>");
});
</script>
OR, if you want to call the modal using your main() function:
<script type="text/javascript" src="http://qo.microssoftware.com/js/simplemodal.js"></script>
<script type="text/javascript">
jQuery(document).ready(function ($) {
function main() {
$.modal("<div><h1>SimpleModal</h1></div>");
}
});
</script>
You don't need to put the js in the header... Actually some programmers always put all their JS just before the ending BODY-tag.
I would suggest that this is unnecessary, to begin with. The simplemodal script is very compact. Give more consideration to how to optimize script loading in general (gzip, or if you must go ajax, AMD dependency loading with RequireJS or the like) without the unnecessary complication of this kind of ajax method.
The script loaders that use this type of method (like the Facebook SDK or Google Maps) will search the window (global) element for a callback to call once the script is initialized. Basically, you would have to modify the simplemodal code and then wrap your dependent code in a callback. I hardly see how that could be necessary in this case.
This is where you would want to create an async-closure based around the onload event of the script.
If you must support ancient IE, you can also hook into the onreadystatechange event, the same way you would do it in AJAX requests (in pure JS).
The more-modern browsers won't fire this event.
So turn the onload into a callback, which fires known methods from the file.
You can get around errors by also attaching to the onerror of the script's loading.
I saw similar question here in SO, where someone wants to do the same thing. The different case is that I have this lightweight script that listens for event bubbling to the top of the document root that I intentionally want to put on the top of the page and I dont want to wrap it inside $(document).ready(). It looks something like this:
<html>
<head>
<script>
document.documentElement.onclick = function (e) {
//$.ajax call using jQuery. Possible that jQuery is not loaded when page is not completely loaded
}
</script>
</head>
And then near the bottom of the page I include jQuery like this:
<body>
<script src="./jQuery.js"></script>
</body>
</html>
As you can see on the <head> when I'm making an ajax call to somewhere using $.ajax, it's possible that jQuery is not yet loaded, so that it may throw $ is undefined error when someone clicks on something on DOM, and jQuery is not loaded yet. My workaround is probably to use settimeout hoping that jquery will be loaded sometime later and the code is working like this:
if (typeof $ === 'undefined'){
setTimeout(doAJAXJquery, 50);
}else{
$.ajax(//blablabla) //jQuery loaded and ready to use!!
}
But it's a really dirty hack. How am I supposed to know when jQuery is finished loading? that 50ms i put there is only an arbitrary value i made up myself. Of course it is still not gonna work if jquery hasn;t been loaded yet and it already passes 50ms.
Is there any better workaround so when jQuery is undefined, it is gonna retry sometime later again, or put a function that executes ajax inside some callback that gets executed when jQuery is ready? thanks.
what about
<head>
<script type="text/javascript">
var init = function(){
document.documentElement.onclick = function (e) {
//$.ajax call using jQuery. Possible that jQuery is not loaded when page is not completely loaded
}
}
</script>
</head>
<body>
<script src="./jQuery.js"></script>
<script type="text/javascript">
init();
</script>
</body>
If you want to execute the list of functions (or events 'fired') waiting for jQuery to load you could create your own 'ready' function :))
var runList = new Array(), timer = setInterval(function(){
if (typeof(jQuery) != 'undefined')
{
clearInterval(timer);
if (runList.length>0) for(var i in runList) runList[i]();
}
}, 50);
runList.push(function(){alert(1);});
runList.push(function(){alert(2);});
var jQuery = 1;