Reputation: 43843
$(function () {
jQuery.validator.unobtrusive.adapters.add('fileextensions', ['fileextensions'], function (options) {
var params = {
fileextensions: options.params.fileextensions.split(',')
};
options.rules['fileextensions'] = params;
if (options.message) {
options.messages['fileextensions'] = options.message;
}
});
jQuery.validator.addMethod("fileextensions", function (value, element, param) {
var extension = getFileExtension(value);
var validExtension = $.inArray(extension, param.fileextensions) !== -1;
return validExtension;
});
function getFileExtension(fileName) {
var extension = (/[.]/.exec(fileName)) ? /[^.]+$/.exec(fileName) : undefined;
if (extension != undefined) {
return extension[0];
}
return extension;
};
} (jQuery));
Wouldn't jQuery already be available inside this function, why would it be passed in at the end there? I don't get this and I've seen it a few times before, never had to use it so, was curious what's going on here.
Upvotes: 1
Views: 127
Reputation: 1516
Read More: jQuery.noConflict
We pass jQuery or other jQuery Control variable ($, jQuery, jq, jQ, jQ1101) to the module or plugin because in the DOM, We can have multiple version of jQuery loaded or we can have other libraries which uses $ as control variable. Such as PrototypeJS or Zepto
By passing jQuery Control variable we ensure that we have right control variable for our module and internally we just use $ as jQuery variable.
Please see this example.
<html>
<head>
<title>StackOverflow 19257741</title>
<script type="text/javascript" src="http://zeptojs.com/zepto.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
</head>
<body>
<div id="content">
<!-- Other HTML Tags -->
</div>
</body>
<script type="text/javascript">
//Change jQuery Control because you have other library loadded or you have multiple jQuery loaded.
var jQ1101 = jQuery.noConflict(true);
//Now, you can not access jQuery by $ or jQuery
//This module have to have jQuery to do DOM Manipulation
var module = (function ($, zepto) {
var i = 0, //private ivar for module use only.
_init = function () {
var me = this;
//TODO: Module can init or do something here...
return me;
},
_fill = function (selector) {
//We can use $ here as jQuery Control
$(selector).css({ "backgroundColor": "#000000", "width": "100%", height: "100%" });
//Wait for 2 seconds
window.setTimeout(function() {
//Not select dom with zepto
zepto(selector).css({ "backgroundColor": "#777777", "width": "100%", height: "100%" });
}, 2000);
};
return {
init: _init,
fill: _fill
};
})(jQ1101, $); //We have to pass the current Control for jQuery so, module can use library for internal function.
//Call module then call fill method by passing variable
module.init().fill("#content");
//Two different Library
console.log(jQ1101.fn.jquery); //jQuery 1.10.1
console.log($); //Zepto
</script>
<html>
Upvotes: 1
Reputation: 28870
The code in that blog post is valid JavaScript syntax and will execute, but it doesn't do what the author probably expected. The $(function...)
call looks like an attempt to run that function on DOM ready in the usual manner, but that's not what happens.
Let's deconstruct the code. First, strip out all the code in the function and add some logging:
console.log( 'before' );
$( function () {
console.log( 'DOM ready' );
} (jQuery) );
console.log( 'after' );
This is (perhaps surprisingly) valid JavaScript and will log:
before
DOM ready
after
But here's the problem: If you put that script in a web page, you really want it to log:
before
after
DOM ready
After all, you're running the script before the DOM is ready, expecting the function to be run later, after the DOM becomes ready. That's the whole point of using the $()
call.
What went wrong? To make it more clear, let's break out the inner function as a separate named function:
console.log( 'before' );
function ready() {
console.log( 'DOM ready' );
}
$( ready(jQuery) );
console.log( 'after' );
And one more change to make it completely step-by-step:
console.log( 'before' );
function ready() {
console.log( 'DOM ready' );
}
var result = ready( jQuery );
$( result );
console.log( 'after' );
Each of these versions has exactly the same semantics and runs in the same order.
Now it should be clear what happened. We're calling the ready
function immediately and passing its return value into the $()
call. The ready
function doesn't return any value, so that value is undefined
.
The last line, then, is the equivalent of:
$( undefined );
And that call simply returns an empty jQuery object ([]
).
The culprit, of course, is that (jQuery)
at the end. Adding that is what caused the function to be called immediately, instead of passing a reference to the function into the $()
call. And the presence of jQuery
inside the parentheses is meaningless: this ready
function doesn't expect any arguments, so that is ignored. It would be the same thing if ()
appeared there.
It's very much like a common error you see with setTimeout()
and similar calls:
// Oops - calls doStuff immediately, not after one second
setTimeout( doStuff(), 1000 );
This raises the question: why didn't this code run into a problem since it doesn't doesn't work as expected? Well, the function does get called either way - the only difference is when it's run.
So two possible reasons why it didn't cause a problem.
This block of code may have been placed at the end of the <body>
as is popular practice these days. In that case the DOM would probably be ready-enough when the code is run. DOM elements are created in order as the <body>
is loaded, and if you put a <script>
tag after a particular DOM element, that DOM element will indeed be available when that script is run.
The code may not require the DOM to be ready. Looking at the validator code in the blog post, it does look like setup code that doesn't do anything with the DOM when it's first run. If so, then as long as the jQuery.validator
plugin is already loaded, then it wouldn't make any difference if this code runs immediately or later when the full DOM is ready.
Upvotes: 0
Reputation: 572
Passing it in isn't doing anything. That syntax isn't right since the function, as it's used there, is a callback and not IIFE.
Only reason I could think to do that would be if no conflict mode is used. Even then the syntax is still not correct.
Upvotes: 2