年輕人你不講武德,耗子尾汁~~~
總結就是爲了形成自己的js知識網,提升自己,加油!
開始幹
51、談性能優化問題
- 代碼層面:避免使用css表達式,避免使用高級選擇器,通配選擇器。
- 緩存利用:緩存Ajax,使用CDN,使用外部js和css文件以便緩存,添加Expires頭,服務端配置Etag,減少DNS查找等
- 請求數量:合併樣式和腳本,使用css圖片精靈,初始首屏之外的圖片資源按需加載,靜態資源延遲加載。
- 請求帶寬:壓縮文件,開啓GZIP,代碼層面的優化
- 用hash-table來優化查找,少用全局變量
- 用innerHTML代替DOM操作,減少DOM操作次數,優化javascript性能
- 用setTimeout來避免頁面失去響應
- 緩存DOM節點查找的結果
- 避免使用CSS Expression
- 避免全局查詢
- 避免使用with(with會創建自己的作用域,會增加作用域鏈長度)
- 多個變量聲明合併
- 避免圖片和iFrame等的空Src。空Src會重新加載當前頁面,影響速度和效率
- 儘量避免寫在HTML標籤中寫Style屬性
51、解釋jsonp的原理,以及爲什麼不是真正的ajax
動態創建script標籤,回調函數;Ajax是頁面無刷新請求數據操作
52、javascript的本地對象,內置對象和宿主對象
- 本地對象爲array obj regexp等可以new實例化
- 內置對象爲gload Math 等不可以實例化的
- 宿主爲瀏覽器自帶的document,window 等
53、document load 和document ready的區別
Document.onload 是在結構和樣式加載完才執行js
Document.ready原生種沒有這個方法,jquery中有 $().ready(function)
54、==
和===的不同
前者會自動轉換類型 值判斷數值 不判斷類型
let a = 12;
let b = '12'
console.log(a==b) //true
後者先比較數值後比較數據類型都一樣時才一樣
let a = 12;
let b = '12'
console.log(a===b) //false
55、javascript的同源策略
一段腳本只能讀取來自於同一來源的窗口和文檔的屬性,這裏的同一來源指的是主機名、協議和端口號的組合
56、Ajax你以前用過麼?簡單介紹一下
AJAX = 異步 JavaScript 和 XML。 xmlhttprequest
AJAX 是一種用於創建快速動態網頁的技術。通過在後臺與服務器進行少量數據交換,AJAX 可以使網頁實現異步更新。這意味着可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。傳統的網頁(不使用AJAX)如果需要更新內容,必需重載整個網頁面。有很多使用 AJAX 的應用程序案例:新浪微博、Google 地圖、開心網等等。
57、 Ajax可以做異步請求麼?
可以。Ajax請求默認是異步的.如果想同步把async設置爲false就可以了默認是true。如果是jquery $.ajax({ url: some.php, async: false, success : function(){ } }); 如果是原生的js xmlHttp.open(“POST”,url,false)。
58、一網站如果有大量的人登陸訪問。那麼會產生很多的session,如果你是程序員你該怎麼辦。
session默認保存在內存中,內存資源寶貴,session數據量大導致內存利用率高,以下方案解決session內存存儲問題:
(1)可以設置session超時時間,達到超時時間session自動清空
<session-config>
<session-timeout>20</session-timeout>
</session-config>
(2)將session中的數據序列化到硬盤中;
不使用session,使用cookie(此方法存在安全性問題)
59、Ajax如何實現異步定時5秒刷新?
setInterval(function() {
$("#content").load(location.href+" #content>*","");
}, 5000);
60、如何實現瀏覽器內多個標籤頁之間的通信?
調用localstorge、cookies等本地存儲方式。
方法一:
localstorge在一個標籤頁裏被添加、修改或刪除時,都會觸發一個storage事件,通過在另一個標籤頁裏監聽storage事件,即可得到localstorge存儲的值,實現不同標籤頁之間的通信。
標籤頁1:
1.<input id="name">
2.<input type="button" id="btn" value="提交">
3.<script type="text/javascript">
4. $(function(){
5. $("#btn").click(function(){
6. var name=$("#name").val();
7. localStorage.setItem("name", name);
8. });
9. });
10.</script>
標籤頁2:
[html] view plain copy
1.<script type="text/javascript">
2. $(function(){
3. window.addEventListener("storage", function(event){
4. console.log(event.key + "=" + event.newValue);
5. });
6. });
7.</script>
方法二:
使用cookie+setInterval,將要傳遞的信息存儲在cookie中,每隔一定時間讀取cookie信息,即可隨時獲取要傳遞的信息。
標籤頁1:
1.<input id="name">
2.<input type="button" id="btn" value="提交">
3.<script type="text/javascript">
4. $(function(){
5. $("#btn").click(function(){
6. var name=$("#name").val();
7. document.cookie="name="+name;
8. });
9. });
10.</script>
標籤頁2:
[html] view plain copy
1.<script type="text/javascript">
2. $(function(){
3. function getCookie(key) {
4. return JSON.parse("{\"" + document.cookie.replace(/;\s+/gim,"\",\"").replace(/=/gim, "\":\"") + "\"}")[key];
5. }
6. setInterval(function(){
7. console.log("name=" + getCookie("name"));
8. }, 10000);
9. });
10.</script>
61、頁面可見性(Page Visibility)API 可以有哪些用途?
頁面可見性: 就是對於用戶來說,頁面是顯示還是隱藏, 所謂顯示的頁面,就是我們正在看的頁面;隱藏的頁面,就是我們沒有看的頁面。 因爲,我們一次可以打開好多標籤頁面來回切換着,始終只有一個頁面在我們眼前,其他頁面就是隱藏的,還有一種就是…,(把瀏覽器最小化,所有的頁面就都不可見了)。
API 很簡單,document.hidden
就返回一個布爾值,如果是true
, 表示頁面可見,false
則表示,頁面隱藏。 不同頁面之間來回切換,觸發visibilitychange事件。 還有一個document.visibilityState, 表示頁面所處的狀態,取值:visible, hidden 等四個。
document.addEventListener("visibilitychange", function(){
if(document.hidden){
document.title ="hidden";
}else {
document.title = "visibile";
}
})
我們打開這個頁面,然後再打開另一個頁面,來回點擊這兩個頁面,當我們看到這個頁面時,標題顯示visiable ,當我們看另一個頁面時,標題顯示hidden;
動畫,視頻,音頻都可以在頁面顯示時打開,在頁面隱藏時關閉。
62、JavaScript原型,原型鏈 ?
- js原型?
js每聲明一個function,都有prototype原型,prototype原型是函數的一個默認屬性,在函數的創建過程中由js編譯器自動添加。
也就是說:當生產一個function對象的時候,就有一個原型prototype。
舉個栗子:
是不是還看到了一個_proto_的屬性?!騷年,你的眼睛不錯~待會在解釋prototype和_proto_的基友關係!
prototype的屬性值是一個對象,是屬性的集合,是屬性的集合,是屬性的集合,
Js原型鏈是實現繼承的主要方法。其基本思想是:利用原型讓一個引用類型繼承另一個應用類型的屬性和方法。
簡單回顧一下構造函數、原型和實例的關係:每個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。
首先,我覺得有必要先解釋一下prototype 和_proto_之間的關係。
每一個基本對象都有自己的_proto_屬性,而每一個函數對象都有自己的prototype原型(函數對象也屬於基本對象,所以也有_proto_),每當去定義一個prototype的時候,就相當於把該實例的__proto__指向一個結構體,那麼這個被指向結構體就稱爲該實例的原型。 我們還是來看圖吧~比較清晰:
var foo = {
x: 10,
y: 20
};
解析:當你定義一個函數對象的時候,其內部就有這樣一個鏈表關係。聲明foo對象,自帶了_proto_的屬性,而這個屬性指向了prototype,從而實現對象的擴展(例如繼承等操作)。
63、Javascript創建對象的幾種方式?
javascript是一種基於prototype的面嚮對象語言 ,與java有非常大的區別,無法通過類來創建對象。那麼,既然是面象對象的,如何來創建對象呢?
一、通過”字面量“方式創建。
方法:將成員信息寫到{}中,並賦值給一個變量,此時這個變量就是一個對象。
例如:
var person = (name:'dongjc', work:function() {
console.log('write coding')});
如果{}中爲空,則將創建一個空對象:
var person = {
} //創建空對象
演示代碼:
<script>
var person = {
name: "dongjc",
age: 32,
Introduce: function () {
alert("My name is " + this.name + ".I'm " + this.age)
}
};
person.Introduce();
</script>
我們還可以給對象豐富成員信息。
對象.成員名稱 = 值;
對象[成員名稱] = 值;
也可以獲取對象的成員信息。
對象.成員名稱;
對象[成員名稱];
<script type="text/javascript">
var person = {
name: "dongjc",
age: 32,
Introduce: function () {
alert("My name is " + this.name + ".I'm " + this.age); }
};
person.worker = 'coding'; //豐富成員信息
</script>
二、通過”構造函數“方式創建。
方法:
var obj = new 函數名();
這與通過類創建對象有本質的區別。通過該方法創建對象時,會自動執行該函數。這點類似於php通過創建對像時,會自動調用構造函數,因此該方法稱爲通過"構造函數“方式創建對象。
<script type="text/javascript"> function Person() {
this.name = "dongjc"; //通過this關鍵字設置默認成員
var worker = 'coding'; //沒有this關鍵字,對象創建後,該變量爲非成員
this.age = 32;
this.Introduce = function () {
alert("My name is " + this.name + ".I'm " + this.age); }; alert("My name is " + this.name + ".I'm " + this.age);
}; var person = new Person();
person.Introduce();
</script>
此代碼一共會兩次跳出對話框,原因在於創建對象是自動執行了該函數。
注意:this關鍵字的使用。這裏的this與php中話法意思類似,指調用該函數的對象,這裏指的是person。
三、通過object方式創建。
方法:先通過object構造器new一個對象,再往裏豐富成員信息。
var obj = new Object();
實例代碼:
<script type="text/javascript">
var person = new Object();
person.name = "dongjc";
person.age = 32;
person.Introduce = function () {
alert("My name is " + this.name + ".I'm " + this.age);
};
person.Introduce();
</script>
64、Javascript作用鏈域?
JavaScript中所有的量都是存在於某一個作用域中的
除了全局作用域, 每一個作用域都是存在於某個作用域中的
在試圖訪問一個變量時JS引擎會從當前作用域開始向上查找直到Global全局作用域停止
例如
var A;//全局作用域
function B()
{
var C;//C位於B函數的作用域
function D()
{
var E;//E位於D函數的作用域
alert(A)
}
}
當alert(A)時, JS引擎沿着D的作用域, B的作用域, 全局作用域的順序進行查找.
這三個作用域組成的有序集合就成爲作用域鏈
至於爲什麼叫鏈, 你可以理解和鏈表有相似之處, 深層的作用域會能夠訪問到上層作用域, 就如同鏈表中兩個連續節點能夠單向訪問一樣
65、什麼是window對象? 什麼是document對象?
簡單來說,document是window的一個對象屬性。
Window 對象表示瀏覽器中打開的窗口。
如果文檔包含框架(frame 或 iframe 標籤),瀏覽器會爲 HTML 文檔創建一個 window 對象,併爲每個框架創建一個額外的 window 對象。
所有的全局函數和對象都屬於Window 對象的屬性和方法。
document 對 Document 對象的只讀引用。
[window對象]
它是一個頂層對象,而不是另一個對象的屬性,即瀏覽器的窗口。
屬性
defaultStatus 缺省的狀態條消息
document 當前顯示的文檔(該屬性本身也是一個對象)
frame 窗口裏的一個框架((FRAME>)(該屬性本身也是一個對象)
frames array 列舉窗口的框架對象的數組,按照這些對象在文檔中出現的順序列出(該屬性本身也是一個對象)
history 窗口的歷史列表(該屬性本身也是一個對象)
length 窗口內的框架數
location 窗口所顯示文檔的完整(絕對)URL(該屬性本身也是一個對象)不要把它與如document.location混淆,後者是當前顯示文檔的URL。用戶可以改變window.location(用另一個文檔取代當前文檔),但卻不能改變document.location (因爲這是當前顯示文檔的位置)
name 窗口打開時,賦予該窗口的名字
opener 代表使用window.open打開當前窗口的腳本所在的窗口(這是Netscape Navigator 3.0beta 3所引入的一個新屬性)
parent 包含當前框架的窗口的同義詞。frame和window對象的一個屬性
self 當前窗口或框架的同義詞
status 狀態條中的消息
top 包含當前框架的最頂層瀏覽器窗口的同義詞
window 當前窗口或框架的同義詞,與self相同
方法
alert() 打開一個Alert消息框
clearTimeout() 用來終止setTimeout方法的工作
close() 關閉窗口
confirm() 打開一個Confirm消息框,用戶可以選擇OK或Cancel,如果用戶單擊OK,該方法返回true,單擊Cancel返回false
blur() 把焦點從指定窗口移開(這是Netscape Navigator 3.0 beta 3引入的新方法)
focus() 把指定的窗口帶到前臺(另一個新方法)
open() 打開一個新窗口
prompt() 打開一個Prompt對話框,用戶可向該框鍵入文本,並把鍵入的文本返回到腳本
setTimeout() 等待一段指定的毫秒數時間,然後運行指令事件處理程序事件處理程序
Onload() 頁面載入時觸發
Onunload() 頁面關閉時觸發
[document 對象]
該對象是window和frames對象的一個屬性,是顯示於窗口或框架內的一個文檔。
屬性
alinkColor 活動鏈接的顏色(ALINK)
anchor 一個HTMI錨點,使用<A NAME=>標記創建(該屬性本身也是一個對象)
anchors array 列出文檔錨點對象的數組(<A NAME=>)(該屬性本身也是一個對象)
bgColor 文檔的背景顏色(BGCOLOR)
cookie 存儲於cookie.txt文件內的一段信息,它是該文檔對象的一個屬性
fgColor 文檔的文本顏色(標記裏的TEXT特性)
form 文檔中的一個窗體()(該屬性本身也是一個對象)
forms anay 按照其出現在文檔中的順序列出窗體對象的一個數組(該屬性本身也是一個對象)
lastModified 文檔最後的修改日期
linkColor 文檔的鏈接的顏色,即標記中的LINK特性(鏈接到用戶沒有觀察到的文檔)
link 文檔中的一個<A HREF=>標記(該屬性本身也是一個對象)
links array 文檔中link對象的一個數組,按照它們出現在文檔中的順序排列(該屬性本身也是一個對象)
location 當前顯示文檔的URL。用戶不能改變document.location(因爲這是當前顯示文檔的位置)。但是,可以改變 window.location (用其它文檔取代當前文檔)window.location本身也是一個對象,而document.location不是對象
referrer 包含鏈接的文檔的URL,用戶單擊該鏈接可到達當前文檔
title 文檔的標題((TITLE>)
vlinkColor 指向用戶已觀察過的文檔的鏈接文本顏色,即標記的VLINK特性
方法
clear 清除指定文檔的內容
close 關閉文檔流
open 打開文檔流
write 把文本寫入文檔
writeln 把文本寫入文檔,並以換行符結尾
區別:
1、window 指窗體。document指頁面。document是window的一個子對象。
2、用戶不能改變 document.location(因爲這是當前顯示文檔的位置)。但是,可以改變window.location (用其它文檔取代當前文檔)window.location本身也是一個對象,而document.location不是對象
66、寫一個通用的事件偵聽器函數
1. markyun.Event = {
2. // 頁面加載完成後
3. readyEvent : function(fn) {
4. if (fn==null) {
5. fn=document;
6. }
7. var oldonload = window.onload;
8. if (typeof window.onload != 'function') {
9. window.onload = fn;
10. } else {
11. window.onload = function() {
12. oldonload();
13. fn();
14. };
15. }
16. },
17. // 視能力分別使用dom0||dom2||IE方式 來綁定事件
18. // 參數: 操作的元素,事件名稱 ,事件處理程序
19. addEvent : function(element, type, handler) {
20. if (element.addEventListener) {
21. //事件類型、需要執行的函數、是否捕捉
22. element.addEventListener(type, handler, false);
23. } else if (element.attachEvent) {
24. element.attachEvent('on' + type, function() {
25. handler.call(element);
26. });
27. } else {
28. element['on' + type] = handler;
29. }
30. },
31. // 移除事件
32. removeEvent : function(element, type, handler) {
33. if (element.removeEnentListener) {
34. element.removeEnentListener(type, handler, false);
35. } else if (element.datachEvent) {
36. element.detachEvent('on' + type, handler);
37. } else {
38. element['on' + type] = null;
39. }
40. },
41. // 阻止事件 (主要是事件冒泡,因爲IE不支持事件捕獲)
42. stopPropagation : function(ev) {
43. if (ev.stopPropagation) {
44. ev.stopPropagation();
45. } else {
46. ev.cancelBubble = true;
47. }
48. },
49. // 取消事件的默認行爲
50. preventDefault : function(event) {
51. if (event.preventDefault) {
52. event.preventDefault();
53. } else {
54. event.returnValue = false;
55. }
56. },
57. // 獲取事件目標
58. getTarget : function(event) {
59. return event.target || event.srcElement;
60. },
61. // 獲取event對象的引用,取到事件的所有信息,確保隨時能使用event;
62. getEvent : function(e) {
63. var ev = e || window.event;
64. if (!ev) {
65. var c = this.getEvent.caller;
66. while (c) {
67. ev = c.arguments[0];
68. if (ev && Event == ev.constructor) {
69. break;
70. }
71. c = c.caller;
72. }
73. }
74. return ev;
75. }
76. };
67、[“1”, “2”, “3”].map(parseInt) 答案是多少?
[1,NaN,NaN]
68、關於事件,IE與火狐的事件機制有什麼區別? 如何阻止冒泡?
我們在網頁中的某個操作(有的操作對應多個事件)。例如:當我們點擊一個按鈕就會產生一個事件。是可以被 JavaScript 偵測到的行爲。
事件處理機制:IE是事件冒泡、火狐是 事件捕獲;
ie:event.cancelBubble = true 或者 return false
火狐: event.stopPropagation() 或者 return false
69、什麼是閉包(closure),爲什麼要用它?
閉包是指有權訪問另一個函數作用域中變量的函數,創建閉包的最常見的方式就是在一個函數內創建另一個函數,通過另一個函數訪問這個函數的局部變量,利用閉包可以突破作用鏈域,將函數內部的變量和方法傳遞到外部。
閉包的特性:
(1)函數內再嵌套函數
(2)內部函數可以引用外層的參數和變量
(3)參數和變量不會被垃圾回收機制回收
HTML:
<!-- li節點的onclick事件都能正確的彈出當前被點擊的li索引 -->
<ul id="testUL">
<li> index = 0</li>
<li> index = 1</li>
<li> index = 2</li>
<li> index = 3</li>
</ul>
JS:
<script type="text/javascript">
var nodes = document.getElementsByTagName("li");
for(i = 0;i<nodes.length;i+= 1){
nodes[i].onclick = (function(i){
return function() {
console.log(i);
} //不用閉包的話,值每次都是4 })(i);
}
</script>
然後我們看看下面的一段代碼,這是對閉包作用的非常直白的描述:
function say667() {
// Local variable that ends up within closure
var num = 666;
var sayAlert = function() {
alert(num);
}
num++;
return sayAlert;
}
var sayAlert = say667();
sayAlert()//執行結果應該彈出的667
執行say667()後,say667()閉包內部變量會存在,而閉包內部函數的內部變量不會存在
使得Javascript的垃圾回收機制GC不會收回say667()所佔用的資源
因爲say667()的內部函數的執行需要依賴say667()中的變量
70、javascript 代碼中的"use strict";是什麼意思 ? 使用它區別是什麼?
除了正常運行模式,ECMAscript 5添加了第二種運行模式:“嚴格模式”(strict mode)。
顧名思義,這種模式使得Javascript在更嚴格的條件下運行。
爲什麼用嚴格模式
- 消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行爲;
- 消除代碼運行的一些不安全之處,保證代碼運行的安全;
- 提高編譯器效率,增加運行速度;
- 爲未來新版本的Javascript做好鋪墊。
"嚴格模式"體現了Javascript更合理、更安全、更嚴謹的發展方向,包括IE 10在內的主流瀏覽器,都已經支持它,許多大項目已經開始全面擁抱它。
另一方面,同樣的代碼,在"嚴格模式"中,可能會有不一樣的運行結果;一些在"正常模式"下可以運行的語句,在"嚴格模式"下將不能運行。掌握這些內容,有助於更細緻深入地理解Javascript,讓你變成一個更好的程序員。
進入標誌
"use strict";
如何調用
(1)針對單個腳本
<script>
"use strict";
console.log("這是嚴格模式。");
</script>
(2)針對單個函數
function strict(){
"use strict";
return "這是嚴格模式。";
}
function notStrict() {
return "這是正常模式。";
}
語法與行爲改變
嚴格模式對Javascript的語法和行爲,都做了一些改變。
5.1 全局變量顯式聲明
在正常模式中,如果一個變量沒有聲明就賦值,默認是全局變量。嚴格模式禁止這種用法,全局變量必須顯式聲明。
"use strict";
v = 1; // 報錯,v未聲明
for(i = 0; i < 2; i++) {
// 報錯,i未聲明
}
因此,嚴格模式下,變量都必須先用var命令聲明,然後再使用。 禁止this關鍵字指向全局對象
function f(){
return !this;
}
// 返回false,因爲"this"指向全局對象,"!this"就是false
function f(){
"use strict";
return !this;
}
// 返回true,因爲嚴格模式下,this的值爲undefined,所以"!this"爲true。
//因此,使用構造函數時,如果忘了加new,this不再指向全局對象,而是報錯。
function f(){
"use strict";
this.a = 1;
};
f();// 報錯,this未定義
禁止刪除變量
嚴格模式下無法刪除變量。只有configurable設置爲true的對象屬性,才能被刪除。
"use strict";
var x;
delete x; // 語法錯誤
var o = Object.create(null, {
'x': {
value: 1,
configurable: true
}});
delete o.x; // 刪除成功
對象不能有重名的屬性
正常模式下,如果對象有多個重名屬性,最後賦值的那個屬性會覆蓋前面的值。嚴格模式下,這屬於語法錯誤。
"use strict";
var o = {
p: 1,
p: 2
}; // 語法錯誤
函數不能有重名的參數
正常模式下,如果函數有多個重名的參數,可以用arguments[i]讀取。嚴格模式下,這屬於語法錯誤。
"use strict";
function f(a, a, b) {
// 語法錯誤
return ;
}
71、如何判斷一個對象是否屬於某個類?
javascript中檢測對象的類型的運算符有:typeof、constructor、instanceof。
typeof:typeof是一個一元運算符,返回結果是一個說明運算數類型的字符串。如:“number”,“string”,“boolean”,“object”,“function”,“undefined”(可用於判斷變量是否存在)。 但 typeof 的能力有限,其對於Date、RegExp、Array類型返回的都是"object"。所以它只在區別對象和原始類型的時候纔有用。要區一種對象類型和另一種對象類型,必須使用其他的方法。
instanceof 運算符:instanceof 運算符要求其左邊的運算數是一個對象,右邊的運算數是對象類的名字或構造函數。如果 object 是 class 或構造函數的實例,則 instanceof 運算符返回 true。如果 object 不是指定類或函數的實例,或者 object 爲 null,則返回 false。instanceof方法可以判斷變量是否是數組類型,但是隻限同一全局環境之內,在一個頁面有多個iframe的情況下,instanceof失效。
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);
console.log(auto instanceof Car);
// expected output: true
console.log(auto instanceof Object);
// expected output: true
constructor 屬性: JavaScript中,每個對象都有一個constructor屬性,它引用了初始化該對象的構造函數,常用於判斷未知對象的類型。如給定一個求知的值 通過typeof運算符來判斷它是原始的值還是對象。如果是對象,就可以使用constructor屬性來判斷其類型。
<script type="text/javascript">
var test=new Array();
if (test.constructor==Array)
{
document.write("This is an Array");
}
if (test.constructor==Boolean)
{
document.write("This is a Boolean");
}
if (test.constructor==Date)
{
document.write("This is a Date");
}
if (test.constructor==String)
{
document.write("This is a String");
}
/輸出
This is an Array
</script>
Object.prototype.toString.call():該方法是目前爲止發現的判斷一個對象類型的最好的辦法。
72、Javascript中,有一個函數,執行時對象查找時,永遠不會去查找原型,這個函數是?
hasOwnProperty
74、js延遲加載的方式有哪些?
js的延遲加載有助與提高頁面的加載速度,以下是延遲加載的幾種方法:
(1)使用setTimeout延遲方法的加載時間
延遲加載js代碼,給網頁加載留出更多時間
<script type="text/javascript" >
function A(){
$.post("/lord/login",{
name:username,pwd:password},function(){
alert("Hello");
});
}
$(function (){
setTimeout('A()', 1000); //延遲1秒
})</script>
(2)讓js最後加載
例如引入外部js腳本文件時,如果放入html的head中,則頁面加載前該js腳本就會被加載入頁面,而放入body中,則會按照頁面從上倒下的加載順序來運行javascript的代碼~~~ 所以我們可以把js外部引入的文件放到頁面底部,來讓js最後引入,從而加快頁面加載速度
(3)上述方法2也會偶爾讓你收到Google頁面速度測試工具的“延遲加載javascript”警告。所以這裏的解決方案將是來自Google幫助頁面的推薦方案。
//這些代碼應被放置在</body>
標籤前(接近HTML文件底部)
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
這段代碼意思是等到整個文檔加載完後,再加載外部文件“defer.js”。
使用此段代碼的步驟:
1).複製上面代碼
2).粘貼代碼到HTML的標籤前 (靠近HTML文件底部)
3).修改“defer.js”爲你的外部JS文件名
4).確保你文件路徑是正確的。例如:如果你僅輸入“defer.js”,那麼“defer.js”文件一定與HTML文件在同一文件夾下。
注意:這段代碼直到文檔加載完纔會加載指定的外部js文件。因此,不應該把那些頁面正常加載需要依賴的javascript代碼放在這裏。而應該將JavaScript代碼分成兩組。一組是因頁面需要而立即加載的javascript代碼,另外一組是在頁面加載後進行操作的javascript代碼(例如添加click事件或其他東西)。這些需等到頁面加載後再執行的JavaScript代碼,應放在一個外部文件,然後再引進來。
75、同步和異步的區別?
同步:
同步的思想是:所有的操作都做完,才返回給用戶。這樣用戶在線等待的時間太長,給用戶一種卡死了的感覺(就是系統遷移中,點擊了遷移,界面就不動了,但是程序還在執行,卡死了的感覺)。這種情況下,用戶不能關閉界面,如果關閉了,即遷移程序就中斷了。
異步:
將用戶請求放入消息隊列,並反饋給用戶,系統遷移程序已經啓動,你可以關閉瀏覽器了。然後程序再慢慢地去寫入數據庫去。這就是異步。但是用戶沒有卡死的感覺,會告訴你,你的請求系統已經響應了。你可以關閉界面了。
同步,是所有的操作都做完,才返回給用戶結果。即寫完數據庫之後,在相應用戶,用戶體驗不好。
異步,不用等所有操作等做完,就相應用戶請求。即先相應用戶請求,然後慢慢去寫數據庫,用戶體驗較好。
異步操作例子:
爲了避免短時間大量的數據庫操作,就使用緩存機制,也就是消息隊列。先將數據放入消息隊列,然後再慢慢寫入數據庫。
引入消息隊列機制,雖然可以保證用戶請求的快速響應,但是並沒有使得我數據遷移的時間變短(即80萬條數據寫入mysql需要1個小時,用了redis之後,還是需要1個小時,只是保證用戶的請求的快速響應。用戶輸入完http url請求之後,就可以把瀏覽器關閉了,幹別的去了。如果不用redis,瀏覽器不能關閉)。
同步就沒有任何價值了嗎?
銀行的轉賬功能。 哈哈哈哈哈 不轉完你放得下心嗎?