1、$(document).ready
點評: 需要引用jquery ;兼容所有瀏覽器。
2、標簽的async=”async”屬性
async的定義和用法(是HTML5的屬性)
async 屬性規定一旦腳本可用,則會異步執行。
點評:HTML5中新增的屬性,Chrome、FF、IE9&IE9+均支持(IE6~8不支持)。此外,這種方法不能保證腳本按順序執行。 async 屬性僅適用於外部腳本(只有在使用 src 屬性時)。
3、defer屬性
<script type="text/javascript" defer="defer"> alert(document.getElementById("p1").firstChild.nodeValue); </script>
點評:兼容所有瀏覽器。此外,這種方法可以確保所有設置defer屬性的腳本按順序執行
async和defer看起來差不多呀?而且經常一起出現!來辨析一下:
(1)如果沒有async和defer屬性,那么瀏覽器會立即執行當前的JS腳本,阻塞后面的腳本;
(2)如果有async屬性,加載和渲染后續文檔的過程和當前JS的加載與執行並行進行(異步),它是亂序執行的,不管你聲明的順序如何,只要它加載完了就會執行;
(3)如果有defer屬性,加載后續文檔元素的過程和JS的加載是並行進行(異步)的,但是JS的執行在所有元素解析完成之后進行,而且它是按照加載順序執行腳本的
4、動態創建
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript"> (function(){ var s = document.createElement('script'); s.type = 'text/javascript'; s.src = "http://code.jquery.com/jquery-1.7.2.min.js"; var tmp = document.getElementsByTagName('script')[0]; tmp.parentNode.insertBefore(s, tmp); })(); </script> </head> <body> <img src="https://images0.cnblogs.com/i/121863/201405/222202573569862.jpg" /> </body> </html>
原生的javascript 實現異步的方式其實遠遠不至7種, 大可以分3類:
1、延遲類型:setTimeout(setInterval也是可以的)、requestAnimationFrame、setImmediate(IE10及以上)
2、監聽事件實現的類型:監聽new Image加載狀態、監聽script加載狀態、監聽iframe加載狀態、Message
3、帶有異步功能類型 Promise、ajax( XMLHttpRequest、ActiveXObject)、Worker;
考慮到 :iframe 效率過慢; ajax 在ie下一定要加載真實的文件才能觸發open及send;Worker 雖然具有異步特性,但它屬於多線程的范疇,需要將主要的算法寫在單獨的js文件中才能完整體現其優點,若單單為了異步化而使用的話太浪費了。 所有這3種方式就不列出。
一、實現異步的方式:
1、setTimeout:這個是最簡單的
setTimeout( function() { console.log(1); }); console.log(2);
2、setImmediate :IE10添加的新功能,專門用於解放ui線程。IE10以下及其他瀏覽器不支持
setImmediate(function(){ console.log(1); }); console.log(2);
3、requestAnimationFrame :HTML5/CSS3時代新產物,專門用於動畫。低級瀏覽器不支持
var asynByAniFrame = (function(){ var _window = window, frame = _window.requestAnimationFrame || _window.webkitRequestAnimationFrame || _window.mozRequestAnimationFrame || _window.oRequestAnimationFrame || _window.msRequestAnimationFrame; return function( callback ) { frame( callback ) }; })(); asynByAniFrame(function(){ console.log(1); }) console.log(2);
4、監聽new Image加載狀態:通過加載一個data:image數據格式的圖片,並監聽器加載狀態實現異步。
盡管部分瀏覽器不支持data:image圖片數據格式,但仍然可以觸發其onerror狀態實現異步,但IE8及以下對data:image數據格式的圖片,onerror為同步執行
function asynByImg( callback ) { var img = new Image(); img.onload = img.onerror = img.onreadystatechange = function() { img = img.onload = img.onerror = img.onreadystatechange = null; callback(); } img.src = "data:image/png,"; } asynByImg(function(){ console.log(1); }); console.log(2);
5、監聽script加載狀態
原理同new Image是一樣的,生成一個data:text/javascript的script,並監聽其加載狀態實現異步。
盡管部分瀏覽器不支持data:text/javascript格式數據的script,但仍然可以觸發其onerror、onreadystatechange事件實現異步。
var asynByScript = (function() { var _document = document, _body = _document.body, _src = "data:text/javascript,", //異步隊列
queue = []; return function( callback ) { var script = _document.createElement("script"); script.src = _src; //添加到隊列
queue[ queue.length ] = callback; script.onload = script.onerror = script.onreadystatechange = function () { script.onload = script.onerror = script.onreadystatechange = null; _body.removeChild( script ); script = null; //執行並刪除隊列中的第一個
queue.shift()(); }; _body.appendChild( script ); } })(); asynByScript( function() { console.log(1); } ); console.log(2);
6、Message:html5新技能,通過監聽window.onmessage事件實現,然后postMessage發送消息,觸發onmessage事件實現異步
var asynByMessage = (function() { //異步隊列
var queue = []; window.addEventListener('message', function (e) { //只響應asynByMessage的召喚
if ( e.data === 'asynByMessage' ) { e.stopPropagation(); if ( queue.length ) { //執行並刪除隊列中的第一個
queue.shift()(); } } }, true); return function( callback ) { //添加到隊列
queue[ queue.length ] = callback; window.postMessage('asynByMessage', '*'); }; })(); asynByMessage(function() { console.log(1); }); console.log(2);
7、Promise: ES6的新技能,具有異步性質
var asynByPromise = (function() { var promise = Promise.resolve({ then : function( callback ) { callback(); } }); return function( callback ) { promise.then(function(){ callback(); }) }; })(); asynByPromise(function() { console.log(1); }); console.log(2);
