I have a strange situation where jQuery is not loading into the window object. My app is an Electron app. My startup page does in fact load jQuery. But while the startup page is loading, I have some code that decides whether to reload the browser window with a different url. That url is another html page in the app and it contains a reference to the jQuery library in the script tag. jQuery does appear to load in this new page because I am able to open DevTools and type $ in the console and it indicates that it is loaded. However, in my javascript code, which is embedded in the page, the $ is not recognized. I am not loading any other scripts that could conflict with the jQuery script. The jQuery script is the only script loaded. What could be preventing jQuery from being attached to the window object? This only happens when I load that new page using window.location.href. If I don't load that page, but simply use jQuery in the startup page, jQuery is attached to the window object.
Here is how I am loading jQuery:
<head>
<script type="text/javascript" src="../../jquery/jquery-3.2.1.min.js"></script>
</head>
I have tried waiting for jQuery to load using:
function defer(method) {
if (window.jQuery) {
method();
} else {
setTimeout(function() { defer(method) }, 50);
}
}
defer(function () {
alert("jQuery is now loaded");
});
but window.jQuery never gets set.
In Electron, jquery isn't loaded as a script.
Use this instead (in your header):
<script>window.$ = window.jQuery = require('jquery');</script>
and install jQuery as a package with npm install --save jquery
If that doesn't work, try using
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
//put all of scripts here
<script src="path/to/jquery"></script>
<script>if (window.module) module = window.module;</script>
Or you can use:
<script>window.$ = window.jQuery = require('./path/to/jquery');</script>
Related
This is a new question arising from what I learnt in: Is order of script onload and window.onload well defined when the script is a DOM node created dynamically from a loaded script?
In the previous question we learnt that when a window is loading scripts, any scripts (the one directly loaded as well as the ones dynamically being loaded by the script) would finish loading first and only after that the window.onload will fire.
But JSDOM seems to be behaving differently.
Here is the loader.js script which is same as the one in the previous question:
function main()
{
if (typeof window !== 'undefined') {
var script = window.document.createElement('script')
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.core.min.js'
script.onload = function () { console.log('script loaded') }
window.onload = function () { console.log('window loaded') }
window.document.head.appendChild(script)
} else {
console.log('window not available yet')
}
}
if (typeof module !== 'undefined' && module.exports) {
exports.main = main
}
main()
Here is the driver code that pretends to be a fake window via JSDOM.
var jsdom = require('jsdom')
var loader = require('./loader.js')
var html = `<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="loader.js"></script>
</head>
<body>
<div>Test</div>
</body>
</html>`
global.window = new jsdom.JSDOM(html, { runScripts: "dangerously", resources: "usable" }).window
This is the output:
$ node fakewindow.js
window not available yet
window loaded
script loaded
The window.onload event fired before the script.onload event fire. Why did JSDOM consider the window loaded even when a dynamic script loaded by a script directly included in the HTML hadn't loaded yet? Is this a bug in JSDOM or is this behavior allowed by relevant W3C standards?
Seems like a bug in JSDOM.
It appears to be solved in the latest version 13.0.0, try updating JSDOM.
I've tried out the same code for jsdom 13 and it works.
window not available yet
script loaded
window loaded
while jsdom 11 indeed shows the problem:
window not available yet
window loaded
script loaded
I have a little issue bugging me for several hours now, so i come to see you guys for some help.
Here is the situation :
I use jquery-2.1.4.js in my application. If i test my fragment of code outside the application it work correctly but when it is in my application Jquery doesn't load correctly.
Jquery is include correctly in my repository and called in my page before the end of the body tag like this (i moved it away from the head tag thiking it might be the issue but i still got the same error) :
<script type="text/javascript" src="js/jquery-2.1.4.js"></script>
I test if Jquery is correctly loaded like this :
if (typeof jQuery == 'undefined') {
// jQuery is not loaded
alert("jquery not loaded,force it");
var jq = document.createElement('script');
jq.type = 'text/javascript';
// Path to jquery.js file, eg. Google hosted version
jq.src = 'js/jquery-2.1.4.js';
document.getElementsByTagName('head')[0].appendChild(jq);
} else {
// jQuery is loaded
alert("jquery is loaded");
}
The issue is here now :), everytime I end up in the not loaded part, and when I force Jquery load, I got an error line 3539 of the Jquery file on the function :
function Data() {
Object.defineProperty( this.cache = {}, 0, {
get: function() {
return {};
}
});
this.expando = jQuery.expando + Data.uid++;
}
With the error message :
This object does not have this property or method : defineProperty
(not sure about the English for this one, my error message is in French).
Just so you know, there is no action done on Load, only when i click a button. Our file with JS codes are in a .include, so i don't know if this is why the error is trigger or not.
Anyway, thanks for taking the time to help me.
Slayner.
You need to include the expando library, since it is not part of standard jQuery. Try adding this:
<script src="//cdn.rawgit.com/cantino/expando/38affee59bffdd87975c492472362c69ce0f6fda/jquery.expando.js"></script>
Right after this:
<script type="text/javascript" src="js/jquery-2.1.4.js"></script>
Okay, so the reason why this did not work for me was that our application is loaded as an IE5 application and is not compatible with JQuery (well not a version from these last few year.)
I'm creating a Java Script widget for the site based on CodeIgniter. The site using templates and Blade library. I need to load my java script right after the page has been loaded. I have added it into template scripts.blade.php:
<script src="{{apps_url('assets/my_widget/js/my_widget.js')}}"></script>
Unfortunately, it seems, what my script was executed before controller has been loaded and therefore the script can not find required SVG object:
(function() {
var container = d3.select(".myContainer");
alert("container: " + container);
})();
This alert show what container is null even if the myContainer object actually exists on the page and was recognized by CSS. The d3 library has been loaded properly and there is no errors in the Firefox console.
Is there a way to execute this script right after the object has been loaded?
use
$(document).ready(function() {
(function() {
var container = d3.select(".myContainer");
alert("container: " + container);
})();
});
On a page i try to fill an empty <iframe id="myFrame"></iframe> with the HTML code of an ajax result. That works well, except script tags in the code are not being executet, so i have to readd them to the iframe's page:
$.post('page.php', function(code) {
$("#myFrame").contents().find("html").get(0).innerHTML = code;
$("#myFrame").contents().find("script").each(function() {
$old_script = $(this);
$frame = document.getElementById("myFrame");
$new_script = $frame.contentWindow.document.createElement("script");
$new_script.type = "text/javascript";
$new_script.src = $old_script.attr("src");
$old_script.remove();
$frame.contentWindow.document.head.appendChild($new_script);
});
});
That works basically, but the document seems to load the Javascript files in a different order. There are 3 js files to load: jquery.min.js, a jquery plugin and a main.js file to control the bahavior inside the iframe:
// main.js:
$(document).ready(function() {
alert("frame document loaded");
// call the jquery plugins etc...
});
The page alerts me "frame document loaded", but cannot execute the jquery plugins. Double-checked the script paths, but they're right. Seems that the jquery.min.js and main.js are loaded before the plugin files.
How could i achieve to load the javascript files one by one as specified originally in the code returned by the ajax request?
EDIT: Forgot to say that sometimes everything works well and the javascript seems to be loaded correctly. On reload it breaks again.
I have this code in a script we use for initializing all of our applications, it loads the jQuery from the google CDN amongst several other things that all of our applications require. Then when we load the specific program functionality we check to make sure that jquery has loaded, in case the CDN is down. The problem I am running into is it is still loading the second one. If I add a simple alert("Test"); after the line headTag.appendChild(jqTag); it works perfectly, but if I remove the alert it uses the second one. What gives?
They are loaded like so:
<script type="text/javascript" src="i-initializer.js"></script>
<script type="text/javascript" src="i-program.js"></script>
initializer script:
if(typeof jQuery=='undefined'){
var headTag = document.getElementsByTagName("head")[0];
var jqTag = document.createElement('script');
jqTag.type = 'text/javascript';
jqTag.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js';
headTag.appendChild(jqTag);
}
Then in another script we have the following:
if(typeof jQuery=='undefined'){
var header = document.getElementsByTagName("head")[0];
var qtag = document.createElement('script');
qtag.type = 'text/javascript';
qtag.src = 'http://feedback.oursite.com/scripts/jquery-1.8.3.min.js';
qtag.onload = checkjQueryUI;
header.appendChild(qtag);
}
else
{
jQCode();
}
jQCode() {
...
}
This is the technique used by HTML5 Boilerplate. First it loads the Google CDN script, then immediately checks if the global jQuery object exists -- if it doesn't, the CDN failed and a local copy is loaded instead.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.8.3.min.js"><\/script>')</script>
Your fallback code loads jQuery asynchronously.
That means that the rest of your scripts run before jQuery loads.
Adding an alert() call forces the rest of your code to wait (until you click OK); by the time that happens, jQuery will have loaded.
Instead, you can emit a new <script> tag using document.write() to load it synchronously.
Alternatively, you could wrap the rest of your code in a callback and call the callback(s) after jQuery loads.
If you do it this way, you should use a script loader library, which will handle all of that for you.