javascript 客戶端驗(yàn)證上傳圖片的大?。嫒軮E和火狐)
更新時(shí)間:2009年08月15日 01:53:02 作者:
做web開發(fā)的哥們都會(huì)遇到批量上傳圖片的需求,相信大家都會(huì)遇到這樣的問(wèn)題,當(dāng)選擇好要上傳的圖片,提交服務(wù)器后,發(fā)現(xiàn)有圖片的大小超過(guò)了系統(tǒng)允許的范圍。
在我 上一篇帖子 (譯文 ) 中,談到了各個(gè)瀏覽器究竟會(huì)在什么情況下彈出腳本失控提示,對(duì)于Internet Explorer 來(lái)說(shuō),當(dāng)瀏覽器執(zhí)行了數(shù)量過(guò)多的語(yǔ)句時(shí)就會(huì)停止執(zhí)行腳本,而其他的瀏覽器,則是持續(xù)執(zhí)行腳本超過(guò)一定時(shí)間的時(shí)候就會(huì)給出提示。而我們要探討的核心問(wèn)題,不是這些瀏覽器如果探測(cè)失控的腳本,而是我們?nèi)绾尾趴梢宰屇_本運(yùn)行的更快一些,從而避免這些警告 。
腳本失控基本上有以下四個(gè)方面的原因:
在循環(huán)中執(zhí)行了太多的操作。
臃腫的函數(shù)體
過(guò)多的遞歸
過(guò)多的 DOM 調(diào)用
在這篇帖子中,我將會(huì)把重點(diǎn)放到第一條上:循環(huán)中的過(guò)多操作。循環(huán)的操作是同步進(jìn)行的,所以執(zhí)行一個(gè)循環(huán)所花費(fèi)的時(shí)間完全取決于循環(huán)的次數(shù)。因此有 兩種情況會(huì)導(dǎo)致循環(huán)執(zhí)行的時(shí)間過(guò)長(zhǎng),并直接導(dǎo)致鎖定瀏覽器。一是循環(huán)體中包含了太多的操作,二是循環(huán)的次數(shù)過(guò)多。這兩種情況都能直接導(dǎo)致鎖定瀏覽器,并顯示腳本失控的提示。
解決這個(gè)問(wèn)題的訣竅就是用下面這兩個(gè)問(wèn)題來(lái)評(píng)估每個(gè)循環(huán):
這個(gè)循環(huán)必須要同步執(zhí)行么?
循環(huán)里面的數(shù)據(jù),必須要按順序執(zhí)行么?
如果兩個(gè)問(wèn)題的答案都是否定的話,你就可以選擇將循環(huán) 里的操作進(jìn)行分解。關(guān)鍵是要根據(jù)代碼的具體環(huán)境確定上面兩個(gè)問(wèn)題的答案。一個(gè)典型的循環(huán)可能像下面這個(gè)樣子:
for(var i=0; i < items.length; i++){
process(items[i]);
}
乍一看這個(gè)循環(huán)并沒有太大的問(wèn)題,是不是會(huì)運(yùn)行很長(zhǎng)時(shí)間完全取決于循環(huán)的次數(shù)。如果緊接循環(huán)后沒有其他代碼在執(zhí)行的時(shí)候需要依賴于循環(huán)的結(jié)果,那么 對(duì)于第一個(gè)問(wèn)題的答案就是“ 不” 。你還可以發(fā)現(xiàn),循環(huán)每次只處理一個(gè)數(shù)值,而且不依賴于上一次循環(huán)的結(jié)果,所以對(duì)于第二個(gè)問(wèn)題的答案同樣也是否定的。這就意味著,循環(huán)可以通過(guò)某種方式進(jìn)行拆解,不會(huì)導(dǎo)致鎖定瀏覽器而顯示腳本失控的提示。
在《Professional JavaScript, Second Edition 》這本書中,對(duì)于那些執(zhí)行次數(shù)非常巨大的虛幻,我推薦使用下面的方式來(lái)處理:
function chunk(array, process, context){
setTimeout(function(){
var item = array.shift();
process.call(context, item);
if (array.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
}
chunk() 函數(shù)的用途就是將一個(gè)數(shù)組分成小塊處理(這也是名字的由來(lái)),我們可以傳遞三個(gè)參數(shù)。要處理的數(shù)組對(duì)象、處理函數(shù)以及一個(gè)可選的上下文變量,用于設(shè)置process() 函數(shù)中對(duì)應(yīng)的this 對(duì)象。第一個(gè)timer 用于處理操作之間的延時(shí)(這里設(shè)置為100 毫秒,大家可以根據(jù)實(shí)際需要自行修改)。每次執(zhí)行這個(gè)函數(shù),都會(huì)將數(shù)組中的第一個(gè)對(duì)象取出,并傳給process() 函數(shù)進(jìn)行操作,如果這時(shí)process() 中還有未處理完的對(duì)象, 另外一個(gè)timer 就會(huì)啟動(dòng),用于重復(fù)等待。上面提到的循環(huán),可以通過(guò)下面的方法使用這個(gè)函數(shù):
chunk(items, process);
需要注意的是,在這里數(shù)組采用了隊(duì)列(queue )的形式,而且在循環(huán)的過(guò)程中,每次都會(huì)發(fā)生修改。如果你要修改數(shù)組的原始狀態(tài),這里介紹兩種途徑:一種是通過(guò)concat() 函數(shù),在傳遞之前,建立一個(gè)當(dāng)前數(shù)組的副本:
chunk(items.concat(), process);
另外一種選擇是直接修改chunk() 函數(shù),直接在函數(shù)內(nèi)部進(jìn)行修改:
function chunk(array, process, context){
var items = array.concat(); //clone the array
setTimeout(function(){
var item = items.shift();
process.call(context, item);
if (items.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
}
注意這種方法要比只保存一個(gè)索引安全的多,因?yàn)閿?shù)組的內(nèi)容在下次計(jì)時(shí)器生效之前可能會(huì)發(fā)生變化。
這里提到的chunk() 函數(shù),只是優(yōu)化循環(huán)性能的一個(gè)起點(diǎn)。你可以根據(jù)需要不斷改進(jìn)它,讓它擁有更多的功能。比如說(shuō),在數(shù)組中所有對(duì)象都處理完成以后,可以增加一個(gè)函數(shù)回調(diào)。無(wú)論你是否會(huì)按照這種方式對(duì)函數(shù)進(jìn)行修改,這只是一種JavaScript 的代碼開發(fā)模式,可以幫助優(yōu)化數(shù)組的處理性能,還可以避免那個(gè)腳本失控的警告。
腳本失控基本上有以下四個(gè)方面的原因:
在循環(huán)中執(zhí)行了太多的操作。
臃腫的函數(shù)體
過(guò)多的遞歸
過(guò)多的 DOM 調(diào)用
在這篇帖子中,我將會(huì)把重點(diǎn)放到第一條上:循環(huán)中的過(guò)多操作。循環(huán)的操作是同步進(jìn)行的,所以執(zhí)行一個(gè)循環(huán)所花費(fèi)的時(shí)間完全取決于循環(huán)的次數(shù)。因此有 兩種情況會(huì)導(dǎo)致循環(huán)執(zhí)行的時(shí)間過(guò)長(zhǎng),并直接導(dǎo)致鎖定瀏覽器。一是循環(huán)體中包含了太多的操作,二是循環(huán)的次數(shù)過(guò)多。這兩種情況都能直接導(dǎo)致鎖定瀏覽器,并顯示腳本失控的提示。
解決這個(gè)問(wèn)題的訣竅就是用下面這兩個(gè)問(wèn)題來(lái)評(píng)估每個(gè)循環(huán):
這個(gè)循環(huán)必須要同步執(zhí)行么?
循環(huán)里面的數(shù)據(jù),必須要按順序執(zhí)行么?
如果兩個(gè)問(wèn)題的答案都是否定的話,你就可以選擇將循環(huán) 里的操作進(jìn)行分解。關(guān)鍵是要根據(jù)代碼的具體環(huán)境確定上面兩個(gè)問(wèn)題的答案。一個(gè)典型的循環(huán)可能像下面這個(gè)樣子:
復(fù)制代碼 代碼如下:
for(var i=0; i < items.length; i++){
process(items[i]);
}
乍一看這個(gè)循環(huán)并沒有太大的問(wèn)題,是不是會(huì)運(yùn)行很長(zhǎng)時(shí)間完全取決于循環(huán)的次數(shù)。如果緊接循環(huán)后沒有其他代碼在執(zhí)行的時(shí)候需要依賴于循環(huán)的結(jié)果,那么 對(duì)于第一個(gè)問(wèn)題的答案就是“ 不” 。你還可以發(fā)現(xiàn),循環(huán)每次只處理一個(gè)數(shù)值,而且不依賴于上一次循環(huán)的結(jié)果,所以對(duì)于第二個(gè)問(wèn)題的答案同樣也是否定的。這就意味著,循環(huán)可以通過(guò)某種方式進(jìn)行拆解,不會(huì)導(dǎo)致鎖定瀏覽器而顯示腳本失控的提示。
在《Professional JavaScript, Second Edition 》這本書中,對(duì)于那些執(zhí)行次數(shù)非常巨大的虛幻,我推薦使用下面的方式來(lái)處理:
復(fù)制代碼 代碼如下:
function chunk(array, process, context){
setTimeout(function(){
var item = array.shift();
process.call(context, item);
if (array.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
}
chunk() 函數(shù)的用途就是將一個(gè)數(shù)組分成小塊處理(這也是名字的由來(lái)),我們可以傳遞三個(gè)參數(shù)。要處理的數(shù)組對(duì)象、處理函數(shù)以及一個(gè)可選的上下文變量,用于設(shè)置process() 函數(shù)中對(duì)應(yīng)的this 對(duì)象。第一個(gè)timer 用于處理操作之間的延時(shí)(這里設(shè)置為100 毫秒,大家可以根據(jù)實(shí)際需要自行修改)。每次執(zhí)行這個(gè)函數(shù),都會(huì)將數(shù)組中的第一個(gè)對(duì)象取出,并傳給process() 函數(shù)進(jìn)行操作,如果這時(shí)process() 中還有未處理完的對(duì)象, 另外一個(gè)timer 就會(huì)啟動(dòng),用于重復(fù)等待。上面提到的循環(huán),可以通過(guò)下面的方法使用這個(gè)函數(shù):
chunk(items, process);
需要注意的是,在這里數(shù)組采用了隊(duì)列(queue )的形式,而且在循環(huán)的過(guò)程中,每次都會(huì)發(fā)生修改。如果你要修改數(shù)組的原始狀態(tài),這里介紹兩種途徑:一種是通過(guò)concat() 函數(shù),在傳遞之前,建立一個(gè)當(dāng)前數(shù)組的副本:
chunk(items.concat(), process);
另外一種選擇是直接修改chunk() 函數(shù),直接在函數(shù)內(nèi)部進(jìn)行修改:
復(fù)制代碼 代碼如下:
function chunk(array, process, context){
var items = array.concat(); //clone the array
setTimeout(function(){
var item = items.shift();
process.call(context, item);
if (items.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
}
注意這種方法要比只保存一個(gè)索引安全的多,因?yàn)閿?shù)組的內(nèi)容在下次計(jì)時(shí)器生效之前可能會(huì)發(fā)生變化。
這里提到的chunk() 函數(shù),只是優(yōu)化循環(huán)性能的一個(gè)起點(diǎn)。你可以根據(jù)需要不斷改進(jìn)它,讓它擁有更多的功能。比如說(shuō),在數(shù)組中所有對(duì)象都處理完成以后,可以增加一個(gè)函數(shù)回調(diào)。無(wú)論你是否會(huì)按照這種方式對(duì)函數(shù)進(jìn)行修改,這只是一種JavaScript 的代碼開發(fā)模式,可以幫助優(yōu)化數(shù)組的處理性能,還可以避免那個(gè)腳本失控的警告。
您可能感興趣的文章:
- 多個(gè)上傳文件用js驗(yàn)證文件的格式和大小的方法(推薦)
- 真正好用的js驗(yàn)證上傳文件大小的簡(jiǎn)單方法
- javascript驗(yàn)證上傳文件的類型限制必須為某些格式
- Node.js開發(fā)教程之基于OnceIO框架實(shí)現(xiàn)文件上傳和驗(yàn)證功能
- js驗(yàn)證上傳圖片的方法
- Javascript驗(yàn)證上傳圖片大小[前臺(tái)處理]
- 上傳的js驗(yàn)證(圖片/文件的擴(kuò)展名)
- js 圖片上傳前大小長(zhǎng)寬驗(yàn)證代碼
- Javascript 驗(yàn)證上傳圖片大小[客戶端]
- JS簡(jiǎn)單驗(yàn)證上傳文件類型的方法
相關(guān)文章
"好玩的放大鏡效果" 的另一種實(shí)現(xiàn)方法
"好玩的放大鏡效果" 的另一種實(shí)現(xiàn)方法...2006-11-11使用webpack/gulp構(gòu)建TypeScript項(xiàng)目的方法示例
這篇文章主要介紹了使用webpack/gulp構(gòu)建TypeScript項(xiàng)目的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12JavaScript 動(dòng)態(tài)添加腳本,并觸發(fā)回調(diào)函數(shù)的實(shí)現(xiàn)代碼
JavaScript 動(dòng)態(tài)添加腳本,并觸發(fā)回調(diào)函數(shù)的實(shí)現(xiàn)代碼,需要的朋友可以參考下。2011-01-01一個(gè)XML格式數(shù)據(jù)轉(zhuǎn)換為圖表的例子
這個(gè)例子使用的是轉(zhuǎn)換為VML的語(yǔ)法,換成其他如SVG的語(yǔ)法,就可以轉(zhuǎn)換成為SVG圖形,單元數(shù)量可以任意加。2010-02-02js前端實(shí)現(xiàn)圖片懶加載(lazyload)的兩種方式
本篇文章主要介紹了js前端實(shí)現(xiàn)圖片懶加載(lazyload)的兩種方式 ,使用圖片懶加載可以提高網(wǎng)頁(yè)運(yùn)行速度,有興趣的可以了解一下。2017-04-04寫入cookie的JavaScript代碼庫(kù) cookieLibrary.js
cookieLibrary.js 寫入cookie的JavaScript代碼庫(kù),需要的朋友可以參考下。2009-10-10如何在JavaScript中使用map()迭代數(shù)組詳細(xì)步驟
在JavaScript中循環(huán)迭代數(shù)組的方法有很多種,下面這篇文章主要給大家介紹了關(guān)于如何在JavaScript中使用map()迭代數(shù)組的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02