1

来源: http ://blog.tomasjansson.com/creating-custom-unobtrusive-file-extension-validation-in-asp-net-mvc-3-and-jquery

$(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));

jQuery 不是已经在这个函数中可用了,为什么会在最后传入呢?我不明白这个,我以前见过它几次,从来没有使用过它,很好奇这里发生了什么。

4

3 回答 3

2

传递它并没有做任何事情。该语法不正确,因为在那里使用的函数是回调而不是 IIFE。

我能想到这样做的唯一原因是如果不使用冲突模式。即使这样,语法仍然不正确。

于 2013-10-08T20:35:00.257 回答
1

阅读更多:jQuery.noConflict

我们将 jQuery 或其他 jQuery 控制变量($、jQuery、jq、jQ、jQ1101)传递给模块或插件,因为在 DOM 中,我们可以加载多个版本的 jQuery,或者我们可以拥有使用 $ 作为控制变量的其他库。如PrototypeJSZepto

通过传递 jQuery 控制变量,我们确保我们的模块具有正确的控制变量,并且在内部我们只使用 $ 作为 jQuery 变量。

请看这个例子。

<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>
于 2013-10-11T20:43:10.627 回答
0

该博客文章中的代码是有效的 JavaScript 语法并且会执行,但它并没有达到作者可能预期的效果。该$(function...)调用看起来像是试图以通常的方式在准备好的 DOM 上运行该函数,但事实并非如此。

让我们解构代码。首先,去掉函数中的所有代码并添加一些日志记录:

console.log( 'before' );

$( function () {
    console.log( 'DOM ready' );
} (jQuery) );

console.log( 'after' );

这是(可能令人惊讶的)有效的 JavaScript 并将记录:

before
DOM ready
after

但问题是:如果您将该脚本放在网页中,您真的希望它记录:

before
after
DOM ready

毕竟,您是在 DOM 准备好之前运行脚本,期望函数稍后运行,在 DOM 准备好之后。这就是使用$()调用的全部意义所在。

什么地方出了错?为了更清楚,让我们将内部函数分解为一个单独的命名函数:

console.log( 'before' );

function ready() {
    console.log( 'DOM ready' );
}

$( ready(jQuery) );

console.log( 'after' );

再进行一项更改以使其完全逐步完成:

console.log( 'before' );

function ready() {
    console.log( 'DOM ready' );
}

var result = ready( jQuery );

$( result );

console.log( 'after' );

这些版本中的每一个都具有完全相同的语义并以相同的顺序运行。

现在应该清楚发生了什么。我们立即ready调用该函数并将其返回值传递给调用。该函数不返回任何值,因此该值为.$()readyundefined

那么,最后一行相当于:

$( undefined );

并且该调用只返回一个空的 jQuery 对象 ( [])。

罪魁祸首当然是(jQuery)最后。添加这就是导致立即调用函数的原因,而不是将对该函数的引用$()传递给调用。jQuery括号内的存在是没有意义的:这个ready函数不需要任何参数,所以它被忽略了。如果()出现在那里,那将是同样的事情。

setTimeout()这与您在类似调用中看到的常见错误非常相似:

// Oops - calls doStuff immediately, not after one second
setTimeout( doStuff(), 1000 );

这就提出了一个问题:为什么这段代码没有遇到问题,因为它没有按预期工作?好吧,无论哪种方式,该函数都会被调用 - 唯一的区别是的运行时间。

因此,它没有引起问题的两个可能原因。

  1. 这段代码可能已经放在了<body>这些天流行的做法的末尾。在这种情况下,运行代码时 DOM 可能已经准备就绪。DOM 元素在加载时按顺序创建<body>,如果您<script>在特定 DOM 元素之后放置标签,则该 DOM 元素在该脚本运行时确实可用。

  2. 代码可能不需要准备好 DOM。查看博客文章中的验证器代码,它看起来确实像设置代码,在第一次运行时对 DOM 没有任何作用。如果是这样,那么只要jQuery.validator插件已经加载,那么如果该代码立即运行或稍后在完整 DOM 准备好时运行,则没有任何区别。

于 2013-10-08T23:20:50.680 回答