欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解JavaScript的回調(diào)函數(shù)

 更新時(shí)間:2015年11月20日 11:16:22   投稿:lijiao  
這篇文章主要介紹了JavaScript的回調(diào)函數(shù),幫助大家正確理解和使用 JavaScript中的回調(diào)函數(shù),感興趣的小伙伴們可以參考一下

本文的目錄:

  • 什么是回調(diào)或高級(jí)函數(shù)
  • 回調(diào)函數(shù)是如何實(shí)現(xiàn)的
  • 實(shí)現(xiàn)回調(diào)函數(shù)的基本原則
  • 回調(diào)地獄的問(wèn)題和解決方案
  • 實(shí)現(xiàn)自己的回調(diào)函數(shù)

在JavaScrip中,function是內(nèi)置的類對(duì)象,也就是說(shuō)它是一種類型的對(duì)象,可以和其它String、Array、Number、Object類的對(duì)象一樣用于內(nèi)置對(duì)象的管理。因?yàn)閒unction實(shí)際上是一種對(duì)象,它可以“存儲(chǔ)在變量中,通過(guò)參數(shù)傳遞給(別一個(gè))函數(shù)(function),在函數(shù)內(nèi)部創(chuàng)建,從函數(shù)中返回結(jié)果值”。

因?yàn)閒unction是內(nèi)置對(duì)象,我們可以將它作為參數(shù)傳遞給另一個(gè)函數(shù),延遲到函數(shù)中執(zhí)行,甚至執(zhí)行后將它返回。這是在JavaScript中使用回調(diào)函數(shù)的精髓。本篇文章的剩余部分將全面學(xué)習(xí)JavaScript的回調(diào)函數(shù)?;卣{(diào)函數(shù)也許是JavaScript中使用最廣泛的功能性編程技術(shù),也許僅僅一小段JavaScript或jQuery的代碼都會(huì)給開(kāi)發(fā)者留下一種神秘感,閱讀這篇文章后,也許會(huì)幫你消除這種神秘感。
回調(diào)函數(shù)來(lái)自一種著名的編程范式——函數(shù)式編程,在基本層面上,函數(shù)式編程指定的了函數(shù)的參數(shù)。函數(shù)式編程雖然現(xiàn)在的使用范圍變小了,但它一直被“專業(yè)的聰明的”程序員看作是一種難懂的技術(shù),以前是這樣,未來(lái)也將是如此。

幸運(yùn)的是,函數(shù)式編程已經(jīng)被闡述的像你我這樣的一般人也能理解和使用。函數(shù)式編程最主要的技術(shù)之一就是回調(diào)函數(shù),你很快會(huì)閱讀到,實(shí)現(xiàn)回調(diào)函數(shù)就像傳遞一般的參數(shù)變量一樣簡(jiǎn)單。這項(xiàng)技術(shù)如此的簡(jiǎn)單,以至于我都懷疑為什么它經(jīng)常被包含在JavaScript的高級(jí)話題中去。

一、什么是回調(diào)或高級(jí)函數(shù)?

回調(diào)函數(shù)被認(rèn)為是一種高級(jí)函數(shù),一種被作為參數(shù)傳遞給另一個(gè)函數(shù)(在這稱作"otherFunction")的高級(jí)函數(shù),回調(diào)函數(shù)會(huì)在otherFunction內(nèi)被調(diào)用(或執(zhí)行)?;卣{(diào)函數(shù)的本質(zhì)是一種模式(一種解決常見(jiàn)問(wèn)題的模式),因此回調(diào)函數(shù)也被稱為回調(diào)模式。

思考一下下面這種在jQuery中常用的回調(diào)函數(shù):

//Note that the item in the click method's parameter is a function, not a variable.
//The item is a callback function
$("#btn_1").click(function() {
 alert("Btn 1 Clicked");
});

正如在前面的例子所看到的,我們傳遞了一個(gè)函數(shù)給click方法的形參,click方法將會(huì)調(diào)用(或執(zhí)行)我們傳遞給它的回調(diào)函數(shù)。這個(gè)例子就給出了JavaScript中使用回調(diào)函數(shù)的一個(gè)典型方式,并廣泛應(yīng)用于jQuery中。

細(xì)細(xì)體味一下另一個(gè)基本JavaScript的典型例子:

var friends = ["Mike", "Stacy", "Andy", "Rick"];

friends.forEach(function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick
});

我們?cè)僖淮斡猛瑯拥姆绞絺鬟f了一個(gè)匿名的函數(shù)(沒(méi)有函數(shù)名的函數(shù))給forEach方法,作為forEach的參數(shù)。

到目前為止,我們傳遞了一個(gè)匿名的函數(shù)作為參數(shù)給另一個(gè)函數(shù)或方法。在看其它更復(fù)雜的回調(diào)函數(shù)之前,讓我們理解一下回調(diào)的工作原理并實(shí)現(xiàn)一個(gè)自己的回調(diào)函數(shù)。

二、回調(diào)函數(shù)是如何實(shí)現(xiàn)的?

我們可以像使用變量一樣使用函數(shù),作為另一個(gè)函數(shù)的參數(shù),在另一個(gè)函數(shù)中作為返回結(jié)果,在另一個(gè)函數(shù)中調(diào)用它。當(dāng)我們作為參數(shù)傳遞一個(gè)回調(diào)函數(shù)給另一個(gè)函數(shù)時(shí),我們只傳遞了這個(gè)函數(shù)的定義,并沒(méi)有在參數(shù)中執(zhí)行它。

當(dāng)包含(調(diào)用)函數(shù)擁有了在參數(shù)中定義的回調(diào)函數(shù)后,它可以在任何時(shí)候調(diào)用(也就是回調(diào))它。

這說(shuō)明回調(diào)函數(shù)并不是立即執(zhí)行,而是在包含函數(shù)的函數(shù)體內(nèi)指定的位置“回調(diào)”它(形如其名)。所以,即使第一個(gè)jQuery的例子看起來(lái)是這樣:

//The anonymous function is not being executed there in the parameter. 
//The item is a callback function
$("#btn_1").click(function() {
 alert("Btn 1 Clicked");
});

匿名函數(shù)將延遲在click函數(shù)的函數(shù)體內(nèi)被調(diào)用,即使沒(méi)有名稱,也可以被包含函數(shù)通過(guò) arguments對(duì)象訪問(wèn)。

回調(diào)函數(shù)是閉包的
當(dāng)作為參數(shù)傳遞一個(gè)回調(diào)函數(shù)給另一個(gè)函數(shù)時(shí),回調(diào)函數(shù)將在包含函數(shù)函數(shù)體內(nèi)的某個(gè)位置被執(zhí)行,就像回調(diào)函數(shù)在包含函數(shù)的函數(shù)體內(nèi)定義一樣。這意味著回調(diào)函數(shù)是閉包的,想更多地了解閉包,請(qǐng)參考作者另一個(gè)貼子Understand JavaScript Closures With Ease。從所周知,閉包函數(shù)可以訪問(wèn)包含函數(shù)的作用域,所以,回調(diào)函數(shù)可以訪問(wèn)包含函數(shù)的變量,甚至是全局變量。

三、實(shí)現(xiàn)回調(diào)函數(shù)的基本原則

簡(jiǎn)單地說(shuō),自己實(shí)現(xiàn)回調(diào)函數(shù)的時(shí)候需要遵循幾條原則。

1、使用命名函數(shù)或匿名函數(shù)作為回調(diào)
在前面的jQuery和forEach的例子中,我們?cè)诎瘮?shù)的參數(shù)中定義匿名函數(shù),這是使用回調(diào)函數(shù)的通用形式之一,另一個(gè)經(jīng)常被使用的形式是定義一個(gè)帶名稱的函數(shù),并將函數(shù)名作為參數(shù)傳遞給另一個(gè)函數(shù),例如:


// global variable
var allUserData = [];

// generic logStuff function that prints to console
function logStuff (userData) {
  if ( typeof userData === "string")
  {
    console.log(userData);
  }
  else if ( typeof userData === "object")
  {
    for (var item in userData) {
      console.log(item + ": " + userData[item]);
    }

  }

}

// A function that takes two parameters, the last one a callback function
function getInput (options, callback) {
  allUserData.push (options);
  callback (options);

}

// When we call the getInput function, we pass logStuff as a parameter.
// So logStuff will be the function that will called back (or executed) inside the getInput function
getInput ({name:"Rich", speciality:"JavaScript"}, logStuff);
// name: Rich
// speciality: JavaScript

2、傳遞參數(shù)給回調(diào)函數(shù)
因?yàn)榛卣{(diào)函數(shù)在執(zhí)行的時(shí)候就和一般函數(shù)一樣,我們可以傳遞參數(shù)給它。可以將包含函數(shù)的任何屬性(或全局的屬性)作為參數(shù)傳遞回調(diào)函數(shù)。在上一個(gè)例子中,我們將包含函數(shù)的options作為參數(shù)傳遞給回調(diào)函數(shù)。下面的例子讓我們傳遞一個(gè)全局變量或本地變量給回調(diào)函數(shù):

//Global variable
var generalLastName = "Clinton";

function getInput (options, callback) {
  allUserData.push (options);
// Pass the global variable generalLastName to the callback function
  callback (generalLastName, options);
}

3、在執(zhí)行之前確?;卣{(diào)是一個(gè)函數(shù)
在調(diào)用之前,確保通過(guò)參數(shù)傳遞進(jìn)來(lái)的回調(diào)是一個(gè)需要的函數(shù)通常是明智的。此外,讓回調(diào)函數(shù)是可選的也是一個(gè)好的實(shí)踐。

讓我們重構(gòu)一下上面例子中的getInput函數(shù),確?;卣{(diào)函數(shù)做了適當(dāng)?shù)臋z查。

function getInput(options, callback) {
  allUserData.push(options);

  // Make sure the callback is a function
  if (typeof callback === "function") {
  // Call it, since we have confirmed it is callable
    callback(options);
  }
}

如果getInput函數(shù)沒(méi)有做適當(dāng)?shù)臋z查(檢查callback是否是函數(shù),或是否通過(guò)參數(shù)傳遞進(jìn)來(lái)了),我們的代碼將會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。

4、使用含有this對(duì)象的回調(diào)函數(shù)的問(wèn)題
當(dāng)回調(diào)函數(shù)是一個(gè)含有this對(duì)象的方法時(shí),我們必須修改執(zhí)行回調(diào)函數(shù)的方法以保護(hù)this對(duì)象的內(nèi)容。否則this對(duì)象將會(huì)指向全局的window對(duì)象(如果回調(diào)函數(shù)傳遞給了全局函數(shù)),或指向包含函數(shù)。讓我們看看下面的代碼:

// Define an object with some properties and a method
// We will later pass the method as a callback function to another function
var clientData = {
  id: 094545,
  fullName: "Not Set",
  // setUserName is a method on the clientData object
  setUserName: function (firstName, lastName) {
    // this refers to the fullName property in this object
   this.fullName = firstName + " " + lastName;
  }
}

function getUserInput(firstName, lastName, callback) {
  // Do other stuff to validate firstName/lastName here

  // Now save the names
  callback (firstName, lastName);
}

在下面的示例代碼中,當(dāng)clientData.setUserName被執(zhí)行時(shí),this.fullName不會(huì)設(shè)置clientData 對(duì)象中的屬性fullName,而是設(shè)置window 對(duì)象中的fullName,因?yàn)間etUserInput是一個(gè)全局函數(shù)。出現(xiàn)這種現(xiàn)象是因?yàn)樵谌趾瘮?shù)中this對(duì)象指向了window對(duì)象。

getUserInput ("Barack", "Obama", clientData.setUserName);

console.log (clientData.fullName);// Not Set

// The fullName property was initialized on the window object
console.log (window.fullName); // Barack Obama

5、使用Call或Apply函數(shù)保護(hù)this對(duì)象

我們可以通過(guò)使用 Call 或 Apply函數(shù)來(lái)解決前面示例中的問(wèn)題。到目前為止,我們知道JavaScript中的每一個(gè)函數(shù)都有兩個(gè)方法:Call和Apply。這些方法可以被用來(lái)在函數(shù)內(nèi)部設(shè)置this對(duì)象的內(nèi)容,并內(nèi)容傳遞給函數(shù)參數(shù)指向的對(duì)象。

Call takes the value to be used as the this object inside the function as the first parameter, and the remaining arguments to be passed to the function are passed individually (separated by commas of course). The Apply function's first parameter is also the value to be used as the thisobject inside the function, while the last parameter is an array of values (or the arguments object) to pass to the function.  (該段翻譯起來(lái)太拗口了,放原文自己體會(huì))

這聽(tīng)起來(lái)很復(fù)雜,但讓我們看看Apply和Call的使用是多么容易。為解決前面例子中出現(xiàn)的問(wèn)題,我們使用Apply函數(shù)如下:

//Note that we have added an extra parameter for the callback object, called "callbackObj"
function getUserInput(firstName, lastName, callback, callbackObj) {
  // Do other stuff to validate name here

  // The use of the Apply function below will set the this object to be callbackObj
  callback.apply (callbackObj, [firstName, lastName]);
}

通過(guò)Apply函數(shù)正確地設(shè)置this對(duì)象,現(xiàn)在我們可以正確地執(zhí)行回調(diào)函數(shù)并它正確地設(shè)置clientData對(duì)象中的fullName屬性。

// We pass the clientData.setUserName method and the clientData object as parameters. The clientData object will be used by the Apply function to set the this object

getUserInput ("Barack", "Obama", clientData.setUserName, clientData);

// the fullName property on the clientData was correctly set
console.log (clientData.fullName); // Barack Obama

我們也可以使用Call 函數(shù),但在本例中我們使用的Apply 函數(shù)。

6、多重回調(diào)函數(shù)也是允許的
我們可以傳遞多個(gè)回調(diào)函數(shù)給另一個(gè)函數(shù),就像傳遞多個(gè)變量一樣。這是使用jQuery的AJAX函數(shù)的典型例子:

function successCallback() {
  // Do stuff before send
}

function successCallback() {
  // Do stuff if success message received
}

function completeCallback() {
  // Do stuff upon completion
}

function errorCallback() {
  // Do stuff if error received
}

$.ajax({
  url:"http://fiddle.jshell.net/favicon.png",
  success:successCallback,
  complete:completeCallback,
  error:errorCallback

});

四、“回調(diào)地獄”的問(wèn)題和解決方案

異步代碼執(zhí)行是一種簡(jiǎn)單的以任意順序執(zhí)行的方式,有時(shí)是很常見(jiàn)的有很多層級(jí)的回調(diào)函數(shù),你看起來(lái)像下面這樣的代碼。下面這種凌亂的代碼稱作“回調(diào)地獄”,因?yàn)樗且环N包含非常多的回調(diào)的麻煩的代碼。我是在node-mongodb-native里看到這個(gè)例子的,MongoDB驅(qū)動(dòng)Node.js.示例代碼就像這樣:

var p_client = new Db('integration_tests_20', new Server("127.0.0.1", 27017, {}), {'pk':CustomPKFactory});
p_client.open(function(err, p_client) {
  p_client.dropDatabase(function(err, done) {
    p_client.createCollection('test_custom_key', function(err, collection) {
      collection.insert({'a':1}, function(err, docs) {
        collection.find({'_id':new ObjectID("aaaaaaaaaaaa")}, function(err, cursor) {
          cursor.toArray(function(err, items) {
            test.assertEquals(1, items.length);

            // Let's close the db
            p_client.close();
          });
        });
      });
    });
  });
});

你不太可能在自己的代碼里碰到這個(gè)的問(wèn)題,但如果你碰到了(或以后偶然碰到了),那么有以下兩種方式解決這個(gè)問(wèn)題。

命名并定義你的函數(shù),然后傳遞函數(shù)名作為回調(diào),而不是在主函數(shù)的參數(shù)列表里定義一個(gè)匿名函數(shù)。
模塊化:把你的代碼劃分成一個(gè)個(gè)模塊,這樣你可以空出一部分代碼塊做特殊的工作。然后你可以將這個(gè)模型引入到你的大型應(yīng)用程序中。

五、實(shí)現(xiàn)自己的回調(diào)函數(shù)

現(xiàn)在你已經(jīng)完全理解(我相信你已經(jīng)理解了,如果沒(méi)有請(qǐng)快速重新閱讀一遍)了JavaScript關(guān)于回調(diào)的所用特性并且看到回調(diào)的使用是如此簡(jiǎn)單但功能卻很強(qiáng)大。你應(yīng)該看看自己的代碼是否有機(jī)會(huì)使用回調(diào)函數(shù),有以下需求時(shí)你可以考慮使用回調(diào):

  • 避免重復(fù)代碼 (DRY—Do Not Repeat Yourself)
  • 在你需要更多的通用功能的地方更好地實(shí)現(xiàn)抽象(可處理各種類型的函數(shù))。
  • 增強(qiáng)代碼的可維護(hù)性
  • 增強(qiáng)代碼的可讀性
  • 有更多定制的功能

實(shí)現(xiàn)自己的回調(diào)函數(shù)很簡(jiǎn)單,在下面的例子中,我可以創(chuàng)建一個(gè)函數(shù)完成所用的工作:獲取用戶數(shù)據(jù),使用用戶數(shù)據(jù)生成一首通用的詩(shī),使用用戶數(shù)據(jù)來(lái)歡迎用戶,但這個(gè)函數(shù)將會(huì)是一個(gè)凌亂的函數(shù),到處是if/else的判斷,甚至?xí)泻芏嗟南拗撇o(wú)法執(zhí)行應(yīng)用程序可能需要的處理用戶數(shù)據(jù)的其它函數(shù)。

替而代之的是我讓實(shí)現(xiàn)增加了回調(diào)函數(shù),這樣主函數(shù)獲取用戶數(shù)據(jù)后可以傳遞用戶全名和性別給回調(diào)函數(shù)的參數(shù)并執(zhí)行回調(diào)函數(shù)以完成任何任務(wù)。

簡(jiǎn)而言之,getUserInput函數(shù)是通用的,它可以執(zhí)行多個(gè)擁有各種功能的回調(diào)函數(shù)。

// First, setup the generic poem creator function; it will be the callback function in the getUserInput function below.
function genericPoemMaker(name, gender) {
  console.log(name + " is finer than fine wine.");
  console.log("Altruistic and noble for the modern time.");
  console.log("Always admirably adorned with the latest style.");
  console.log("A " + gender + " of unfortunate tragedies who still manages a perpetual smile");
}

//The callback, which is the last item in the parameter, will be our genericPoemMaker function we defined above.
function getUserInput(firstName, lastName, gender, callback) {
  var fullName = firstName + " " + lastName;

  // Make sure the callback is a function
  if (typeof callback === "function") {
  // Execute the callback function and pass the parameters to it
  callback(fullName, gender);
  }
}

調(diào)用getUserInput函數(shù)并傳遞genericPoemMaker函數(shù)作為回調(diào):

getUserInput("Michael", "Fassbender", "Man", genericPoemMaker);
// Output
/* Michael Fassbender is finer than fine wine.
Altruistic and noble for the modern time.
Always admirably adorned with the latest style.
A Man of unfortunate tragedies who still manages a perpetual smile.
*/

因?yàn)間etUserInput 函數(shù)只處理用戶數(shù)據(jù)的輸入,我們可以傳遞任何回調(diào)函數(shù)給它。例如我們可以像這樣傳遞一個(gè)greetUser函數(shù)。

function greetUser(customerName, sex) {
  var salutation = sex && sex === "Man" ? "Mr." : "Ms.";
 console.log("Hello, " + salutation + " " + customerName);
}

// Pass the greetUser function as a callback to getUserInput
getUserInput("Bill", "Gates", "Man", greetUser);

// And this is the output
Hello, Mr. Bill Gates

和上一個(gè)例子一樣,我們調(diào)用了同一個(gè)getUserInput 函數(shù),但這次卻執(zhí)行了完全不同的任務(wù)。

如你所見(jiàn),回調(diào)函數(shù)提供了廣泛的功能。盡管前面提到的例子非常簡(jiǎn)單,在你開(kāi)始使用回調(diào)函數(shù)的時(shí)候思考一下你可以節(jié)省多少工作,如何更好地抽象你的代碼。加油吧!在早上起來(lái)時(shí)想一想,在晚上睡覺(jué)前想一想,在你休息時(shí)想一想……

我們?cè)贘avaScript中經(jīng)常使用回調(diào)函數(shù)時(shí)注意以下幾點(diǎn),尤其是現(xiàn)在的web應(yīng)用開(kāi)發(fā),在第三方庫(kù)和框架中

  • 異步執(zhí)行(例如讀文件,發(fā)送HTTP請(qǐng)求)
  • 事件監(jiān)聽(tīng)和處理
  • 設(shè)置超時(shí)和時(shí)間間隔的方法
  • 通用化:代碼簡(jiǎn)潔

以上就是更加深入的學(xué)習(xí)了JavaScript的回調(diào)函數(shù),希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • javascript實(shí)現(xiàn)九宮格相加數(shù)值相等

    javascript實(shí)現(xiàn)九宮格相加數(shù)值相等

    這篇文章主要介紹了javascript實(shí)現(xiàn)九宮格相加數(shù)值相等的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-02-02
  • JavaScript實(shí)現(xiàn)密碼框驗(yàn)證信息

    JavaScript實(shí)現(xiàn)密碼框驗(yàn)證信息

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)密碼框驗(yàn)證信息,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Openlayers實(shí)現(xiàn)點(diǎn)閃爍擴(kuò)散效果

    Openlayers實(shí)現(xiàn)點(diǎn)閃爍擴(kuò)散效果

    這篇文章主要為大家詳細(xì)介紹了Openlayers實(shí)現(xiàn)點(diǎn)閃爍擴(kuò)散效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • 淺談javascript中的數(shù)據(jù)類型轉(zhuǎn)換

    淺談javascript中的數(shù)據(jù)類型轉(zhuǎn)換

    本文主要對(duì)javascript中的數(shù)據(jù)類型轉(zhuǎn)換進(jìn)行介紹,具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2016-12-12
  • javascript 繪制矩形框

    javascript 繪制矩形框

    今天讀John Resig的Pro Javascript Techniques時(shí)候看到他書(shū)上給的一個(gè)關(guān)于drag and drop的例子,我做的第二件事就是js模擬用鼠標(biāo)拖出矩形框,代碼很簡(jiǎn)單
    2009-04-04
  • JS實(shí)現(xiàn)判斷有效的數(shù)獨(dú)算法示例

    JS實(shí)現(xiàn)判斷有效的數(shù)獨(dú)算法示例

    這篇文章主要介紹了JS實(shí)現(xiàn)判斷有效的數(shù)獨(dú)算法,結(jié)合實(shí)例形式分析了javascript數(shù)獨(dú)判斷的原理及相關(guān)算法實(shí)現(xiàn)、使用操作技巧,需要的朋友可以參考下
    2019-02-02
  • js觸發(fā)select onchange事件的小技巧

    js觸發(fā)select onchange事件的小技巧

    select 或text的onchange事件需要手動(dòng)改變select或text的值才能觸發(fā),下面有個(gè)不錯(cuò)的方法可以通過(guò)js觸發(fā)select onchange事件
    2014-08-08
  • 詳解TypeScript中類的定義與用法

    詳解TypeScript中類的定義與用法

    TypeScript是一種開(kāi)源的編程語(yǔ)言,它是JavaScript的超集,這篇文章主要來(lái)和大家介紹一下TypeScript中類的定義與用法,感興趣的小伙伴可以了解一下
    2023-06-06
  • javascript 不讓鼠標(biāo)事件觸發(fā)

    javascript 不讓鼠標(biāo)事件觸發(fā)

    div上加了onclick事件,里面又有超鏈a,點(diǎn)超鏈的時(shí)候能不觸發(fā)div 的事件嗎?
    2007-12-12
  • JS實(shí)現(xiàn)批量上傳文件并顯示進(jìn)度功能

    JS實(shí)現(xiàn)批量上傳文件并顯示進(jìn)度功能

    這篇文章主要介紹了JS實(shí)現(xiàn)批量上傳文件并顯示進(jìn)度功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-06-06

最新評(píng)論