全面了解javascript中的錯(cuò)誤處理機(jī)制
前面的話
錯(cuò)誤處理對(duì)于web應(yīng)用程序開(kāi)發(fā)至關(guān)重要,不能提前預(yù)測(cè)到可能發(fā)生的錯(cuò)誤,不能提前采取恢復(fù)策略,可能導(dǎo)致較差的用戶體驗(yàn)。由于任何javascript錯(cuò)誤都可能導(dǎo)致網(wǎng)頁(yè)無(wú)法使用,因此作為開(kāi)發(fā)人員,必須要知道何時(shí)可能出錯(cuò),為什么會(huì)出錯(cuò),以及會(huì)出什么錯(cuò)。本文將詳細(xì)介紹javascript中的錯(cuò)誤處理機(jī)制
error對(duì)象
error對(duì)象是包含錯(cuò)誤信息的對(duì)象,是javascript的原生對(duì)象。當(dāng)代碼解析或運(yùn)行時(shí)發(fā)生錯(cuò)誤,javascript引擎就會(huì)自動(dòng)產(chǎn)生并拋出一個(gè)error對(duì)象的實(shí)例,然后整個(gè)程序就中斷在發(fā)生錯(cuò)誤的地方
console.log(t);//Uncaught ReferenceError: t is not defined
ECMA-262規(guī)定了error對(duì)象包括兩個(gè)屬性:message和name。message屬性保存著錯(cuò)誤信息,而name屬性保存錯(cuò)誤類(lèi)型
//一般地,使用try-catch語(yǔ)句來(lái)捕獲錯(cuò)誤 try{ t; }catch(ex){ console.log(ex.message);//t is not defined console.log(ex.name);//ReferenceError }
瀏覽器還對(duì)error對(duì)象的屬性做了擴(kuò)展,添加了其他相關(guān)信息。其中各瀏覽器廠商實(shí)現(xiàn)最多的是stack屬性,它表示棧跟蹤信息(safari不支持)
try{ t; }catch(ex){ console.log(ex.stack);//@file:///D:/wamp/www/form.html:12:2 }
當(dāng)然,可以使用error()構(gòu)造函數(shù)來(lái)創(chuàng)建錯(cuò)誤對(duì)象。如果指定message參數(shù),則該error對(duì)象將把它用做它的message屬性;若不指定,它將使用一個(gè)預(yù)定義的默認(rèn)字符串作為該屬性的值
new Error(); new Error(message); //一般地,使用throw語(yǔ)句來(lái)拋出錯(cuò)誤 throw new Error('test'); //Uncaught Error: test throw new Error();//Uncaught Error
function UserError(message) { this.message = message; this.name = "UserError"; } UserError.prototype = new Error(); UserError.prototype.constructor = UserError; throw new UserError("errorMessage");//Uncaught UserError: errorMessage
當(dāng)不使用new操作符,直接將Error()構(gòu)造函數(shù)像一個(gè)函數(shù)一樣調(diào)用時(shí),它的行為和帶new操作符調(diào)用時(shí)一樣
Error(); Error(message); throw Error('test');//Uncaught Error: test throw Error();//Uncaught Error
error對(duì)象有一個(gè)toString()方法,返回'Error:'+ error對(duì)象的message屬性
var test = new Error('testError'); console.log(test.toString());//'Error: testError'
error類(lèi)型
執(zhí)行代碼期間可能會(huì)發(fā)生的錯(cuò)誤有多種類(lèi)型。每種錯(cuò)誤都有對(duì)應(yīng)的錯(cuò)誤類(lèi)型,而當(dāng)錯(cuò)誤發(fā)生時(shí),就會(huì)拋出相應(yīng)類(lèi)型的錯(cuò)誤對(duì)象。ECMA-262定義了下列7種錯(cuò)誤類(lèi)型:
Error EvalError(eval錯(cuò)誤) RangeError(范圍錯(cuò)誤) ReferenceError(引用錯(cuò)誤) SyntaxError(語(yǔ)法錯(cuò)誤) TypeError(類(lèi)型錯(cuò)誤) URIError(URI錯(cuò)誤)
其中,Error是基類(lèi)型,其他錯(cuò)誤類(lèi)型都繼承自該類(lèi)型。因此,所有錯(cuò)誤類(lèi)型共享了一組相同的屬性。Error類(lèi)型的錯(cuò)誤很少見(jiàn),如果有也是瀏覽器拋出的;這個(gè)基類(lèi)型的主要目的是供開(kāi)發(fā)人員拋出自定義錯(cuò)誤
【EvalError(eval錯(cuò)誤)】
eval函數(shù)沒(méi)有被正確執(zhí)行時(shí),會(huì)拋出EvalError錯(cuò)誤。該錯(cuò)誤類(lèi)型已經(jīng)不再在ES5中出現(xiàn)了,只是為了保證與以前代碼兼容,才繼續(xù)保留
【RangeError(范圍錯(cuò)誤)】
RangeError類(lèi)型的錯(cuò)誤會(huì)在一個(gè)值超出相應(yīng)范圍時(shí)觸發(fā),主要包括超出數(shù)組長(zhǎng)度范圍以及超出數(shù)字取值范圍等
new Array(-1);//Uncaught RangeError: Invalid array length new Array(Number.MAX_VALUE);//Uncaught RangeError: Invalid array length (1234).toExponential(21);//Uncaught RangeError: toExponential() argument must be between 0 and 20 (1234).toExponential(-1);////Uncaught RangeError: toExponential() argument must be between 0 and 20
【ReferenceError(引用錯(cuò)誤)】
引用一個(gè)不存在的變量或左值(lvalue)類(lèi)型錯(cuò)誤時(shí),會(huì)觸發(fā)ReferenceError(引用錯(cuò)誤)
a;//Uncaught ReferenceError: a is not defined 1++;//Uncaught ReferenceError: Invalid left-hand side expression in postfix operation
【SyntaxError(語(yǔ)法錯(cuò)誤)】
當(dāng)不符合語(yǔ)法規(guī)則時(shí),會(huì)拋出SyntaxError(語(yǔ)法錯(cuò)誤)
//變量名錯(cuò)誤 var 1a;//Uncaught SyntaxError: Unexpected number // 缺少括號(hào) console.log 'hello');//Uncaught SyntaxError: Unexpected string
【TypeError(類(lèi)型錯(cuò)誤)】
在變量中保存著意外的類(lèi)型時(shí),或者在訪問(wèn)不存在的方法時(shí),都會(huì)導(dǎo)致TypeError類(lèi)型錯(cuò)誤。錯(cuò)誤的原因雖然多種多樣,但歸根結(jié)底還是由于在執(zhí)行特定類(lèi)型的操作時(shí),變量的類(lèi)型并不符合要求所致
var o = new 10;//Uncaught TypeError: 10 is not a constructor alert('name' in true);//Uncaught TypeError: Cannot use 'in' operator to search for 'name' in true Function.prototype.toString.call('name');//Uncaught TypeError: Function.prototype.toString is not generic
【URIError(URI錯(cuò)誤)】
URIError是URI相關(guān)函數(shù)的參數(shù)不正確時(shí)拋出的錯(cuò)誤,主要涉及encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()、escape()和unescape()這六個(gè)函數(shù)
decodeURI('%2');// URIError: URI malformed
error事件
任何沒(méi)有通過(guò)try-catch處理的錯(cuò)誤都會(huì)觸發(fā)window對(duì)象的error事件
error事件可以接收三個(gè)參數(shù):錯(cuò)誤消息、錯(cuò)誤所在的URL和行號(hào)。多數(shù)情況下,只有錯(cuò)誤消息有用,因?yàn)閁RL只是給出了文檔的位置,而行號(hào)所指的代碼行既可能出自嵌入的JavaScript代碼,也可能出自外部的文件
要指定onerror事件處理程序,可以使用DOM0級(jí)技術(shù),也可以使用DOM2級(jí)事件的標(biāo)準(zhǔn)格式
//DOM0級(jí) window.onerror = function(message,url,line){ alert(message); } //DOM2級(jí) window.addEventListener("error",function(message,url,line){ alert(message); });
瀏覽器是否顯示標(biāo)準(zhǔn)的錯(cuò)誤消息,取決于onerror的返回值。如果返回值為false,則在控制臺(tái)中顯示錯(cuò)誤消息;如果返回值為true,則不顯示
//控制臺(tái)顯示錯(cuò)誤消息 window.onerror = function(message,url,line){ alert(message); return false; } a; //控制臺(tái)不顯示錯(cuò)誤消息 window.onerror = function(message,url,line){ alert(message); return true; } a;
這個(gè)事件處理程序是避免瀏覽器報(bào)告錯(cuò)誤的最后一道防線。理想情況下,只要可能就不應(yīng)該使用它。只要能夠適當(dāng)?shù)厥褂胻ry-catch語(yǔ)句,就不會(huì)有錯(cuò)誤交給瀏覽器,也就不會(huì)觸發(fā)error事件
圖像也支持error事件。只要圖像的src特性中的URL不能返回可以被識(shí)別的圖像格式,就會(huì)觸發(fā)error事件。此時(shí)的error事件遵循DOM格式,會(huì)返回一個(gè)以圖像為目標(biāo)的event對(duì)象
加載圖像失敗時(shí)會(huì)顯示一個(gè)警告框。發(fā)生error事件時(shí),圖像下載過(guò)程已經(jīng)結(jié)束,也就是不能再重新下載了
var image = new Image(); image.src = 'smilex.gif'; image.onerror = function(e){ console.log(e); }
throw語(yǔ)句與拋出錯(cuò)誤
throw語(yǔ)句用于拋出錯(cuò)誤。拋出錯(cuò)誤時(shí),必須要給throw語(yǔ)句指定一個(gè)值,這個(gè)值是什么類(lèi)型,沒(méi)有要求
[注意]拋出錯(cuò)誤的過(guò)程是阻塞的,后續(xù)代碼將不會(huì)執(zhí)行
throw 12345; throw 'hello world'; throw true; throw {name: 'javascript'};
可以使用throw語(yǔ)句手動(dòng)拋出一個(gè)Error對(duì)象
throw new Error('something bad happened'); throw new SyntaxError('I don\'t like your syntax.'); throw new TypeError('what type of variable do you take me for?'); throw new RangeError('sorry,you just don\'t have the range.'); throw new EvalError('That doesn\'t evaluate.'); throw new URIError('URI, is that you?'); throw new ReferenceError('you didn\'t cite your references properly');
利用原型鏈還可以通過(guò)繼承Error來(lái)創(chuàng)建自定義錯(cuò)誤類(lèi)型(原型鏈在第6章中介紹)。此時(shí),需要為新創(chuàng)建的錯(cuò)誤類(lèi)型指定name和message屬性
瀏覽器對(duì)待繼承自Error的自定義錯(cuò)誤類(lèi)型,就像對(duì)待其他錯(cuò)誤類(lèi)型一樣。如果要捕獲自己拋出的錯(cuò)誤并且把它與瀏覽器錯(cuò)誤區(qū)別對(duì)待的話,創(chuàng)建自定義錯(cuò)誤是很有用的
function CustomError(message){ this.name = 'CustomError'; this.message = message; } CustomError.prototype = new Error(); throw new CustomError('my message');
在遇到throw語(yǔ)句時(shí),代碼會(huì)立即停止執(zhí)行。僅當(dāng)有try-catch語(yǔ)句捕獲到被拋出的值時(shí),代碼才會(huì)繼續(xù)執(zhí)行
更詳細(xì)的解釋為:當(dāng)拋出異常時(shí),javascript解釋器會(huì)立即停止當(dāng)前正在執(zhí)行的邏輯,并跳轉(zhuǎn)到就近的異常處理程序。異常處理程序是用try-catch語(yǔ)句的catch從句編寫(xiě)的。如果拋出異常的代碼塊沒(méi)有一條相關(guān)聯(lián)的catch從句,解釋器會(huì)檢查更高層的閉合代碼塊,看它是否有相關(guān)聯(lián)的異常處理程序。以此類(lèi)推,直到找到一個(gè)異常處理程序?yàn)橹?。如果拋出異常的函?shù)沒(méi)有處理它的try-catch語(yǔ)句,異常將向上傳播到調(diào)用該函數(shù)的代碼。這樣的話,異常就會(huì)沿著javascript方法的詞法結(jié)構(gòu)和調(diào)用棧向上傳播。如果沒(méi)有找到任何異常處理程序,javascript將把異常當(dāng)成程序錯(cuò)誤來(lái)處理,并報(bào)告給用戶
try catch語(yǔ)句與捕獲錯(cuò)誤
ECMA-262第3版引入了try-catch語(yǔ)句,作為JavaScript中處理異常的一種標(biāo)準(zhǔn)方式,用于捕獲和處理錯(cuò)誤
其中,try從句定義了需要處理的異常所在的代碼塊。catch從句跟隨在try從句之后,當(dāng)try塊內(nèi)某處發(fā)生了異常時(shí),調(diào)用catch內(nèi)的代碼邏輯。catch從句后跟隨finally塊,后者中放置清理代碼,不管try塊中是否產(chǎn)生異常,finally塊內(nèi)的邏輯總是會(huì)執(zhí)行。盡管catch和finally都是可選的,但try從句需要至少二者之一與之組成完整的語(yǔ)句
try/catch/finally語(yǔ)句塊都需要使用花括號(hào)括起來(lái),這里的花括號(hào)是必需的,即使從句中只有一條語(yǔ)句也不能省略花括號(hào)
try{ //通常來(lái)講,這里的代碼會(huì)從頭到尾而不會(huì)產(chǎn)生任何問(wèn)題 //但有時(shí)會(huì)拋出一個(gè)異常,要么是由throw語(yǔ)句直接拋出,要么通過(guò)調(diào)用一個(gè)方法間接拋出 }catch(e){ //當(dāng)且僅當(dāng)try語(yǔ)句塊拋出了異常,才會(huì)執(zhí)行這里的代碼 //這里可以通過(guò)局部變量e來(lái)獲得對(duì)Error對(duì)象或者拋出的其他值的引用 //這里的代碼塊可以基于某種原因處理這個(gè)異常,也可以忽略這個(gè)異常,還可以通過(guò)throw語(yǔ)句重新拋出異常 }finally{ //不管try語(yǔ)句是否拋出了異常,finally里的邏輯總是會(huì)執(zhí)行,終止try語(yǔ)句塊的方式有: //1、正常終止,執(zhí)行完語(yǔ)句塊的最后一條語(yǔ)句 //2、通過(guò)break、continue或return語(yǔ)句終止 //3、拋出一個(gè)異常,異常被catch從句捕獲 //4、拋出一個(gè)異常,異常未被捕獲,繼續(xù)向上傳播 }
一般地,把所有可能會(huì)拋出錯(cuò)誤的代碼都放在try語(yǔ)句塊中,而把那些用于錯(cuò)誤處理的代碼放在catch塊中
如果try塊中的任何代碼發(fā)生了錯(cuò)誤,就會(huì)立即退出代碼執(zhí)行過(guò)程,然后接著執(zhí)行catch塊。此時(shí),catch塊會(huì)接收到一個(gè)錯(cuò)誤信息的對(duì)象,這個(gè)對(duì)象中包含的實(shí)際信息會(huì)因?yàn)g覽器而異,但共同的是有一個(gè)保存著錯(cuò)誤消息的message屬性
[注意]一定要給error對(duì)象起個(gè)名字,置空會(huì)報(bào)語(yǔ)法錯(cuò)誤
try{ q; }catch(error){ alert(error.message);//q is not defined } //Uncaught SyntaxError: Unexpected token ) try{ q; }catch(){ alert(error.message); }
catch接受一個(gè)參數(shù),表示try代碼塊拋出的值
function throwIt(exception) { try { throw exception; } catch (e) { console.log('Caught: '+ e); } } throwIt(3);// Caught: 3 throwIt('hello');// Caught: hello throwIt(new Error('An error happened'));// Caught: Error: An error happened
catch代碼塊捕獲錯(cuò)誤之后,程序不會(huì)中斷,會(huì)按照正常流程繼續(xù)執(zhí)行下去
try{ throw "出錯(cuò)了"; } catch (e) { console.log(111); } console.log(222); // 111 // 222
為了捕捉不同類(lèi)型的錯(cuò)誤,catch代碼塊之中可以加入判斷語(yǔ)句
try { foo.bar(); } catch (e) { if (e instanceof EvalError) { console.log(e.name + ": " + e.message); } else if (e instanceof RangeError) { console.log(e.name + ": " + e.message); } // ... }
雖然finally子句在try-catch語(yǔ)句中是可選的,但finally子句一經(jīng)使用,其代碼無(wú)論如何都會(huì)執(zhí)行。換句話說(shuō),try語(yǔ)句塊中的代碼全部正常執(zhí)行,finally子句會(huì)執(zhí)行;如果因?yàn)槌鲥e(cuò)而執(zhí)行了catch語(yǔ)句塊,finally子句照樣還會(huì)執(zhí)行。只要代碼中包含finally子句,則無(wú)論try或catch語(yǔ)句塊中包含什么代碼——甚至return語(yǔ)句,都不會(huì)阻止finally子句的執(zhí)行
//由于沒(méi)有catch語(yǔ)句塊,所以錯(cuò)誤沒(méi)有捕獲。執(zhí)行finally代碼塊以后,程序就中斷在錯(cuò)誤拋出的地方 function cleansUp() { try { throw new Error('出錯(cuò)了……'); console.log('此行不會(huì)執(zhí)行'); } finally { console.log('完成清理工作'); } } cleansUp(); // 完成清理工作 // Error: 出錯(cuò)了……
function testFinnally(){ try{ return 2; }catch(error){ return 1; }finally{ return 0; } } testFinnally();//0
[注意]return語(yǔ)句的count的值,是在finally代碼塊運(yùn)行之前,就獲取完成了
var count = 0; function countUp() { try { return count; } finally { count++; } } countUp();// 0 console.log(count);// 1
function f() { try { console.log(0); throw "bug"; } catch(e) { console.log(1); return true; // 這句原本會(huì)延遲到finally代碼塊結(jié)束再執(zhí)行 console.log(2); // 不會(huì)運(yùn)行 } finally { console.log(3); return false; // 這句會(huì)覆蓋掉前面那句return console.log(4); // 不會(huì)運(yùn)行 } console.log(5); // 不會(huì)運(yùn)行 } var result = f(); // 0 // 1 // 3 console.log(result);// false
【tips】塊級(jí)作用域
try-catch語(yǔ)句的一個(gè)常見(jiàn)用途是創(chuàng)建塊級(jí)作用域,其中聲明的變量?jī)H僅在catch內(nèi)部有效
ES6引入了let關(guān)鍵字,為其聲明的變量創(chuàng)建塊級(jí)作用域。但是,在目前ES3和ES5的情況下,常常使用try-catch語(yǔ)句來(lái)實(shí)現(xiàn)類(lèi)似的效果
由下面代碼可知,e僅存在于catch分句內(nèi)部,當(dāng)試圖從別處引用它時(shí)會(huì)拋出錯(cuò)誤
try{ throw new Error();//拋出錯(cuò)誤 }catch(e){ console.log(e);//Error(…) } console.log(e);//Uncaught ReferenceError: e is not defined
常見(jiàn)錯(cuò)誤錯(cuò)誤處理的核心是首先要知道代碼里會(huì)發(fā)生什么錯(cuò)誤。由于javaScript是松散類(lèi)型的,而且也不會(huì)驗(yàn)證函數(shù)的參數(shù),因此錯(cuò)誤只會(huì)在代碼期間出現(xiàn)。一般來(lái)說(shuō),需要關(guān)注三種錯(cuò)誤:類(lèi)型轉(zhuǎn)換錯(cuò)誤、數(shù)據(jù)類(lèi)型錯(cuò)誤、通信錯(cuò)誤
【類(lèi)型轉(zhuǎn)換錯(cuò)誤】
類(lèi)型轉(zhuǎn)換錯(cuò)誤發(fā)生在使用某個(gè)操作符,或者使用其他可能自動(dòng)轉(zhuǎn)換值的數(shù)據(jù)類(lèi)型的語(yǔ)言結(jié)構(gòu)時(shí)
容易發(fā)生類(lèi)型轉(zhuǎn)換錯(cuò)誤的地方是流控制語(yǔ)句。像if之類(lèi)的語(yǔ)句在確定下一步操作之前,會(huì)自動(dòng)把任何值轉(zhuǎn)換成布爾值。尤其是if語(yǔ)句,如果使用不當(dāng),最容易出錯(cuò)
未使用過(guò)的命名變量會(huì)自動(dòng)被賦予undefined值。而undefined值可以被轉(zhuǎn)換成布爾值false,因此下面這個(gè)函數(shù)中的if語(yǔ)句實(shí)際上只適用于提供了第三個(gè)參數(shù)的情況。問(wèn)題在于,并不是只有undefined才會(huì)被轉(zhuǎn)換成false,也不是只有字符串值才可以轉(zhuǎn)換為true。例如,假設(shè)第三個(gè)參數(shù)是數(shù)值0,那么if語(yǔ)句的測(cè)試就會(huì)失敗,而對(duì)數(shù)值1的測(cè)試則會(huì)通過(guò)
function concat(str1,str2,str3){ var result = str1 + str2; if(str3){ //絕對(duì)不要這樣 result += str3; } return result; }
在流控制語(yǔ)句中使用非布爾值,是極為常見(jiàn)的一個(gè)錯(cuò)誤來(lái)源。為避免此類(lèi)錯(cuò)誤,就要做到在條件比較時(shí)切實(shí)傳入布爾值。實(shí)際上,執(zhí)行某種形式的比較就可以達(dá)到這個(gè)目的
function concat(str1,str2,str3){ var result = str1 + str2; if(typeof str3 == 'string'){ //更合適 result += str3; } return result; }
【數(shù)據(jù)類(lèi)型錯(cuò)誤】
javascript是松散類(lèi)型的,在使用變量和函數(shù)參數(shù)之前,不會(huì)對(duì)它們進(jìn)行比較以確保它們的數(shù)據(jù)類(lèi)型正確。為了保證不會(huì)發(fā)生數(shù)據(jù)類(lèi)型錯(cuò)誤,只能編寫(xiě)適當(dāng)?shù)臄?shù)據(jù)類(lèi)型檢測(cè)代碼。在將預(yù)料之外的值傳遞繪函數(shù)的情況下,最容易發(fā)生數(shù)據(jù)類(lèi)型錯(cuò)誤
//不安全的函數(shù),任何非數(shù)組值都會(huì)導(dǎo)致錯(cuò)誤 function reverseSort(values){ if(values){ values.sort(); values.reverse(); } }
另一個(gè)常見(jiàn)的錯(cuò)誤就是將參數(shù)與null值進(jìn)行比較。與null進(jìn)行比較只能確保相應(yīng)的值不是null和undefined。要確保傳入的值有效,僅檢測(cè)null值是不夠的
//不安全的函數(shù),任何非數(shù)組值都會(huì)導(dǎo)致錯(cuò)誤 function reverseSort(values){ if(values != null){ values.sort(); values.reverse(); } }
如果傳入一個(gè)包含sort()方法的對(duì)象(而不是數(shù)組)會(huì)通過(guò)檢測(cè),但調(diào)用reverse()函數(shù)時(shí)可能會(huì)出錯(cuò)
//不安全的函數(shù),任何非數(shù)組值都會(huì)導(dǎo)致錯(cuò)誤 function reverseSort(values){ if(typeof values.sort == 'function'){ values.sort(); values.reverse(); } }
在確切知道應(yīng)該傳入什么類(lèi)型的情況下,最好是使用instanceof來(lái)檢測(cè)其數(shù)據(jù)類(lèi)型
//安全,非數(shù)組值被忽略 function reverseSort(values){ if(values instanceof Array){ values.sort(); values.reverse(); } }
【通信錯(cuò)誤】
隨著Ajax編程的興起,Web應(yīng)用程序在其生命周期內(nèi)動(dòng)態(tài)加載信息或功能,已經(jīng)成為一件司空見(jiàn)慣的事。不過(guò),javascript與服務(wù)器之間的任何一次通信,都有可能會(huì)產(chǎn)生錯(cuò)誤
最常見(jiàn)的問(wèn)題是在將數(shù)據(jù)發(fā)送給服務(wù)器之前,沒(méi)有使用encodeURIComponent()對(duì)數(shù)據(jù)進(jìn)行編碼
//錯(cuò)誤 http://www.yourdomain.com/?redir=http://www.sometherdomain.com?a=b&c=d //針對(duì)'redir='后面的所有字符串調(diào)用encodeURIComponent()就可以解決這個(gè)問(wèn)題 http://www.yourdomain.com/?redir=http:%3A%2F%2Fwww.sometherdomain.com%3Fa%3Db%26c%3Dd
以上這篇全面了解javascript中的錯(cuò)誤處理機(jī)制就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
js圖片延遲加載(Lazyload)三種實(shí)現(xiàn)方式
這篇文章主要介紹了js延遲加載(Lazyload)三種實(shí)現(xiàn)方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03基于JS代碼實(shí)現(xiàn)圖片在頁(yè)面中旋轉(zhuǎn)效果
這篇文章主要介紹了基于JS代碼實(shí)現(xiàn)圖片在頁(yè)面中旋轉(zhuǎn)效果 的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06微信小程序?qū)崿F(xiàn)列表頁(yè)的點(diǎn)贊和取消點(diǎn)贊功能
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)列表頁(yè)的點(diǎn)贊和取消點(diǎn)贊功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11jquery $(document).ready()和window.onload的區(qū)別淺析
這篇文章主要介紹了jquery $(document).ready()和 window.onload的區(qū)別淺析,本文總結(jié)了執(zhí)行時(shí)間、編寫(xiě)個(gè)數(shù)不同、簡(jiǎn)化寫(xiě)法等不同的地方,需要的朋友可以參考下2015-02-02js實(shí)現(xiàn)無(wú)需數(shù)據(jù)庫(kù)的縣級(jí)以上聯(lián)動(dòng)行政區(qū)域下拉控件
縣級(jí)以上聯(lián)動(dòng)行政區(qū)域下拉控件,想必大家對(duì)此也有所熟悉,本文為大家介紹下使用js實(shí)現(xiàn)無(wú)需數(shù)據(jù)庫(kù)的聯(lián)動(dòng)下拉控件,感興趣的朋友可以參考下,希望對(duì)大家有所幫助2013-08-08JavaScript+canvas實(shí)現(xiàn)五子棋游戲
這篇文章主要為大家詳細(xì)介紹了JavaScript+canvas實(shí)現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05