avaScript(簡稱JS)是一種廣泛用于Web開發的腳本語言,用于為網頁添加交互性和動態內容。它是一種高級、解釋性、基于對象和事件驅動的編程語言,由Netscape公司首先引入并在1995年推出。JavaScript通常嵌入在HTML文檔中,并通過Web瀏覽器在客戶端執行。
JavaScript的語法基于C語言,但也借鑒了Java和其他編程語言的特點。它支持動態類型,允許在運行時更改變量的類型,不需要提前聲明變量的類型。JavaScript也是一種弱類型語言,它會自動進行類型轉換,使得在一些情況下比較靈活,但也需要小心處理類型相關的問題。
JavaScript可以用于處理各種任務,包括但不限于網頁動態交互、表單驗證、動畫效果、數據處理、服務器端開發(如Node.js)、移動應用開發(如React Native)等。JavaScript具有豐富的標準庫,提供了很多內置對象和函數,同時也支持通過第三方庫(如jQuery、React、Vue等)擴展其功能。
JavaScript具有事件驅動的編程模型,可以對用戶的操作或其他事件做出響應。通過事件處理器,可以捕捉和處理用戶的鼠標點擊、鍵盤輸入、頁面加載完成等事件,從而實現豐富的交互體驗。
導讀:
JavaScript腳本語言(JS)的特點:
JavaScript是一種網頁腳本語言,被廣泛用于Web應用開發。可以使用JS添加、刪除、修改網頁上的所有元素及屬性;在HTML網頁中動態寫入文本、數字和插入圖表;響應網頁中的事件,并做出相應處理。了解JS編程后,可以輕松調用各類網絡統計學庫函數和在網頁上統計數據處理或分析。
一、JavaScript嵌入HTML文檔
1、JavaScript代碼嵌入HTML文檔
【#Code 101】:JavaScript代碼嵌入HTML文檔案例
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>銀河網絡統計學教程</title>
<style>
網頁內部樣式CSS代碼
</style>
<script language="JavaScript">
//*JavaScript腳本代碼*
</script>
</head>
<body>
文檔體HTML代碼
</body>
</html>
注:JavaScript腳本代碼在<script language="JavaScript">...</script>標簽之間
2、JavaScript代碼運行方式
(1) 網頁打開時自動調用JS代碼
【#Code 102】:網頁打開時自動調用JS代碼案例
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>銀河網絡統計學教程</title>
<style>
網頁內部樣式CSS代碼
</style>
<script language="JavaScript">
//*JavaScript腳本代碼*
function init() {
alert("加載網頁時提示我!");
}
</script>
</head>
<body onload="init()">
文檔體HTML代碼
</body>
</html>
注:可復制代碼到WINDOWS記事本,保存為HTML文檔。例如,“jsTest1.html”。鼠標雙擊該文件觀察效果
代碼【#Code 102】中,瀏覽器解析完HTML文檔體代碼后,觸發body標簽的onload網頁加載事件,從而運行JS函數init()。
(2) 用頁面按鈕或超鏈接觸發JS代碼
【#Code No.103】:用頁面按鈕或超鏈接觸發JS代碼案例
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>銀河網絡統計學教程</title>
<style>
網頁內部樣式CSS代碼
</style>
<script language="JavaScript">
//*JavaScript腳本代碼*
function init() {
alert("加載網頁時提示我!");
}
</script>
</head>
<body>
<button onclick="init()">運行JS函數init()</button>
<p><i>用鼠標左鍵點擊命令按鈕JS函數。</i></p><br/>
<a href="#" onclick="init()">運行JS函數init()</a>
<p><i>
由于href="#"沒有指定連接文件,用鼠標左鍵點擊超鏈接時onclick事件運行運行JS函數init()。
</i></p><br/>
</body>
</html>
注:JavaScript腳本代碼中的標點符號都必須為半角英文字符。JavaScript腳本可以插入注釋語句,注釋語句增加代碼可讀性,不被瀏覽器解析執行。符號"/.../"為單行注釋,符號"/*...*/"為多行行注釋
例如:
<script language="JavaScript">
//這是單行注釋
/*
這是多行注釋;
銀河網絡統計學教程。
*/
}
</script>
二、JavaScript語法
1、第一個實例
打開網頁時,瀏覽器中顯示"Hello World!
【#Code 104】:第一個網頁“Hello World!”案例
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>銀河網絡統計學教程</title>
<style></style>
<script language="JavaScript">
function init() {
document.write("Hello World!");
}
</script>
</head>
<body onload="init()">
</body>
</html>
2、JavaScript的三種對話框
(1)提醒對話框,不能對腳本產生任何改變,腳本樣例:
alert("提醒對話框");
在網頁中的運用參見#Code 102。
(2)確認對話框,返回true或者false,可以用于if...else...判斷用戶的選擇,腳本樣例:
confirm("你確信要學習網絡統計學嗎?")
confirm函數返回true或者false,網頁設計中運用實例,
【#Code 105】:JavaScript確認對話框案例
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>銀河網絡統計學教程 </title>
<style> </style>
<script language="JavaScript">
function init() {
document.write("Hello World!");
firm();
}
function firm() {
//利用對話框返回的值(true或者false)
if(confirm("你確信要學習網絡統計學嗎?")) {
alert("我確信要學習網絡統計學!");
} else {
alert("我學習網絡統計學有困難!");
}
}
</script>
</head>
<body onload="init()">
</body>
</html>
(3)輸入對話框,可以返回用戶填入的字符串或數值,腳本樣例:
var name=prompt("請輸入您的名字",""); //將輸入的內容賦給變量name
注:腳本中符號“//”為注釋符,可在“//”符號后面加入腳本解釋
prompt函數返回用戶填入的字符串或數值,網頁設計中運用實例,
【#Code 106】:JavaScript輸入對話框案例
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>銀河網絡統計學教程</title>
<style>
<script language="JavaScript">
function init() {
document.write("Hello World!");
prom();
}
function prom() {
var name=prompt("請輸入您的名字","張三"); //將輸入的內容賦給變量name
if(name) { //如果返回的有內容
alert("歡迎您:"+ name)
}
}
</script>
</head>
<body onload="init()">
</body>
</html>
注:prompt有兩個參數,前面是提示的信息,后面是當對話框出來后,在對話框里的默認值
3、定義JavaScript變量
JavaScript是弱類型語言,聲明變量時用var關鍵字(注意var要全部小寫)就可以了。而很多編程語言聲明變量時,需要指明變量的類型,如:int, double, string, boolean, date, array, object等;而且變量類型一旦指定,就不能改變了。但在JavaScript中不同,只需用var,且數據類型可以改變。但要請注意變量的命名規:
通常使用var(或let)關鍵字定義變量,如:
var total=346; //定義整數變量(int)
var value=45.7865 //定義浮點型變量(double)
var notNull=true; //定義邏輯型變量(boolean)
var name="張三", gender="男"; //用逗號分隔,同行定義兩個字符型變量(string)
var i=j=0; //同時定義兩個變量(int)
var hobby=["聽音樂","看電影"]; //定義數組變量(array)
var d=new Date(); //定義日期時間變量(date)
注:代碼中關鍵字var可以替換為let,但let關鍵字在同一作用域不能重復定義
【#Code 107】:JavaScript變量使用案例
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>銀河網絡統計學教程</title>
<style></style>
<script language="JavaScript">
var myName="銀河統計學"; //myName是全局變量
function init() {
var total=346;
var value=45.7865;
var notNull=true;
var name="張三", gender="男";
var i=j=0;
var hobby=["聽音樂","看電影"];
hobby[2]="打籃球"; //數組賦值
stdId=2016; //全局變量
var d=new Date(); //定義日期時間變量(date)
document.write("變量i="+i+"<br/>");
document.write("變量j="+j+"<br/>");
document.write("變量name="+name+"<br/>");
document.write("變量gender="+gender+"<br/>");
document.write("變量notNull="+notNull+"<br/>");
document.write("變量hobby="+hobby+"<br/>");
document.write("變量hobby[0]="+hobby[0]+"<br/>");
document.write("變量hobby[1]="+hobby[1]+"<br/>");
document.write("變量hobby[2]="+hobby[2]+"<br/>");
document.write("變量hobby[3]="+hobby[3]+"<br/>");
document.write("變量d="+d+"<br/>");
document.write("變量d.getFullYear()="+d.getFullYear()+"<br/>"); //參見JS日期對象
var ostr="<p/><i>下面調用函數test(),輸出該函數體內的全局和局部變量。";
ostr+="<br/>全局可以輸出,局部變量局部變量total無法輸出。</i><p/>";
document.write( ostr);
test();
}
function test() {
document.write("全局變量myName="+myName+"<br/>");
document.write("全局變量stdId="+stdId+"<br/>");
document.write("局部變量total="+total+"<br/>");
}
</script>
</head>
<body onload="init()">
</body>
</html>
注:代碼中"+="為連加運算符,將一行過長代碼分段代碼連接起來;"變量name="+name+"<br/>"中符號"+"連接字符串和變量
4、JavaScript運算符和操作符
JavaScript操作符比較復雜,下面介紹JS運算符和常用操作符。
(1)算數操作符
除了加號(+)之外,如果操作數不是Number類型,會自動先調用Number()將其轉換為Number類型再進行計算;除號(/)和取模(%)并不會區分整數和浮點數,都會自動轉化為浮點數。
(2)字符串操作符
字符串連接符號(+)相當于concat()函數,會將操作數據轉化為字符串再連接。在字符串和數值型進行+號運算時,會將數值型轉為字符串。
(3)布爾操作符
布爾邏輯操作符!(非、not)、&&(與、and)、||(或、or)常和if等條件函數一起判斷一個變量或屬性是否有定義。
【#Code 108】:JavaScript運算符和操作符案例
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>銀河網絡統計學教程</title>
<style></style>
<script language="JavaScript">
document.write("<p><b>//算術操作符</b></p>");
var x=11;
var y=5;
with (document) { //注意with關鍵字用法,其用于簡化代碼
write("x=11, y=5");
write("<br>x + y 是 ", x + y);
write("<br>x - y 是 ", x - y);
write("<br>x * y 是 ", x * y);
write("<br>x / y 是 ", x / y);
write("<br>x % y 是 ", x % y);
write("<br>++ x 是 ", ++ x);
write("<br>-- y 是 ", -- y);
write("<br>x 是 ", x);
write("<br>y 是 ", y);
write("<br>x-- 是 ", x--);
write("<br>y-- 是 ", y--);
}
document.write("<p><b>//++運算練習</b></p>");
var x=y=3;
with (document) {
write("y++=",(y++),"<br>");
write("++y=",(++y),"<br>");
write("x=3, y=5 <br>");
write("若x=y++ 運算之后:");
x=y++;//y→x,y+1→y
write("x 是 ", x, "; y 是 ", y, "<br>");
write("再作x=++y 運算:");
x=++y;//y+1→x,y+1→y
write("x 是 ", x, "; y 是 ", y);
}
document.write("<p><b>//++運算練習</b></p>");
var t=true;
var f=false;
with(document) {
write("true && true 的結果是 ", t && t);
write("<br>true && false 的結果是 ", t && f);
write("<br>false && true 的結果是 ", f && t);
write("<br>false && false 的結果是 ", f && f);
write("<br>true && (1==1) 的結果是 ", t && (1==1));
write("<br>false && 'A' 的結果是 ", f && 'A');
write("<br>'A' && false 的結果是 ", 'A' && f);
write("<br>true && 'A' 的結果是 ", t && 'A');
write("<br>'A' && true 的結果是 ", 'A' && t);
write("<br>'A' && 'B' 的結果是 ", 'A' && 'B');
write("<br>1 && 1 的結果是 ", 1 && 1);
write("<br>1 && 0 的結果是 ", 1 && 0);
write("<br>true && 0 的結果是 ", true && 0);
write("<br>true && 1 的結果是 ", true && 1);
write("<br>true && '0' 的結果是 ", true && '0');
}
document.write('<p><b>//邏輯運算符"||"</b></p>');
var t=true;
var f=false;
with(document) {
write("true || true 的結果是 ", t || t);
write("<br>true || false 的結果是 ", t || f);
write("<br>false || true 的結果是 ", f || t);
write("<br>false || false 的結果是 ", f || f);
write("<br>true || (1==1) 的結果是 ", t || (1==1));
write("<br>false || 'A' 的結果是 ", f || 'A');
write("<br>'A' || false 的結果是 ", 'A' || f);
write("<br>true || 'A' 的結果是 ", t || 'A');
write("<br>'A' || true 的結果是 ", 'A' || t);
write("<br>'A' || 'B' 的結果是 ", 'A' || 'B');
write("<br>1 || 1 的結果是 ", 1 || 1);
write("<br>1 || 0 的結果是 ", 1 || 0);
write("<br>true || 0 的結果是 ", true || 0);
write("<br>true || 1 的結果是 ", true || 1);
write("<br>true || '0' 的結果是 ", true || '0');
}
document.write('<p><b>////輯運算符"!"</b></p>');
with(document) {
write("!true 的結果是 ", !true);
write("<br>!false 的結果是 ", !false);
write("<br>!'A' 的結果是 ", !'A');
write("<br>!0 的結果是 ", !0);
write("<br>!1 的結果是 ", !1);
write("<br>!2 的結果是 ", !2);
write("<br>!'0' 的結果是 ", !'0');
write("<br>!'1' 的結果是 ", !'1');
write("<br>!-1 的結果是 ", !-1);
}
</script>
</head>
<body>
</body>
</html>
三、JavaScript的轉義字符
可以在 JavaScript 中使用反斜杠來向文本字符串添加特殊字符。對于某些特殊的字符,無法用鍵盤直接鍵入,這時就需要使用轉義字符。還有一些字符(符號)用于特殊的用途,比如引號,如果要在字符串內包含引號,就需要使用轉義字符。切記,每一個轉義字符都是以反斜杠“\”開始的。
1、無法用鍵盤錄入的轉義字符
轉義字符 | 字符 | 轉義字符 | 字符 |
\b | 退格符 | \f | 換頁符 |
\n | 換行符 | \r | 回車符 |
\t | 制表符 | \" | 雙引號 |
\' | 單引號 | \ | 反斜杠 |
2、特殊用途符號轉義字符
字符 | 轉義字符 |
點的轉義:. | \u002E |
美元符號的轉義:$ | \u0024 |
乘方符號的轉義:^ | \u005E |
左大括號的轉義:{ | \u007B |
左方括號的轉義:[ | \u005B |
左圓括號的轉義:( | \u0028 |
豎線的轉義:| | \u007C |
右方括號轉義:] | \u005D |
右圓括號的轉義:) | \u0029 |
星號的轉義:* | \u002A |
加號的轉義:+ | \u002B |
問號的轉義:? | \u003F |
反斜杠的轉義:\ | \u005C |
JavaScript代碼如下:
<script type="text/javascript">
var oStr="我的名字叫\“張三\”,這段文字已經被雙引號,按JS語法規則,";
oStr+="雙引號中不能包括雙引號。為了顯示是姓名被雙引號,在姓名雙引號前加反斜杠。";
document.write(oStr);
</script>
將script標簽內的JavaScript腳步代碼復制、粘貼到銀河統計JavaScript腳本測試工具,運行結果如下:
我的名字叫“張三”,這段文字已經被雙引號,按JS語法規則,雙引號中不能包括雙引號。為了顯示是姓名被雙引號,在姓名雙引號前加反斜杠。
注:這段文字為引號嵌套,但姓名的引號前使用了轉移符號“\”,使得document.write(oStr)可以正確顯示
HTML+CSS+JS是前端網頁開發的基礎,JS(JavaScript)在HTML網頁中動態寫入文本、數字和插入圖表。掌握JavaScript編程可以輕松調用各類統計學庫函數和在網頁上進行統計數據處理或分析。
<!DOCTYPE>聲明位于位于HTML文檔中的第一行,處于 <html>標簽之前。告知瀏覽器的解析器,用什么文檔標準解析這個文檔。DOCTYPE不存在或格式不正確會導致文檔以兼容模式呈現。
標準模式的排版 和JS運作模式都是以該瀏覽器支持的最高標準運行。在兼容模式中,頁面以寬松的向后兼容的方式顯示,模擬老式瀏覽器的行為以防止站點無法工作。
HTML5 不基于 SGML,因此不需要對DTD進行引用,但是需要doctype來規范瀏覽器的行為(讓瀏覽器按照它們應該的方式來運行);
而HTML4.01基于SGML,所以需要對DTD進行引用,才能告知瀏覽器文檔所使用的文檔類型。**
首先:CSS規范規定,每個元素都有display屬性,確定該元素的類型,每個元素都有默認的display值,如div的display默認值為“block”,則為“塊級”元素;span默認display屬性值為“inline”,是“行內”元素。
(1)行內元素有:a b span img input select strong(強調的語氣)
(2)塊級元素有:div ul ol li dl dt dd h1 h2 h3 h4…p
(3)常見的空元素:
<img><input><link><meta>
鮮為人知的是:
<area><base><col><command><embed><keygen><param><source><track><wbr>
4.頁面導入樣式時,使用link和@import有什么區別?
link屬于XHTML標簽,除了加載CSS外,還能用于定義RSS, 定義rel連接屬性等作用;而@import是CSS提供的,只能用于加載CSS;
頁面被加載的時,link會同時被加載,而@import引用的CSS會等到頁面被加載完再加載;
import是CSS2.1 提出的,只在IE5以上才能被識別,而link是XHTML標簽,無兼容問題;
主要分成兩部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。
渲染引擎:負責取得網頁的內容(HTML、XML、圖像等等)、整理訊息(例如加入CSS等),以及計算網頁的顯示方式,然后會輸出至顯示器或打印機。瀏覽器的內核的不同對于網頁的語法解釋會有不同,所以渲染的效果也不相同。所有網頁瀏覽器、電子郵件客戶端以及其它需要編輯、顯示網絡內容的應用程序都需要內核。
JS引擎則:解析和執行javascript來實現網頁的動態效果。
最開始渲染引擎和JS引擎并沒有區分的很明確,后來JS引擎越來越獨立,內核就傾向于只指渲染引擎。
Trident內核:IE,MaxThon,TT,The World,360,搜狗瀏覽器等。[又稱MSHTML]
Gecko內核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等
Presto內核:Opera7及以上。 [Opera內核原為:Presto,現為:Blink;]
Webkit內核:Safari,Chrome等。 [ Chrome的:Blink(WebKit的分支)]
移除的元素:
純表現的元素:basefont,big,center,font, s,strike,tt,u;
對可用性產生負面影響的元素:frame,frameset,noframes;
用正確的標簽做正確的事情。
html語義化讓頁面的內容結構化,結構更清晰,便于對瀏覽器、搜索引擎解析;
即使在沒有樣式CSS情況下也以一種文檔格式顯示,并且是容易閱讀的;
搜索引擎的爬蟲也依賴于HTML標記來確定上下文和各個關鍵字的權重,利于SEO;
使閱讀源代碼的人對網站更容易將網站分塊,便于閱讀維護理解。
在用戶沒有連網時,可以正常訪問站點或應用,在用戶與網絡連接時更新用戶機器上的緩存文件。
原理:HTML5的離線存儲是基于一個新建的.appcache文件的緩存機制(不是存儲技術),通過這個文件上的解析清單離線存儲資源,這些資源就會像cookie一樣被存儲了下來。之后當網絡在處于離線狀態下時,瀏覽器會通過被離線存儲的數據進行頁面展示。
如何使用:
頁面頭部像下面一樣加入一個manifest的屬性;
在cache.manifest文件的編寫離線存儲的資源;
CACHE MANIFEST
#v0.11
CACHE:
js/app.js
css/style.css
NETWORK:
resourse/logo.png
FALLBACK:
/ /offline.html
在離線狀態時,操作window.applicationCache進行需求實現。
在線的情況下,瀏覽器發現html頭部有manifest屬性,它會請求manifest文件,如果是第一次訪問app,那么瀏覽器就會根據manifest文件的內容下載相應的資源并且進行離線存儲。如果已經訪問過app并且資源已經離線存儲了,那么瀏覽器就會使用離線的資源加載頁面,然后瀏覽器會對比新的manifest文件與舊的manifest文件,如果文件沒有發生改變,就不做任何操作,如果文件改變了,那么就會重新下載文件中的資源并進行離線存儲。
離線的情況下,瀏覽器就直接使用離線存儲的資源。
iframe會阻塞主頁面的Onload事件;
搜索引擎的檢索程序無法解讀這種頁面,不利于SEO;
iframe和主頁面共享連接池,而瀏覽器對相同域的連接有限制,所以會影響頁面的并行加載。
使用iframe之前需要考慮這兩個缺點。如果需要使用iframe,最好是通過javascript
動態給iframe添加src屬性值,這樣可以繞開以上兩個問題。
label標簽來定義表單控制間的關系,當用戶選擇該標簽時,瀏覽器會自動將焦點轉到和標簽相關的表單控件上。
<label for="Name">Number:</label>
<input type=“text“name="Name" id="Name"/>
<label>Date:<input type="text" name="B"/></label>
WebSocket、也可以調用localstorge、cookies等本地存儲方式,還可以使用頁面的路有參數傳遞
localstorge另一個瀏覽上下文里被添加、修改或刪除時,它都會觸發一個事件,
我們通過監聽事件,控制它的值來進行頁面信息通信;
14.如何在頁面上實現一個圓形的可點擊區域?
map+area或者svg
border-radius
純js實現 需要求一個點在不在圓上簡單算法、獲取鼠標坐標等等
title屬性沒有明確意義只表示是個標題,H1則表示層次明確的標題,對頁面信息的抓取也有很大的影響;
strong是標明重點內容,有語氣加強的含義,使用閱讀設備閱讀網絡時:會重讀,而是展示強調內容。
i內容展示為斜體,em表示強調的文本;
h5新增的屬性
可以通過ele.dataset獲取到標簽上的data-x的屬性
返回一個對象
解決:解決方案是做成PNG8.
解決:方案是加一個全局的*{margin:0;padding:0;}來統一。
解決:解決方案是在float的標簽樣式控制中加入 ——_display:inline;將其轉化為行內屬性。(_這個符號只有ie6會識別)
漸進識別的方式,從總體中逐漸排除局部。
首先,巧妙的使用“9”這一標記,將IE游覽器從所有情況中分離出來。 接著,再次使用“+”將IE8和IE7、IE6分離開來,這樣IE8已經獨立識別。
css
.bb{
background-color:#f1ee18;/*所有識別*/
.background-color:#00deff\9; /*IE6、7、8識別*/
+background-color:#a200ff;/*IE6、7識別*/
_background-color:#1e0bd1;/*IE6識別*/
}
解決:解決方法:統一通過getAttribute()獲取自定義屬性.
解決方法:(條件注釋)缺點是在IE瀏覽器下可能會增加額外的HTTP請求數。
解決:可通過加入 CSS 屬性 -webkit-text-size-adjust: none; 解決.
解決:方法是改變CSS屬性的排列順序:L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}
該標簽可聲明三種 DTD 類型,分別表示嚴格版本、過渡版本以及基于框架的 HTML 文檔。
HTML 4.01 規定了三種文檔類型:Strict、Transitional 以及 Frameset。
XHTML 1.0 規定了三種 XML 文檔類型:Strict、Transitional 以及 Frameset。
Standards (標準)模式(也就是嚴格呈現模式)用于呈現遵循最新標準的網頁,而 Quirks(包容)模式(也就是松散呈現模式或者兼容模式)用于呈現為傳統瀏覽器而設計的網頁。
1)所有的標記都必須要有一個相應的結束標記
2)所有標簽的元素和屬性的名字都必須使用小寫
3)所有的XML標記都必須合理嵌套
4)所有的屬性必須用引號""括起來
5)把所有<和&特殊符號用編碼表示
6)給所有屬性賦一個值
7)不要在注釋內容中使“--”
8)圖片必須有說明文字
title是global attributes之一,用于為元素提供附加的advisory information。通常當鼠標滑動到元素上的時候顯示。
alt是<img>的特有屬性,是圖片內容的等價描述,用于圖片無法加載時顯示、讀屏器閱讀圖片。可提圖片高可訪問性,除了純裝飾圖片外都必須設置有意義的值,搜索引擎會重點分析。
改版的時候更方便 只要改css文件。
頁面加載速度更快、結構化清晰、頁面顯示簡潔。
表現與結構相分離。
易于優化(seo)搜索引擎更友好,排名更容易靠前。
派生選擇器(用HTML標簽申明)
id選擇器(用DOM的ID申明)
類選擇器(用一個樣式類名申明)
屬性選擇器(用DOM的屬性申明,屬于CSS2,IE6不支持,不常用,不知道就算了)
除了前3種基本選擇器,還有一些擴展選擇器,包括
后代選擇器(利用空格間隔,比如div .a{ })
群組選擇器(利用逗號間隔,比如p,div,#a{ })
那么問題來了,CSS選擇器的優先級是怎么樣定義的?
一般而言,選擇器越特殊,它的優先級越高。也就是選擇器指向的越準確,它的優先級就越高。
復雜的計算方法:
用1表示派生選擇器的優先級
用10表示類選擇器的優先級
用100標示ID選擇器的優先級
div.test1 .span var 優先級 1+10 +10 +1
span#xxx .songs li 優先級1+100 + 10 + 1
xxx li 優先級 100 +1
那么問題來了,看下列代碼,<p>標簽內的文字是什么顏色的?
<style>
.classA{ color:blue;}
.classB{ color:red;}
</style>
<body>
<p class='classB classA'> 123 </p>
</body>
答案:red。與樣式定義在文件中的先后順序有關,即是后面的覆蓋前面的,與在<p class=’classB classA’>中的先后關系無關。
塊級元素(block)特性:
總是獨占一行,表現為另起一行開始,而且其后的元素也必須另起一行顯示;
寬度(width)、高度(height)、內邊距(padding)和外邊距(margin)都可控制;
內聯元素(inline)特性:
和相鄰的內聯元素在同一行;
寬度(width)、高度(height)、內邊距的top/bottom(padding-top/padding-bottom)和外邊距的top/bottom(margin-top/margin-bottom)都不可改變(也就是padding和margin的left和right是可以設置的),就是里面文字或圖片的大小。
那么問題來了,瀏覽器還有默認的天生inline-block元素(擁有內在尺寸,可設置高寬,但不會自動換行),有哪些?
答案:<input> 、<img> 、<button> 、<texterea> 、<label>。
外邊距重疊就是margin-collapse。
在CSS當中,相鄰的兩個盒子(可能是兄弟關系也可能是祖先關系)的外邊距可以結合成一個單獨的外邊距。這種合并外邊距的方式被稱為折疊,并且因而所結合成的外邊距稱為折疊外邊距。
折疊結果遵循下列計算規則:
兩個相鄰的外邊距都是正數時,折疊結果是它們兩者之間較大的值。
兩個相鄰的外邊距都是負數時,折疊結果是兩者絕對值的較大值。
兩個外邊距一正一負時,折疊結果是兩者的相加的和。
rgba()和opacity都能實現透明效果,但最大的不同是opacity作用于元素,以及元素內的所有內容的透明度,
而rgba()只作用于元素的顏色或其背景色。(設置rgba透明的元素的子元素不會繼承透明效果!)
* 1.id選擇器( # myid)
2.類選擇器(.myclassname)
3.標簽選擇器(div, h1, p)
4.相鄰選擇器(h1 + p)
5.子選擇器(ul < li)
6.后代選擇器(li a)
7.通配符選擇器( * )
8.屬性選擇器(a[rel="external"])
9.偽類選擇器(a: hover, li: nth - child)
* 可繼承: font-size font-family color, UL LI DL DD DT;
* 不可繼承 :border padding margin width height ;
* 優先級就近原則,樣式定義最近者為準;
* 載入樣式以最后載入的定位為準;
優先級為:
!important > id > class > tag
important 比 內聯優先級高
CSS3新增偽類舉例:
p:first-of-type 選擇屬于其父元素的首個 <p> 元素的每個 <p> 元素。
p:last-of-type 選擇屬于其父元素的最后 <p> 元素的每個 <p> 元素。
p:only-of-type 選擇屬于其父元素唯一的 <p> 元素的每個 <p> 元素。
p:only-child 選擇屬于其父元素的唯一子元素的每個 <p> 元素。
p:nth-child(2) 選擇屬于其父元素的第二個子元素的每個 <p> 元素。
:enabled、:disabled 控制表單控件的禁用狀態。
:checked,單選框或復選框被選中。
給div設置一個寬度,然后添加margin:0 auto屬性
div{
width:200px;
margin:0 auto;
}
居中一個浮動元素
確定容器的寬高 寬500 高 300 的層
設置層的外邊距
.div {
Width:500px ; height:300px;//高度可以不設
Margin: -150px 0 0 -250px;
position:relative;相對定位
background-color:pink;//方便看效果
left:50%;
top:50%;
}
* IE瀏覽器的內核Trident、 Mozilla的Gecko、google的WebKit、Opera內核Presto;
* png24為的圖片在iE6瀏覽器上出現背景,解決方案是做成PNG8.
* 瀏覽器默認的margin和padding不同。解決方案是加一個全局的*{margin:0;padding:0;}來統一。
* IE6雙邊距bug:塊屬性標簽float后,又有橫行的margin情況下,在ie6顯示margin比設置的大。
浮動ie產生的雙倍距離 #box{ float:left; width:10px; margin:0 0 0 100px;}
這種情況之下IE會產生20px的距離,解決方案是在float的標簽樣式控制中加入 ——_display:inline;將其轉化為行內屬性。(_這個符號只有ie6會識別)
漸進識別的方式,從總體中逐漸排除局部。
首先,巧妙的使用“\9”這一標記,將IE游覽器從所有情況中分離出來。
接著,再次使用“+”將IE8和IE7、IE6分離開來,這樣IE8已經獨立識別。
css
.bb{
background-color:#f1ee18;/*所有識別*/
.background-color:#00deff\9; /*IE6、7、8識別*/
+background-color:#a200ff;/*IE6、7識別*/
_background-color:#1e0bd1;/*IE6識別*/
}
* IE下,可以使用獲取常規屬性的方法來獲取自定義屬性,
也可以使用getAttribute()獲取自定義屬性;
Firefox下,只能使用getAttribute()獲取自定義屬性.
解決方法:統一通過getAttribute()獲取自定義屬性.
* IE下,even對象有x,y屬性,但是沒有pageX,pageY屬性;
Firefox下,event對象有pageX,pageY屬性,但是沒有x,y屬性.
* (條件注釋)缺點是在IE瀏覽器下可能會增加額外的HTTP請求數。
* Chrome 中文界面下默認會將小于 12px 的文本強制按照 12px 顯示, 可通過加入 CSS 屬性 -webkit-text-size-adjust: none; 解決.
超鏈接訪問過后hover樣式就不出現了 被點擊訪問過的超鏈接樣式不在具有hover和active了解決方法是改變CSS屬性的排列順序:
L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}
!important > id > class > 標簽
!important 比 內聯優先級高
可繼承: font-size font-family color, ul li dl dd dt;
不可繼承 :border padding margin width height ;
講 DOM 先從 HTML 講起,講 HTML 先從 XML 講起。XML 是一種可擴展的標記語言,所謂可擴展就是它可以描述任何結構化的數據,它是一棵樹!
document.write只能重繪整個頁面
innerHTML可以重繪頁面的一部分
createDocumentFragment() //創建一個DOM片段
createElement() //創建一個具體的元素
createTextNode() //創建一個文本節點
appendChild()
removeChild()
replaceChild()
insertBefore() //在已有的子節點前插入一個新的子節點
getElementsByTagName() //通過標簽名稱
getElementsByName() //通過元素的Name屬性的值(IE容錯能力較強,會得到一個數組,其中包括id等于name值的)
getElementById() //通過元素Id,唯一性
attribute是dom元素在文檔中作為html標簽擁有的屬性;
property就是dom元素在js中作為對象擁有的屬性。
所以:
對于html的標準屬性來說,attribute和property是同步的,是會自動更新的,
但是對于自定義的屬性來說,他們是不同步的,
src用于替換當前元素,href用于在當前文檔和引用資源之間確立聯系。
src是source的縮寫,指向外部資源的位置,指向的內容將會嵌入到文檔中當前標簽所在位置;在請求src資源時會將其指向的資源下載并應用到文檔內,當瀏覽器解析到該元素時,會暫停其他資源的下載和處理,直到將該資源加載、編譯、執行完畢,圖片和框架等元素也如此,類似于將所指向資源嵌入當前標簽內。這也是為什么將js腳本放在底部而不是頭部。
Src source,指向外部資源的位置,如果我們添加<script src="js.js"></script>瀏覽器會暫停其他資源的下載和處理,直到該資源加載,編譯,執行完畢(圖片和框架也是如此),這也就是為什么js腳本要放在底部。
src用于替換當前元素,href用于在當前文檔和引入資源之間建立聯系。
cookie 本身不是用來做服務器端存儲的(計算機領域有很多這種“狗拿耗子”的例子,例如 CSS 中的 float),它是設計用來在服務器和客戶端進行信息傳遞的,因此我們的每個 HTTP 請求都帶著 cookie。但是 cookie 也具備瀏覽器端存儲的能力(例如記住用戶名和密碼),因此就被開發者用上了。
使用起來也非常簡單,document.cookie=....即可。
但是 cookie 有它致命的缺點:
存儲量太小,只有 4KB
所有 HTTP 請求都帶著,會影響獲取資源的效率
API 簡單,需要封裝才能用
后來,HTML5 標準就帶來了sessionStorage和localStorage,先拿localStorage來說,它是專門為了瀏覽器端緩存而設計的。
存儲量增大到 5MB
不會帶到 HTTP 請求中
API 適用于數據存儲 localStorage.setItem(key, value) localStorage.getItem(key)
sessionStorage的區別就在于它是根據 session 過去時間而實現,而localStorage會永久有效,應用場景不同。例如,一些需要及時失效的重要信息放在sessionStorage中,一些不重要但是不經常設置的信息,放在localStorage中。
標簽閉合、標簽小寫、不亂嵌套、提高搜索機器人搜索幾率、使用外 鏈css和js腳本、結構行為表現的分離、文件下載與頁面速度更快、內容能被更多的用戶所訪問、內容能被更廣泛的設備所訪問、更少的代碼和組件,容易維 護、改版方便,不需要變動頁面內容、提供打印版本而不需要復制內容、提高網站易用性;
的想法:如果我要構建快速可靠的網站,需要真正了解瀏覽器渲染網頁的每個步驟機制,這樣就可以在開發過程中對每個步驟進行優化。這篇文章是我在較高水平上對端到端過程的學習總結。
好了,廢話不多說,我們開始吧。這個過程可以分為以下幾個主要階段:
當瀏覽器通過網絡接收頁面的HTML數據時,它會立即設置解析器將HTML轉換為文檔對象模型(DOM)。
文檔對象模型 (DOM) 是HTML和XML文檔的編程接口。它提供了對文檔的結構化的表述,并定義了一種方式可以使從程序中對該結構進行訪問,從而改變文檔的結構,樣式和內容。DOM 將文檔解析為一個由節點和對象(包含屬性和方法的對象)組成的結構集合。簡言之,它會將web頁面和腳本或程序語言連接起來。
解析過程的第一步是將HTML分解并表示為開始標記、結束標記及其內容標記,然后它可以構造DOM。
當解析器遇到外部資源(如CSS或JavaScript文件)時,解析器將提取這些文件。解析器在加載CSS文件時繼續運行,此時會阻止頁面渲染,直到資源加載解析完(稍后會詳細介紹)。
JavaScript 文件略有不同-默認情況下,解析器會在加載 JS 文件然后進行解析同時會阻止對HTML的解析。可以將兩個屬性添加到腳本標簽中以減輕這種情況:defer 和async。兩者都允許解析器在后臺加載JavaScript 文件的同時繼續運行,但是它們的執行方式不同。關于這一點后面還會再講一點,但總的來說:
defer表示文件的執行將被延遲,直到文檔的解析完成為止。如果多個文件具有defer屬性,則將按照頁面放置的順序依次執行。
<script type="text/javascript" src="script.js" defer>
async 意味著文件將在加載后立即執行,這可能是在解析過程中或在解析過程之后執行的,因此不能保證異步腳本的執行順序。
<script type="text/javascript" src="script.js" async>
<link> 元素的 rel 屬性的屬性值preload能夠讓你在你的HTML頁面中 <head>元素內部書寫一些聲明式的資源獲取請求,可以指明哪些資源是在頁面加載完成后即刻需要的。
對于這種即刻需要的資源,你可能希望在頁面加載的生命周期的早期階段就開始獲取,在瀏覽器的主渲染機制介入前就進行預加載。這一機制使得資源可以更早的得到加載并可用,且更不易阻塞頁面的初步渲染,進而提升性能。
<link href="style.css" rel="preload" as="style" />
你可能很早就知道DOM,但對**CSSOM(CSS對象模型)**可能聽得少,反正我也沒聽過幾次。
CSS 對象模型 (CSSOM) 是樹形形式的所有CSS選擇器和每個選擇器的相關屬性的映射,具有樹的根節點,同級,后代,子級和其他關系。CSSOM 與 文檔對象模型(DOM) 非常相似。兩者都是關鍵渲染路徑的一部分,也是正確渲染一個網站必須采取的一系列步驟。
CSSOM 與 DOM一起構建渲染樹,瀏覽器依次使用渲染樹來布局和繪制網頁。
與HTML文件和DOM相似,加載CSS文件時,必須將它們解析并轉換為樹-這次是CSSOM。它描述了頁面上的所有CSS選擇器,它們的層次結構和屬性。
CSSOM 與 DOM的不同之處在于它不能以增量方式構建,因為CSS規則由于特定性而可以在各個不同的點相互覆蓋。這就是CSS 阻塞渲染的原因,因為在解析所有CSS并構建CSSOM之前,瀏覽器無法知道每個元素在屏幕上的位置。
不同的瀏覽器有不同的 JS 引擎來執行此任務。從計算機資源的角度來看,解析 JS 可能是一個昂貴的過程,比其他類型的資源更昂貴,因此優化它對于獲得良好的性能是如此重要。
加載的JS和DOM被完全解析并準備就緒后就會 emit document.DOMContentLoaded事件。對于需要訪問DOM的任何腳本,例如以某種方式進行操作或偵聽用戶交互事件,優良作法是在執行腳本之前先等待此事件。
document.addEventListener('DOMContentLoaded', (event) => {
// 這里面可以安全地訪問DOM了
});
在所有其他內容(例如異步JavaScript,圖像等)完成加載后,將觸發window.load事件。
window.addEventListener('load', (event) => {
// 頁面現已完全加載
});
渲染樹是DOM和CSSOM的組合,表示將要渲染到頁面上的所有內容。這并不一定意味著渲染樹中的所有節點都將在視覺上呈現,例如,將包含opacity: 0或visibility: hidden的樣式的節點,并仍然可以被屏幕閱讀器等讀取,而display: none不包括任何內容。此外,諸如<head>之類的不包含任何視覺信息的標簽將始終被忽略。
與 JS 引擎一樣,不同的瀏覽器具有不同的渲染引擎。
現在我們有了完整的渲染樹,瀏覽器知道了要渲染什么,但是不知道在哪里渲染。因此,必須計算頁面的布局(即每個節點的位置和大小)。渲染引擎從頂部開始一直向下遍歷渲染樹,計算應顯示每個節點的坐標。
完成之后,最后一步是獲取布局信息并將像素繪制到屏幕上。
作者:James Starkie 譯者:前端小智 來源:dev
原文:https://dev.to/jstarmx/how-the-browser-renders-a-web-page-1ah
*請認真填寫需求信息,我們會在24小時內與您取得聯系。