2013-10-08 70 views
1

來源:http://blog.tomasjansson.com/creating-custom-unobtrusive-file-extension-validation-in-asp-net-mvc-3-and-jquery爲什麼'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的已經可用此功能中,爲什麼會在年底有傳遞嗎?我不明白這一點,之前我已經看過幾次,從來沒有使用過,所以很好奇這裏發生了什麼。

+1

是不是'$'裏面'函數($){'? – Sergio

+1

您確定此代碼有效嗎? AFAIK,匿名函數會立即用'jQuery'參數調用,'undefined'將作爲參數傳遞給'$()'函數,而這些AFAIU沒有任何意義。 – dbanet

+0

猜測回答這個問題,從這裏拉它:http://blog.tomasjansson.com/creating-custom-unobtrusive-file-extension-validation-in-asp-net-mvc-3-and-jquery – BigOmega

回答

2

傳遞它並沒有做任何事情。該語法不正確,因爲它在那裏使用的函數是回調函數而不是IIFE。

只有我能想到這樣做的原因是,如果沒有使用衝突模式。即使如此,語法仍然不正確。

+0

正是我想的......我已經更新了源可能有更多的線索,或者他只是拙劣的例子http://blog.tomasjansson.com/creating-custom-unobtrusive-file-extension-validation- in-asp-net-mvc-3-and-jquery – BigOmega

+0

應該在他的網站上發表評論。你說得對,jQuery已經在全球範圍內定義了,因此無論「傳入」如何都可以使用。 – asafreedman

+0

良好的通話,發表評論 – BigOmega

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函數立即並將其返回值傳遞給$()調用。 ready函數不返回任何值,因此該值爲undefined

的最後一行,那麼,是等價的:

$(undefined); 

這呼叫簡單地返回一個空jQuery對象([])。

罪魁禍首當然就是(jQuery)最後。添加這就是導致函數立即被調用的原因,而不是將參考傳遞給函數調用$()。括號內jQuery的存在是沒有意義的:這個ready函數並不期望任何參數,因此被忽略。如果()出現在那裏,這將是同樣的事情。

它非常像你setTimeout()和類似通話時看到一個常見的錯誤:

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

這就提出了一個問題:爲什麼沒有這個代碼運行到一個問題,因爲它不會不工作如預期?那麼,這個函數會被調用 - 唯一的區別是當它運行時

所以它沒有引起問題的兩個可能的原因。

  1. 這個代碼塊可能已被放置在<body>的端部由於是流行的做法,這些天。在這種情況下,當代碼運行時,DOM可能已經足夠了。 DOM元素按照<body>的加載順序創建,如果您在特定的DOM元素之後放置了<script>標記,則該元素在該腳本運行時確實可用。

  2. 該代碼可能不需要DOM準備就緒。查看博客文章中的驗證器代碼,它看起來像設置代碼,它在第一次運行時不會對DOM做任何事情。如果是這樣,那麼只要jQuery.validator插件已被加載,那麼如果此代碼立即運行或稍後在完整DOM準備就緒時運行,則不會有任何區別。

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> 
相關問題