Structure of JavaScript files and Modernizr/yepnope - javascript

I'm looking into the whole asynchronous script loading thing with Modernizr and yepnope.js and I'm wondering how I can adapt my application's structure to use asynchronous script loading.
Right now the structure resembles this:
...
<head>
<script src=jquery.js></script>
<script src=plugin1.js></script>
<script src=plugin2.js></script>
<script src=plugin3.js></script>
<script src=global.js></script>
</head>
<body>
This code is found in a header.php file that is required throughout the application. In the document body section (other PHP files), I may have some JavaScript files like this:
...
<script src=moduleA.js></script>
<script src=someScripts.js></script>
</html>
Here's a simplified example of what moduleA.js and someScripts.js could contain:
$(document).ready(function() {
$('.searchDate').myCoolPlugin({ /* some options */ });
});
And someScripts.js:
$(document).ready(function() {
$('#departureDate, #arrivalDate').myCoolPlugin({ /* some options */ });
});
If I'm using Modernizr, at the top of the page I would remove the other plugin scripts and in global.js I'd write:
Modernizr.load([
{
test: $.fn.myCoolPlugin,
nope: 'plugin1.js',
complete: function() {
$(document).ready(function() {
$('.filterDates').myCoolPlugin();
}
}
}
]);
How do I guarantee that myCoolPlugin has been loaded by the time moduleA.js and someScripts.js are executed? I realize that I can wrap the plugin initialization in those files with Modernizr.load(), but that seems like unnecessary duplication of code.

If I have understood your question correctly then you want to execute the body scripts after the necessary scripts have been loaded with Modernizr.
You could do something like this:
// Header script
var race_won = false;
var load_body_script = function() {
race_won = true;
};
Modernizr.load([
{
test: ..your condition..,
yep: ..test success..,
nope: ..test fail..,
complete: function() {
$(document).ready(function() {
$('.filterDates').myCoolPlugin();
load_body_script();
}
}
}
]);
// Body script
var body_script = function() {
// .. your code here ..
}
if (race_won) {
body_script();
}
else {
load_body_script = body_script;
}

Related

Adding a javascript to a razor page properly

I have a template that I am using from template monster. In the files there is a javascript page that has all of the scripts needed to run the pages. I have added this to the bottom of the page where the scripts are rendered. It does not seem to be accessing the file. It is on the page and comes up when I am viewing it under the "Inspect object". When I put the code snippet directly in the razor page it works. Any ideas why it would not be pulling it from the javascript file? Thanks for your help.
EDIT
This resides in the _Layout page. Where the Menu is.
The below works when inserted in the razor page.
<script type="text/javascript">
$(document).ready(function () {
$(".sticky-menu").sticky({ topSpacing: 0 });
});
$(window).on('load', function () {
function fadeOut(el) {
el.style.opacity = 0.4;
var last;
var tick = function () {
el.style.opacity = +el.style.opacity - (new Date() - last) / 600;
last = +new Date();
if (+el.style.opacity > 0) {
(window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 100);
} else {
el.style.display = "none";
}
};
tick();
}
var pagePreloaderId = document.getElementById("page-preloader");
setTimeout(function () {
fadeOut(pagePreloaderId)
}, 1000);
});
</script>
This is what I have in the razor page that does not work
#Scripts.Render("~/Scripts/scripts.js")
The Top code resides in the "scripts.js" file.
There is a lot of code in this file and it seems like none of it is working. Meaning it is like it is not accessing the script. All the scripts that are loaded in the page are in the same order as the Regular HTML in the template. The template HTML file works.
UPDATE -
I got this to work by moving this out of the script page and onto the layout page. I am still not sure why or what was causing this snippet not to work in the script page. It seems like the only part that wasnt working.
In the script file it is written like this:
(function($) {
'use strict';
jQuery(document).on('ready', function() {
////// Other snippets //////
$(".sticky-menu").sticky({
topSpacing: 0
});
////// Other snippets //////
});
In the _Layout page it looks like this:
<script type="text/javascript">
$(document).ready(function () {
$(".sticky-menu").sticky({ topSpacing: 0 });
var hub = $.connection.notificationHub;
$.connection.hub.start()
.done(function () {
console.log("Hub Connected!");
})
.fail(function () {
console.log("Could not Connect!");
});
});
</script>
I still do not know why this does not work from the Script file...
UPDATE - 4-26-2019
I have found the problem. The Template was created with a earlier version of jQuery. I have found that the Script file loads and partially works when I remove
jQuery(document).on('ready', function () {
The entire file looks like this
(function($) {
'use strict';
jQuery(document).on('ready', function () {
---> All the jQuery Code
});
})(jQuery);
I changed the above line to be:
}(jQuery));
I saw some other implementations that had it this way.
However there is something not right with this using jQuery 3.3.1.. if anyone knows how to properly format this so it works that would help alot.
You change from
#Scripts.Render("~/Scripts/scripts.js")
to
<script src="~/Scripts/scripts.js"></script>
It will work
You can refer this link to understand different between Script.Render vs script tag
What is the difference between "#Script.Render" and "<script>"?
Update:
If you have a _Layout.cshtml view like this
<html>
<body>
#RenderBody()
#RenderSection("scripts", required: false)
</body>
</html>
then you can have an index.cshtml content view like this
#section scripts {
<script type="text/javascript" src="~/Scripts/scripts.js"></script>
}

Why does my 'menu hide' code not work when I place it within my external script file?

I have a /js/common.js file attached in the <head> of my webpage, and then the file for my page /about.aspx.
<script src='/js/common.js'></script>
<script src='/js/modernizr-custom.js'></script>
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.min.js"></script>
I can hear how dumb this question is, and I do apologise, but it is annoying me as to why I can not figure it out.
This code here shows and hides the navigation:
var didScroll;
/* more variables .. */
$(window).scroll(function (event) {
didScroll = true;
});
setInterval(function () {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
/* Rest of code */
}
And my common.js file has the following structure:
// Declarations
var pageLoaded = false;
var fontsLoaded = false;
// Wrapper
function wrapperWidth() {
return parseFloat(document.getElementById("wrapper").offsetWidth);
}
// And so on..
//-----------------------
// jQuery Initialisation
//-----------------------
$(document).ready(function () {
//Set variables on page load
$(window).load(function () {
pageLoaded = true;
fontsLoaded = true;
});
});
If I place my js to hide the menu on scroll within the external .js file common.js, the javascript does not work and I don't know why?
At present, I place it right before the closing </body> tag on each page.
I wish to be able to place my javascript in one place 1) so that it can be easily found for maintenance and 2) most importantly, to speed up load time, as the more <script></script> tags one has, will slow down page load.
Can someone please explain why my 'menu hide' javascript will not work when I place within my common.js file?
Check if you called properly your common.js and jquery min.js
Call it in below given order
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<script type="text/javascript" src="js/common.js"> </script>

unable to access an object created using require.js

Hello everyone,
I have just recently started learning the require.js , but I don't seem to understand as how does the whole mechanism work...and especialy how do I access the variables/objects created using this javascript library.
Let me explain it further in the example below..
webroot/page.jsp
<html>
<script data-main="js/page" src="js/lib/require.js"></script>
</html>
webroot/js/common.js
requirejs.config({
baseUrl: 'js/lib',
paths: {
app: '../app',
}
});
webroot/js/app/page.js
require(['./common'], function (common) {
require(['./app/page/init'], function(page)
{
page.load(1);
});
});
webroot/js/app/page/init.js
define(['./load'], function (load) {
var LoadPage = new load();
return LoadPage;
});
webroot/js/app/page/load.js
define(function () {
function loadPage() {
}
loadPage.prototype = {
load: function (page_id) {
console.log("Opening page "+page_id+" ");
}
};
return loadPage;
});
now when I run the page everything works perfectly, but now I'd like to execute the load method by clicking on a button.
<div onclick="page.load(2);"> </div>
but this does not work..So I'd like to know if there is any possibility to bind this action to any button or link...whatever..
(apologies for my bad english)
Thanks,
Alex
How about as below assuming you are using JQuery:
<div id="divPageLoad"></div>
<script language="javascript" type="text/javascript">
$("#divPageLoad").on("click", function() {
page.load(2);
});
</script>

Calling JQuery function from xhtml in external js file

I have a jquery function defined in an external js file :
myJquery.js
(function($) {
$.fn.test = function (options) {
//Extended default options
var opts = $.extend({
chars: 0
}, options);
...doSomething...
})(jQuery);
Inclding this file in xhtml as:
<script type="text/javascript" src="_/js/myJquery.js"/>
and trying to access as:
$(document).ready(function() {
$("input.testClass").each(function() {
$(this).test({
chars:10
});
});
});
But getting js error saying 'test' function not found.
Your test function is scoped to the external file space, not the global environment. If you are sure that jQuery has command of the $ then append your function without the function($) wrapper.
EDIT: while the above may still be relevant for others ... it does work fine (at least for just showing the alert) with the } in place:
external file inlcuded with <script type="text/javascript" src="testing.js"></script>
(function($) {
$.fn.test = function (options) {
//Extended default options
var opts = $.extend({chars: 0}, options);
alert('boo: '+opts.chars);
}
})(jQuery);
in page:
<script type="text/javascript">
$(document).ready(function() {
$("h1").each(function() {
$(this).test({
chars:10
});
});
});
</script>

How can I delay document.ready until a variable is set?

I am doing QUnit testing in an IFRAME and have a recursive JavaScript function that loads all of the scripts from the parent page into the IFRAME before starting QUnit. This works great. My problem is that some of our scripts use document.ready to make stuff start.
Something such as:
$(document).ready(function () {
// blah
});
to do do their work. I'd prefer to not change production code just to account for tests and I don't want these production scripts to think the IFRAME document is "ready" until every scripts is loaded.
How I can delay "document.ready" itself?
Here is my pseudocode to give you an example to work from:
scripts[0] = "/foo/bar.js";
scripts[1] = "/blah/blah.js";
function RecursiveScriptStart(){
// I want to set document.ready = false right here!
if(scripts.length == 0) {
QUnitStart();
return;
}
RecursiveScriptLoader(0, scripts);
}
function RecursiveScriptLoader(currentScriptID, scripts) {
$.getScript(scripts[currentScriptID], function () {
if (currentScriptID == (scripts.length - 1)) {
QUnitStart();
}
else {
RecursiveScriptLoader(currentScriptID + 1, scripts);
}
});
}
function QUnitStart() {
// I want to set document.ready = true right here!
QUnit.stop();
QUnit.start();
}
The actual code is similar, but involves a jquery selector populating the array "scripts[]" with JavaScript tag "src" properties.
Thanks!
If you're using jQuery 1.6+ then you can use holdReady. Just set $.holdReady(true) at the top of your script and then in the beginning of QUnitStart set $.holdReady(false).
This code worked for me; To invoke $(window).load() inside $(document).ready()
$(document).ready(function() {
$(window).load(function() {
// this code will run after all other $(document).ready() scripts
// have completely finished, AND all page elements are fully loaded.
});
});
This method would preserve execution order in all cases by making sure that your run-last code is not passed to $(window).load() until all $(document).ready() scripts have completed.
If your using jQuery 1.6 or higher you can use holdReady to delay the ready event being fired.
For 1.4.3 or higher you can use $.readyWait property to delay the ready event, Demo Here (not my code)
if your interested in figuring out how jquery handles the ready event search for the line
jQuery( document ).trigger( "ready" ).unbind( "ready" );
in your developer copy of jquery.js
Just to fill in where others left off, you may use this load order in your test.html
<script src="jquery.js"></script>
<script src="qunit.js"></script>
<script>$.holdReady(true);</script>
<script src="theThingIwantToTest.js"></script>
<script src="theTestScript.js"></script>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript">
window.setInterval(function() {
console.log(document.getElementById('waitForMe'));
}, 500);
</script>
</head>
<body>
Before
<script type="text/javascript" src="/php-with-sleep.php"></script>
After
<div id="waitForMe"></div>
</body>
</html>
Extended test, I have tested RequireJs domReady plugin
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="/vendor/require/require.js"></script>
<script type="text/javascript">
window.setInterval(function() {
console.log(document.getElementById('waitForMe'));
}, 500);
require.config({
baseUrl: '/',
paths: {
domReady: 'vendor/require/plugin/dom-ready',
jQuery: 'vendor/jquery'
},
shim: {
async: {
exports: 'async'
},
jQuery: {
exports: 'jQuery'
}
}
});
require(['domReady', 'jQuery'], function(domReady, $) {
console.log('jQuery loaded');
$(function() {
console.log('jQuery dom ready');
});
domReady(function() {
console.log('domReady requireJs plugin, callback');
})
});
require(['domReady!', 'jQuery'], function(domReady, $) {
console.log('domReady! (no callback)');
});
require(['domReady', 'jQuery'], function(domReady, $) {
console.log('domReady plugin loaded');
});
</script>
</head>
<body>
Before
<script type="text/javascript" src="/php-with-sleep.php"></script>
After
<div id="waitForMe"></div>
</body>
</html>

Categories

Resources