一直以來寫代碼的時候的常用習慣就是吧所有的js文件直接加載在文檔的head標簽里面,在寫js文件的時候有時候獲取一些文件對象的時候為空對象,這是由於文檔結構還沒有加載完,但是js文件已經加載完。也就是說雖然寫了js語句來獲取對象,但是由於dom結構還沒有加載完成,因此獲取到的是空對象,進一步測試發現在firebug的控制台下把賦值語句執行之后可以獲得對象,同理是因為在文檔已經得到顯示之后文檔結構已經處於加載完成的狀態,所以可以直接獲取到對應的文檔對象。
解決方法用兩種:defer和async。
- defer="defer":該屬性用來通知瀏覽器,這段腳本代碼將不會產生任何文檔內容。例如 JavaScript代碼中的document.write()方法將不會騎作用,瀏覽器遇到這樣的代碼將會忽略,並繼續執行后面的代碼。屬性只能是 defer,與屬性名相同。在HTML語法格式下,也允許不定義屬性值,僅僅使用屬性名。
- async="true/false":該屬性為html5中新增的屬性,它的作用是能夠異步地下載和執行腳本,不因為加載腳本而阻塞頁面的加載。一旦下載完畢就會立刻執行。
script中的defer屬性默認情況下是false的,因此在使用時需要顯式調用這一屬性。
defer既可用於載入js文件,也可用於行內腳本。
加上 defer 等於在頁面完全在入后再執行,相當於 window.onload ,但應用上比 window.onload 更靈活!實際上 defer 更接近於 DomContentLoad。
事實上腳本執行於onload事件之前,即文檔載入后即執行,不用等於包括圖片在內的資源下載完畢。
async和defer一樣,都不會阻塞其他資源下載,所以不會影響頁面的加載,但在async的情況下,js文檔一旦下載完畢就會立刻執行,所以很有可能不是按照原本的順序來執行,如果js有依賴性,就要注意了。
defer和async的比較
相同點:
- 加載文件時不阻塞頁面渲染;
- 對於inline的script無效;
- 使用這兩個屬性的腳本中不能調用document.write方法;
- 有腳本的onload的事件回調;
- 允許不定義屬性值,僅僅使用屬性名;
不同點:
- html的版本html4.0中定義了defer;html5.0中定義了async;這將造成由於瀏覽器版本的不同而對其支持的程度不同;
- 執行時刻:每一個async屬性的腳本都在它下載結束之后立刻執行,同時會在window的load事件之前執行。所以就有可能出現腳本執行順序被打亂 的情況;每一個defer屬性的腳本都是在頁面解析完畢之后,按照原本的順序執行,同時會在document的DOMContentLoaded之前執 行。
這兩個屬性會有三種可能的組合:
- 如果async為true,那么腳本在下載完成后異步執行。
- 如果async為false,defer為true,那么腳本會在頁面解析完畢之后執行。
- 如果async和defer都為false,那么腳本會在頁面解析中,停止頁面解析,立刻下載並且執行。
例子:
<script type="text/javascript" src="js/index.js" defer></script>直接放在head標簽中
html的body中代碼:
<div id="first_menu">
<ul>
<li class="individual_info">
<div class="menu_content">
<i class="fa fa-user"></i>
<p>個人信息</p>
</div>
</li>
<li class="prizes_amount">
<div class="menu_content">
<i class="fa fa-pencil-square-o"></i>
<p>獲獎統計</p>
</div>
</li>
<li class="attendence_management">
<div class="menu_content">
<i class="fa fa-calendar"></i>
<p>考勤管理</p>
</div>
</li>
<li class="expand_tables">
<div class="menu_content">
<i class="fa fa-file-excel-o"></i>
<p>拓展表項</p>
</div>
</li>
</ul>
</div>
js代碼:var li_list=$("#first_menu ul li");
沒有添加defer之前獲取的li_list為空對象,添加defer屬性之后可以正常獲取對象
將async屬性設置為true之后同樣也可以獲取到對象
參考資料:http://www.oseye.net/user/kevin/blog/53