Use of Modernizr.load - javascript

I am using Modernizr for conditional loading of resources. My code is
<link rel="stylesheet" type="text/css" media="all" href="stylesheet/style.css" />
<script type="text/javascript" src="javascript/jQuery/jquery-1.8.1.min.js"></script>
<script src="javascript/stickyheader/jquery.fixedheadertable.js"></script>
<link rel="stylesheet" type="text/css" media="all" href="javascript/stickyheader/defaultTheme.css" />
<script type="text/javascript" src="javascript/modernizr/modernizr.2.6.2.js"></script>
<script type="text/javascript">
Modernizr.load([ {
// If browser supports touch
test : Modernizr.touch,
//Load iPad related resorces
yep : [ 'javascript/ipad-default.js', 'javascript/touchscroll.js', 'javascript/ipad-scroll.js',
'javascript/mobile.js' ],
// Load common resorces
load : ['javascript/ipad-default.js']
} ]);
</script>
This is working fine. But I am wondering if I can load all resources in Modernizr.load when I test for Modernizr.touch.
To be clear I want to load all resources within Modernizr.load.
How can I do this? And is this a good approach?

Yes you can. It definitely is a good approach to use a resource loader for a web application. However, I found the page rendering to be a little shattering when loading all CSS through Modernizr.
// You can load CSS just like JS
Modernizr.load("stylesheet/style.css", [
{
test : Modernizr.touch,
yep : [ 'javascript/touchscroll.js', 'javascript/ipad-scroll.js', 'javascript/mobile.js' ],
load : [ 'javascript/ipad-default.js' ] // No need to specify this in 'yep' too
}]);
Because Modernizr.load is built on yepnope.js, the yepnope documentation is a little more interesting for resource loading than the Modernizr tutorials. If you don't mind yet another framework, I can recommend requirejs. This one really helps to decouple and load your components.

Related

Can't understand laravel Mix works on my custom js/css files

I'm new to Laravel and whole framework stuff.
I do (may) understand a part of how the page rendered via laravel, but even after extensive search, I do not understand how laravel mix works.
Suppose that there is a page requires a global js and css library (lets specify jQuery and bootstrap)
Also the page requires custom js file like someJsTools.js.
Elementary speaking, in the past, those files referenced via <script src="blah"></script> and <link rel="blah" /> inside head tag and I used to it. In this env, all I have to do is specify those tags page by page.
// pageA requires jQuery.js, bootstrap.css and one CUSTOM JS file imatrouble.js
<head>
<link rel="stylesheet" herf="bootstrap.css"/>
<script src="jquery.js"></script>
<script src="imatrouble.js"></script>
</head>
//pageB requires jQuery.js, bootstrap.css and two custom js files.
<head>
<link rel="stylesheet" herf="bootstrap.css"/>
<script src="jquery.js"></script>
<script src="imatrouble.js"></script>
<script src="withimatroubleimadisasterlikewhateveryoucanimagine.js"></script>
</head>
PageA and PageB both requires common jQuery.js and bootstrap.css file. From what I learn, laravel Mix combine all js files into one and I don't get it here.
Problem 1 - One file do everything?
If it is true that "mix" things all together as one file, then how this one file could handle all of this different requirements seperatelly? I believe that my knowledge is wrong and its from my incorrect understanding of laravel mix and perhaps webpack mechanism.
Problem 2 - How can I manage all different page and every different situation?
Whether the problem above is originated from my missunderstanding or not, I cannot figure out what part of I (will) do could cause differences between pages. If mix only works for common global library, then all I have to do is just load custom js/css files manually. I currently assume that it is highly unlikely.
Please, someone help me to escape this chaos.
Have a good day.
It is purely based on your requirements. It depends on how you are customising your assets file.
For example :
Jquery, Angular,Bootstrap,Font Awesome is common for all your pages. So what I usually do is. I combine all css files to one file and all js files to one. Like below..
CSS mix
elixir(function(mix) {
mix.styles([
"libraries/bootstrap.css",
"libraries/font-awesome.min.css",
"custom/default.css",
], 'public/assets/css/common.css');
});
JS mix
elixir(function(mix) {
mix.scripts([
"libraries/jquery-1.10.2.js",
"libraries/bootstap.js"
"libraries/angular.js",
"libraries/angular-animate.js",
"custom/defaut.js"
], 'public/assets/js/common.js');
});
Suppose some pages need specific dependency[product, orders...etc]. For instance if product page needs wow.js, product.js and wow.css,product.css
CSS mix
elixir(function(mix) {
mix.styles([
"libraries/wow.css",
"custom/product.css",
], 'public/assets/css/product.css');
});
JS mix
elixir(function(mix) {
mix.scripts([
"libraries/wow.js",
"custom/product.js"
], 'public/assets/js/product.js');
});
So final laravel mix file looks like below
gulpfile.js
var elixir = require('laravel-elixir');
elixir.config.sourcemaps = true;
/**
* Global CSS MIX
*/
elixir(function(mix) {
mix.styles([
"libraries/bootstrap.css",
"libraries/font-awesome.min.css",
"custom/default.css",
], 'public/assets/css/common.css');
});
/**
* Global JS MIX
*/
elixir(function(mix) {
mix.scripts([
"libraries/jquery-1.10.2.js",
"libraries/bootstap.js"
"libraries/angular.js",
"libraries/angular-animate.js",
"custom/defaut.js"
], 'public/assets/js/common.js');
});
/**
* Product CSS MIX
*/
elixir(function(mix) {
mix.styles([
"libraries/wow.css",
"custom/product.css",
], 'public/assets/css/product.css');
});
/**
* Product JS MIX
*/
elixir(function(mix) {
mix.scripts([
"libraries/wow.js",
"custom/product.js"
], 'public/assets/js/product.js');
});
Now all your assets files are ready. Now you need to include wherever you want.
Suppose on your homepage you only requires common.js and common.css files.
homepage.blade.php
<head>
<link rel="stylesheet" href="{{ asset('assets/css/common.css') }}"/>
<script type="text/javascript" src="{{ asset('assets/css/common.js') }}"></script>
</head>
On the product page, you require both common and product assets file dependency. Include like below
product.blade.php
<head>
<link rel="stylesheet" href="{{ asset('assets/css/common.css') }}"/>
<link rel="stylesheet" href="{{ asset('assets/css/product.css') }}"/>
<script type="text/javascript" src="{{ asset('assets/js/common.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/js/product.js') }}"></script>
</head>

How to load third party libraries in isomorphic reactjs apps?

I am trying to use the stripe library specifically stripe elements so I can set up a custom form for payment processing. I am using the mern-starter in the server.js file I have the following code. You can see that at the bottom I have added a script tag to import stripe. However, in my client folder I have a component that is trying to make use of stripe and it cannot seem to access it. My guess is that is doesn't know it exists yet, but how can I circumvent that issue? I have looked at a react component that specifically deals with loading scripts, but it didn't seem like a great solution. I was just wondering if anyone else out there knows a better way. I know I could use a callback and have that dispatch and action(using REDUX) when it is done loading and only then allow my stripe code to execute, but again this seems pretty annoying to do. Any insights on this issue would be appreciated.
return `
<!doctype html>
<html>
<head>
${head.base.toString()}
${head.title.toString()}
${head.meta.toString()}
${head.link.toString()}
${head.script.toString()}
${process.env.NODE_ENV === 'production' ? `<link rel='stylesheet' href='${assetsManifest['/app.css']}' />` : ''}
<link href='https://fonts.googleapis.com/css?family=Lato:400,300,700' rel='stylesheet' type='text/css'/>
<link rel="shortcut icon" href="http://res.cloudinary.com/hashnode/image/upload/v1455629445/static_imgs/mern/mern-favicon-circle-fill.png" type="image/png" />
</head>
<body>
<div id="root">${html}</div>
<script>
window.__INITIAL_STATE__ = ${JSON.stringify(initialState)};
${process.env.NODE_ENV === 'production' ?
`//<![CDATA[
window.webpackManifest = ${JSON.stringify(chunkManifest)};
//]]>` : ''}
</script>
<script src='${process.env.NODE_ENV === 'production' ? assetsManifest['/vendor.js'] : '/vendor.js'}'></script>
<script src='${process.env.NODE_ENV === 'production' ? assetsManifest['/app.js'] : '/app.js'}'></script>
<script src='https://js.stripe.com/v3/'></script>
</body>
</html>`;
Your issue is that your application scripts are running before stripe.js has been loaded.
put <script src='https://js.stripe.com/v3/'></script> in the head or, at the very least, before your app (app.js in this case).

Conditional Loading of CSS files based on test condition in JQuery plugin

I'm looking for the best approach to conditionally load some files based on a specific set of conditions.
I have three CSS files and two javascript files which I'm currently loading like so:
<link href="core.min.css" rel="stylesheet" type="text/css">
<link href="add_regular.min.css" rel="stylesheet" type="text/css">
<link href="add_retina.min.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery-plugin.min.js"></script>
As is evident the fourth file is JQuery and the fifth is my JQuery plugin. Inside the JQuery plugin are a series of functions that are like tests e.g. isMobile, isRetina, isPhone, etc. However, let's focus on isRetina.
What I am trying to accomplish is as follows:
Load JQuery and my JQuery Plugin first
Use isRetina function inside my JQuery plugin to check whether the device has a retina display
Load core.min.css
Load add_regular.min.css if not Retina display, or load add_retina.min.css if Retina display
Currently I'm loading all three CSS files and I wouldn't want to do that because I've got a bunch of other CSS files and I want to load them as my JQuery plugin determines which one is best as per my above example. For example, I might have a phone.min.css that I would want to load after I do another test using my plugin's isPhone function.
I'm considering using YepNope and doing something like this:
<script type="text/javascript" src="yepnope.min.js"></script>
<script>
yepnope([{
load: ['jquery.min.js', 'jquery-plugin.min.js'],
test : $.myplugin.isRetina(),
yep : ['core.min.css', 'add_retina.min.css'],
nope : ['core.min.css', 'add_regular.min.css'],
complete : function(){
//my jquery plugin constructor here
$(selector).myplugin(options);
}
}]);
</script>
However, even if the above approach is the correct one, I am not sure how to implement document.ready, as my plugin's constructor needs to run only when the DOM is ready.
I would like some ideas on how I can pull this off using YepNope or any other solution.
Cheers.
I am not sure how to implement document.ready, as my plugin's constructor needs to run only when the DOM is ready.
There are two relevant events
window.addEventListener('load', function () {
// code runs when document+resources have finished loading
});
and
document.addEventListener('DOMContentLoaded', function () {
// code runs when document has finished parsing, but before resources loaded
});
If you wait for either of these events before importing jQuery, I'm not sure what effect it will have on jQuery's inbuilt $(document).ready / similar.
That said, you do have the option of checking document.readyState === 'complete' before attaching listeners, to see if you should invoke straight away.
I was just going over the JQuery Docs for .ready(), and apparently $(function(){}); is equivalent to $(document).ready(function() {}); (I'm not sure how I'm just discovering this #ScratchingMyHead).
I also saw this being used in a YepNope Tutorial on NetTuts+: http://net.tutsplus.com/tutorials/javascript-ajax/easy-script-loading-with-yepnope-js/.
So I guess my earlier code becoming what you see below should solve the problem:
<script type="text/javascript" src="yepnope.min.js"></script>
<script>
yepnope([{
load: ['jquery.min.js', 'jquery-plugin.min.js', 'core.min.css'],
test : $.myplugin.isRetina(),
yep : 'add_retina.min.css',
nope : 'add_regular.min.css',
complete : function(){
//my jquery plugin constructor added to JQuery DOM Ready Stack
$(function(){
$(selector).myplugin(options);
});
}
}]);
</script>
I will test this out and remove this if it doesn't work.
Not sure if I understand you correctly but this should work.
Include this by default:
<link href="core.min.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery-plugin.min.js"></script>
<script type="text/javascript">
yepnope([{
load: ['jquery.min.js', 'jquery-plugin.min.js'],
test : $.myplugin.isRetina(),
yep : ['core.min.css', 'add_retina.min.css'],
nope : ['core.min.css', 'add_regular.min.css'],
complete : function(){
//my jquery plugin constructor here
$(selector).myplugin(options);
//Remove the mask here.
}
}]);
// Feel free to call ready() here
$(document).ready(function(){
// whatever you want here
});
</script>
Then you can call ready() adding your specific logic according to the output of your tests. This way ready will only fire once the above has loaded and executed.

Building Dojo 1.7 for Mobile PhoneGap App

I am trying to build dojo 1.7 to use in my phonegap application. I am currently using dojo 1.6.1. I built my current dojo.js file by going to build.dojotoolkit.org and selecting everything under dojox.mobile as well as a dojo.store.JsonRest module. That works great.
My issue is trying to create a profile file to create a build similiar to the one I got from the dojo build website.
I downloaded dojo 1.7 stable release src.
I went into the buildScripts folder from the command line and tried to run a build with the following command:
>build profile=path/myMobileProfile.js action=release releaseName=test
I used the sample profile from the profiles folder:
dependencies = {
stripConsole: "normal",
layers: [
{
name: "dojo.js",
customBase: true,
dependencies: [
"dojox.mobile.parser",
"dojox.mobile",
"dojox.mobile.compat"
]
},
{
name: "../dojox/mobile/_compat.js",
layerDependencies: [
"dojo.js"
],
dependencies: [
"dojox.mobile._compat"
]
}
],
prefixes: [
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ]
]
}
It built with no errors. The dojo.js generated from the build was then dropped into my phonegap application. I changed my index file to the following just for testing:
<!DOCTYPE HTML>
<html>
<head>
<title>PhoneGap</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
<meta http-equiv="cache-control" content="no-cache"/>
<meta http-equiv="pragma" content="no-cache"/>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojox/mobile/themes/android/android.css" type="text/css" media="screen" title="no title">
<script type="text/javascript" src="libs/dojo/dojo/dojo.js" djConfig="parseOnLoad:true"></script>
<script type="text/javascript" charset="utf-8" src="phonegap-1.1.0.js"></script>
</head>
<body style="background-color:white">
Phonegap
</body>
</html>
Everytime I run the app I get a white page. When I replace the dojo.js file with my working copy I see the Phonegap output.
I would like to be able to use dojo 1.7 mobile and some of the new features such as the SpinWheel.
Can someone please help me with my build?
Thanks
I'm having the same type of issues. I think it has to do with the new AMD loader.
It seems as if the parser is not parsing the declarative widgets but rather is waiting to do it on demand or that it just never gets called.
I did find some docs that mention we should use dojo/ready, but couldn't get it to work with it and phoneGap. The same code works fine on a desktop without phoneGap, which is weird.
See live docs: http://livedocs.dojotoolkit.org/dojo/ready
As well as: http://livedocs.dojotoolkit.org/loader/amd
"To put the loader in the AMD mode, set the async configuration variable to truthy:
<script data-dojo-config="async:1" src="path/to/dojo/dojo.js"></script>
<script>
// ATTENTION: nothing but the AMD API is available here
</script>
Note that you can only set the async flag before dojo.js is loaded, and that in AMD mode, neither Dojo nor any other library is automatically loaded - it is entirely up to the application to decide which modules/libraries to load."
For me this Profile works fine with dojo 1.7 and PhoneGap:
dependencies = {
selectorEngine: "acme",
layers: [
{
// This is a specially named layer, literally 'dojo.js'
// adding dependencies to this layer will include the modules
// in addition to the standard dojo.js base APIs.
name: "dojo.js",
dependencies: [
"dijit._Widget",
"dijit._Templated",
"dojo.fx",
"dojo.NodeList-fx",
//this wasn't included in the standard build but necessary
"dojo._firebug.firebug",
//my used dojo requirements
"dojox.mobile.parser",
"dojox.mobile",
"dojox.mobile.Button",
"dojox.mobile.SwapView",
"dojox.mobile.ScrollableView",
"dojox.mobile.TabBar",
"dojox.mobile.SpinWheelTimePicker",
"dojox.mobile.compat"
]
}
],
prefixes: [
["dijit", "../dijit" ],
["dojox", "../dojox" ]
]
}
But with this Profil the CSS Files are not included, so you have to copy all the CSS folder structure.
My HTML file looks like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 5.0//EN" "http://www.w3.org/TR/html5/strict.dtd">
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"></meta>
<meta name="apple-mobile-web-app-capable" content="yes"></meta>
<title>dojox.mobile Demo</title>
<link href="css/themes/iphone/iphone.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="phonegap.js" charset="utf-8"></script>
<script type="text/javascript" src="dojo.js" djConfig="isDebug:true, parseOnLoad:true"></script>
<script type="text/javascript">
require([
"dojox/mobile/parser", // (Optional) This mobile app uses declarative programming with fast mobile parser
"dojox/mobile", // (Required) This is a mobile app.
"dojox/mobile/Button",
//Some other dojo Widgets
"dojox/mobile/compat" // (Optional) This mobile app supports running on desktop browsers
],
function(parser, mobile, compat){
//Optional module aliases that can then be referenced inside callback block
}
// Do something with mobile api's. At this point Dojo Mobile api's are ready for use.
);
//to make sure dojo and PhoneGap was loaded use this
document.addEventListener("deviceready", init(), false);
function init(){
dojo.ready(function(){
//do something
});
}
</script>
</head>
<body>
</body>
HTH
This problem is solved with Dojo 1.7.2
Also found this: http://livedocs.dojotoolkit.org/dojo/parser
and tried to force parse on the entire dom or just the specific element, but still nothing.
I did find the following that may shed some more light on this issue: "Dojo and PhoneGap? both have their own event to acknowledge when the page is ready. We are finding that the dojo.ready is too early for things like deviceDetection APis when running within a PhoneGap? container and it would be better off being done inside of the PG deviceReady method. ..."
Full thread can be found here: http://bugs.dojotoolkit.org/ticket/14062
It is discussing dojo 1.6.1, but sounds like some changes in dojo 1.7 may suffer more severe reactions. There is a suggested workaround, but I'm not sure it will solve the 1.7 issue.

Group of CSS and JS files import at HTML?

I have a group of CSS imports as like:
<link rel="stylesheet" href="/css/reset.css"/>
<link rel="stylesheet" href="/css/visualize.css"/>
<link rel="stylesheet" href="/css/datatables.css"/>
and some JavaScript code imports as like:
<script src="/js/excanvas.js"></script>
<script src="/js/jquery.js"></script>
<script src="/js/jquery.livesearch.js"></script>
<script src="/js/jquery.visualize.js"></script>
Is it possible to put all CSS import lines into a file i.e. cssImports.css and put all JS import lines into a file i.e. jsImports.js. So when I want to import that CSS and JS group files I will write something like:
<link rel="stylesheet" href="/css/cssImports.css"/>
<script src="/js/jsImports.js"></script>
so all the files listed above will be imported?
PS: I don't want to write any code belongs to web server specific.
Javascript imports: no.
CSS import: yes, but you shouldn't because it breaks parallel downloading of stylesheets.
Your best bet is to use a local build script (such as the Ant script included with the HTML5 Boilerplate) to concatenate your stylesheets and scripts before uploading them to the server, then linking to the 'master' resources in your HTML:
<link rel="stylesheet" href="/css/master.css">
<script src="/js/master.js"></script>
There is a tutorial on using the Ant script.
Go with LazyLoad! https://github.com/rgrove/lazyload/
It's a very small js (less than 1kb) that takes care of resource loading for you.
Download the package and save on your js folder. Then you would probably want to do this:
<script src="js/lazyload-min.js"></script>
Then for javascript files:
<script>
LazyLoad.js(["/js/excanvas.js", "/js/jquery.js", "/js/jquery.livesearch.js", "/js/jquery.visualize.js"], function () {
alert('all js files have been loaded');
});
</script>
Css:
<script>
LazyLoad.css(["/css/reset.css", "/css/visualize.css", "/css/datatables.css"], function () {
alert('all css files have been loaded');
});
</script>
This will also boost the performance of your page, enabling parallel css and js loading (the latter on firefox opera only).
You can Import CSS like this:
Create a new CSS cssImports.css and add there lines
#import url('/css/reset.css');
#import url('/css/visualize.css');
#import url('/css/datatables.css');
and relate it in your homepage as:
<link rel="stylesheet" href="/css/cssImports.css"/>
For Javascript import doesn't work. But you can create a single JS file and include the javascript code of each file after one another. But this is not recommended. It is better to have separate <script> tag for each js file.
for css:
<style>
#import url('/css/styles.css');
</style>
for js you could try something like
document.write("<script type='text/javascript' src='otherScript.js'></script>");
but i dont see a reason to do either of theese...
Yes just copy all the code and place in into a new file in the order than you would like it to run.
I know there are some javascript libraries that can do this for you but I dont have an experience of using them. I think Yahoo compiler/ YUI has one.
I'm not recommend do that because performance issue, but if you want the way, you can do that:
For CSS yes its possible, in cssImports.css you can put:
#import url(/css/reset.css);
#import url(/css/visualize.css);
#import url(/css/datatables.css);
But for JS, I think no way as much as CSS, but you can do this (adding JS files) from one JS file (ex jsImports.js), by write code create script element and add this element to page, like that :
var jsE = document.createElement('script');
var url = 'JS LINK HERE';
jsE.setAttribute('type', 'text/javascript');
jsE.setAttribute('src', url);
document.getElementsByTagName('head').item(0).appendChild(jsE);
Do this for each link of JS that you want to put, I have and idea, using Arracy contains JS links like this:
var jsLinks = new Array(
"/js/excanvas.js",
"/js/jquery.js",
"/js/jquery.livesearch.js",
"/js/jquery.visualize.js"
);
then a loop read a link each time and put this, like :
for (i = 0; i < jsLinks.length; i++)
{
var jsE = document.createElement('script');
var url = jsLinks[i];
jsE.setAttribute('type', 'text/javascript');
jsE.setAttribute('src', url);
document.getElementsByTagName('head').item(0).appendChild(jsE);
}
I didn't test my code, But I hope my idea is explained well.
Best
Edit 1: yes you can use Gatekeeper solution for JS (Very Simple), but it use "write" but "for me" I don't like that way :)
This is now possible as follows with HTML Imports which are in W3C draft
<link rel="import" href="import.html">
import.html
<link rel="stylesheet" href="/css/reset.css"/>
<link rel="stylesheet" href="/css/visualize.css"/>
<link rel="stylesheet" href="/css/datatables.css"/>
<script src="/js/excanvas.js"></script>
<script src="/js/jquery.js"></script>
<script src="/js/jquery.livesearch.js"></script>
<script src="/js/jquery.visualize.js"></script>
At this time only Chrome, Android and Opera support HTML Imports natively, but WebComponents provides a very mature polyfill script called webcomponents-lite.js to support all modern browsers

Categories