Learn JS NoteBook
基本概念
1.變量:
(1)js的變量是鬆散類型的,可以用來保存任何類型的數據。定義變量要用var操作符。
var a = 1;
var a = "abc";
var a = 1,b = "a";
(2)用var修飾和不用var修飾的變量區別:
使用var
操作符定義的變量將成爲定義該變量作用域的局部變量。
function test(){
message = "hi";
}
test();
alert(message);
使用var修飾的變量不可delete,無var修飾的變量可以delete
2.數據類型
(1)js中有5種基本數據類型:Undefined,Null,Boolean,Number,String.
還有一種複雜數據類型Object(無序的名值)
i
(2)typeof操作符測試變量的數據類型,括號可以不寫
undefined:這個值未定義
boolean:布爾值
string:字符串
number:數值
object:對象或者null
function:這個值是函數
function test(){
var message = "hi",age = 29;
var b;
alert(c);//報錯
alert(typeof b);//undefined
alert(typeof c);//undefined
}
test();
(3)var修飾的變量在函數內的定義是處處有定義的
var a = "abc";
var b = 1;
c= 2;
function test(){
alert(a);//undefined
alert(b);//1
alert(c);//2
var a = "bcd";
b = 2;
c =3;
alert(a);//bcd
alert(b);//2
alert(c);//3
}
test();
//以上代碼相當於在函數test()函數的第一行自動添加 var a;
(4)null和undefined在用==判斷總是想等,返回true;
var a = null;
function test(){
var message = "hi",age = 29;
var b;
alert(b==a); //true;
}
test();
(5)NaN,Infinity,-Infinity
var a =1/0;
alert(a);
var b = -1/0;
alert(b);
alert(isNaN(NaN));
alert(isNaN("10"));
alert(isNaN("abc"));
alert(isNaN(true));
var s = "sd";
alert(s/2);
4.操作符與語句(略)
==
和===
逗號操作符
function test(){
var a = (1,2,3,4);
alert(a);
}
test(); //4
for-in
語句:循環輸出的屬性名順序是不可預測的
function test(){
// var a = [1,2,3,4,5,6];
// for(var b in a){
// alert(a[b]);
// }
var person = {
name:"Mike",
age:29,
5:true
}
for(var b in person){
alert(person[b]);
}
}
test();
5.函數
(1)理解參數
js函數不介意傳遞進來多少個參數,也不在乎參數的類型,固沒有重載的概念。也就是說
,即使你定義的函數只能傳遞只接收兩個參數,在調用這個函數時也未必傳遞兩個參數。
在函數體內,可以通過arguments對象訪問參數數組,即第一個元素就爲arguments[0].
(2)當沒有參數時,小括號可以省略var person = new Object;
變量,作用域和內存問題
1.複製變量值
var person = new Object();
person.name = "Mike";
var p = person;
p.name = "Jack";
alert(person.name);
alert(p.name);
2.沒有塊級作用域,對應var修飾的變量在函數內的定義是處處有定義的
function test(){
var a = 1;
if(a==1){
var b = 2;
}
alert(b);
}
test();
引用類型
1.創建Object實例的方法
(1)new操作符後跟Object構造函數
var person = new Object();
person.name = "Mike";
person.age = 29;
var s = "name";
alert(person["name"]);
alert(person.name);
alert(person[s]);
(2)對象字面量表示法
var person = {
name:"Mike",
age:29,
5:true //數值屬性會自動轉換成字符串
}
var p = {}; //相當於var p = new Object();
2.Array類型(數組)
創建數組的方式
(1)使用Array構造函數
var a = new Array();
var b = new Array(20);
var c = new Array("Mike");
var d = new Array(1,2,3,4,5);
(2)數組字面量表示法
var colors = ["red","blue","green"];
var a = [];
數組length屬性
數組的length不是隻讀的,可以設置這個屬性進行移除,增加項
var colors = ["red","blue","green"];
colors.length = 2;
alert(colors[2]);
colors[colors.length] = "brown";
alert(colors[2]);
棧方法,隊列方法
push,pop
push,shift
重排序方法
reverse:反轉數組
sort:根據字符串升序排序
toString,valueOf,join方法
concat,splice,indexOf方法
(3)迭代方法
filter()方法:對數組每一項運行給定函數,返回true項返回的數組
var a = [1,2,3,4,5];
var b = a.filter(function(c){
if(c>2) return true;
})
alert(b);
map()方法:對數組每一項運行給定函數,返回每次函數調用的結果組成的數組
var a = [1,2,3,4,5];
var b = a.map(function(c){
return c+1;
})
alert(b);
every()方法:對數組每一項運行給定函數,如果每一項返回true,則返回true
some()方法:對數組每一項運行給定函數,如果任意一項返回true,則返回true
forEach()方法:對數組每一項運行給定函數,無返回值,相當於遍歷數組。
3.Function類型
(1)js裏Function就是個對象,因此函數名就是指向函數對象的指針,不會與某個函數綁定
function f1(num1,num2){ //函數聲明定義函數
return num1 + num2;
}
var a = f1;
alert(a(10,10));
var sum = function(num1,num2){ //函數表達式定義函數
return num1 + num2;
};
(2)函數聲明與函數表達式
解析器在向執行環境中加載數據時,對函數聲明和函數表達式並非一視同仁。
解析器會率先讀取函數聲明,並使其在執行任何代碼之前可用(可以訪問),至於
函數表達式,則必須等到執行器執行到它所在的代碼行,纔會真正被解釋執行。
//以下代碼完全可以正常運行
alert(sum(10,10));
function sum(num1,num2){
return num1 + num2;
}
//以下代碼會在運行期間產生錯誤
alert(sum(10,10));
var sum = function(num1,num2){
return num1 + num2;
};
(3)函數的內部屬性:arguments和this
利用arguments.callee進行遞歸解耦
function f1(num){ //輸出0
if(num<=1) return 1;
else return num * f1(num-1);
}
var f2 = f1;
f1 = function(num){
return 0;
}
alert(f2(5));
function f1(num){//輸出120
if(num<=1) return 1;
else return num * arguments.callee(num-1);
}
var f2 = f1;
f1 = function(num){
return 0;
}
alert(f2(5));
4.基本包裝類型
(1)爲了便於操作基本類型值,js還提供了3個特殊的的引用類型Boolean,Number,和String.
var s1 = "Dumplings";
var s2 = s1.substring(2);
(2)引用類型與基本包裝類型區別
var people = "sd";
people.name = "Jack";
alert(people.name);
(3)使用new調用基本包裝類型和直接調用同名轉型函數區別
function test(){
var value = "25";
var number = value; //(value);
alert(typeof number); //string
var num = new Number(25);
alert(typeof num); //Object
}
test();
(4)Boolean類型
var f = new Boolean(false);
var result = f && true;
alert(result); //true
var f = false;
result = f && true;
alert(result); //false
(5)String類型
charAt charCodeAt concat slice substring substr indexOf lastIndexOf split localeCompare
對於slice substring substr
,在傳遞給這些方法是負值的情況下,slice會將傳入的負值與字符串的長度相加。
substr會將第一個參數加上字符串的長度,將第二個參數轉換成0,substring會把所有參數轉換成0。
var a = "abcdefgh";
alert(a.slice(-3));
alert(a.substring(-3));
alert(a.substr(-3));
alert(a.slice(3,-4));
alert(a.substring(3,-4));
alert(a.substr(3,-4));
面向對象
1.理解對象
var person = {
name:"Mike",
age:22,
sayName:function(){
alert(this.name);
}
}
person.sayName();
2.創建對象
(1)工廠模式
function createPerson(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
}
return o;
}
var p1 = createPerson(1,2,3);
var p2 = createPerson(4,5,6);
無法搞清是哪個對象的實例
(2)構造函數模式
function Person(name,age,person){
this.name = name;
this.age = age;
this.person = person;
this.sayName = function(){
alert(this.name);
}
}
var p1 = new Person(1,2,3);
var p2 = new Person(4,5,6);
sayName創建多次
function Person(name,age,person){
this.name = name;
this.age = age;
this.person = person;
this.sayName = sayName;
}
function sayName(){
alert(this.name);
}
var p1 = new Person(1,2,3);
var p2 = new Person(4,5,6);
p1.sayName();
sayName在全局創建一次,內部sayName相當於指針
(3)原型模式
function Person(){
}
Person.prototype.name = "Mike";
Person.prototype.age = 29;
Person.prototype.job = "Engineer";
Person.prototype.sayName = function () {
alert(this.name);
}
var p1 = new Person();
p1.age = 2222;
alert(p1.age);
alert(p1.hasOwnProperty("age"));
function Person(){
}
Person.prototype = {
name:"Mike",
age:29,
job:"engineer",
sayName: function () {
alert(this.name);
}
};
原型模式的問題
function Person(){
}
Person.prototype = {
name:"Mike",
friends:["A","B"]
};
var p1 = new Person();
p1.friends.push("C");
var p2 = new Person();
alert(p2.friends);
(4)組合使用構造函數模式和原型模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ["A","B"];
}
Person.prototype = {
constructor:Person,
sayName: function () {
alert(this.name);
}
}
var p1 = new Person("Mike",29,"engineer");
var p2 = new Person("Jack",27,"student");
p1.friends.push("C");
alert(p1.friends);
alert(p2.friends);
(5)動態原型模式
(6)寄生構造函數模式
(7)穩妥構造函數模式
3.繼承
(1)原型鏈
function superType(){
this.property = true;
}
superType.prototype.getSuperValue = function(){
return this.property;
}
function SubType(){
this.subproperty = false;
}
SubType.prototype = new superType();
SubType.prototype.getSubValue = function () {
return this.subproperty;
}
var instance = new SubType();
alert(instance.getSuperValue());
alert(instance.getSubValue());
原型鏈的問題
function superType(){
this.property = ["A","B"];
}
superType.prototype.getSuperValue = function(){
return this.property;
}
function SubType(){
}
SubType.prototype = new superType();
SubType.prototype.getSubValue = function () {
return this.subproperty;
}
var instance1 = new SubType();
instance1.property.push("C");
var instance2 = new SubType();
alert(instance2.property);
(2)借用構造函數
function sum(num1,num2){
return num1 + num2;
}
function callSum1(num1,num2){
return sum.call(this,num1,num2);
}
alert(callSum1(1,2));
var color = "red";
var o = {color:"blue"};
function sayColor(){
alert(this.color);
}
sayColor.call(o);
function A(){
this.colors = {"red","blue","green"};
}
function B(){
A.call(this);
}
var instance1 = new B();
instance1.colors.push("black");
alert(instance1.colors);
var instance2 = new B();
alert(instance2.colors);
function A(name){
this.name = name;
this.sayName = function(){
alert("haha");
}
}
function B(){
A.call(this,"Mike");
this.age = 29;
}
var instance = new B();
instance.sayName();
(3)組合繼承
使用原型鏈實現對原型屬性和方法的繼承,通過借用構造函數實現對實例屬性的繼承
function A(name){
this.name = name;
this.colors = ["red","blue","green"];
}
A.prototype.sayName = function () {
alert(this.name);
};
function B(name,age){
A.call(this,name);
this.age = age;
}
B.prototype = new A();
var instance1 = new B("Mike",29);
instance1.colors.push("black");
alert(instance1.colors);
var instance2 = new B("Jack",22);
alert(instance2.colors);
(4)原型式繼承
(5)寄生式繼承
(6)寄生組合式繼承
函數表達式
1.匿名函數(拉姆達函數)
2.閉包
(1)閉包指有權訪問另一個函數作用域中的變量的函數,創建閉包最常見的方式,就是在函數內部創建另一個函數
function f1(p){
return function (ob1,ob2){
var value1 = ob1[p];
var value2 = ob2[p];
if(value1<value2) return -1;
else if(value1>value2) return 1;
else return 0;
};
}
(2)閉包只能取得包含函數中任何變量的最後一個值,閉包所保存的是整個變量對象
function f1(){
var result = new Array();
for(var i = 0;i<10;i++){
result[i] = function(){
return i;
}
}
return result;
}
var s = f1();
for(var i = 0;i< s.length;i++){
alert(s[i]());
}
function f1(){
var result = new Array();
for(var i = 0;i<10;i++){
result[i] = (function(num){
return function () {
return num;
};
})(i);
}
return result;
}
var s = f1();
for(var i = 0;i< s.length;i++){
alert(s[i]());
}
(3)匿名立即執行函數
var f1 = function(){
alert("sdsad");
};
f1();
(function(){
alert("sdsad");
}());
(function(){
alert("sdsad");
})();
BOM
BOM:Browser Object Model(瀏覽器對象模型)
1.window對象
window是BOM的核心對象,它表示一個瀏覽器的實例,既是js訪問瀏覽器窗口的接口,
也是js規定的Global(全局)對象
(1)全局作用域
在全局作用域中聲明的變量,函數都會變成window對象的屬性和方法。
var age = 29;
function sayAge(){
alert(this.age);
}
alert(window.age);
sayAge();
window.sayAge();
//age = 29 相當於 window.age = 29
window對象定義的屬性可以delete,var定義的變量無法delete
var age1 = 1;
window.age2 = 2;
delete window.age2;
alert(window.age2);
(2)窗口位置
var left = window.screenLeft;
var tops = window.screenTop;
alert(left);
alert(tops);
(3)窗口大小
alert(window.innerHeight);
alert(window.innerWidth);
alert(window.outerHeight);
alert(window.outerWidth);
(4)系統對話框
alert,confirm,prompt
if(confirm("Are you ok")){
alert("選擇了是");
}else {
alert("選擇了取消");
}
window.print();
var result = prompt("什麼是一階線性非齊次微分方程?","不會");
if(result===null){
alert("取消");
}else{
alert("Your answer is:"+result);
}
2.location對象
既是window對象的屬性,又是document對象的屬性
//window.location = "http://www.baidu.com";
location.href = "http://www.baidu.com";
document.location = "http://www.baidu.com";
3.navigator對象
包含瀏覽器的屬性和方法,不同瀏覽器屬性不同。例如產品名稱,版本信息,瀏覽器主語言等等..
4.screen對象
表明客戶端能力,不同瀏覽器屬性不同,如屏幕像素高度,DPI(屏幕點數)屬性等等..
5.history對象
保存用戶上網的歷史紀錄
history.go(-1);//後退一頁
history.go(1);//前進一頁
history.go(2);//前進兩頁
DOM
DOM:Document Object Model(文檔對象模型)
DOM可以將任何HTML文檔描繪成一個由多層節點構成的結構
<html>
<head>
<title>Sample Page</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>
文檔節點是每個文檔的根節點,以上文檔結點只有一個子節點,即<html>元素,我們稱
之爲文檔元素文檔元素是文檔的最外層元素,每個文檔只能有一個文檔元素,在HTML中
始終是<html>
(1)childNodes屬性,nodeName,nodeType(節點類型的值),nodeValue(文本節點的值)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<script type="text/javascript">
var a = document.documentElement;
for(var i = 0;i< a.childNodes.length;i++){
alert(a.childNodes[i].nodeName);
}
</script>
</body>
</html>
瀏覽器兼容問題:重點,初學者先忽略。
(2)每個節點都有一個parentNode屬性,指向文檔樹的父節點。
包含在childNodes列表中的每個節點都是同胞兄弟,有相同的parentNode,
並可以通過previousSibling和nextSibling屬性訪問同意列表其他結點,
第一個結點的previousSibling屬性爲null,最後一個節點的nextSibling屬性也爲null
(3)操作結點
可以將DOM樹看成由一系列指針連接起來,任何DOM結點不能同時出現在文檔的多個位置
appendChild:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<p>123</p>
<p>456</p>
<p>789</p>
<script type="text/javascript">
var a = document.body.firstChild.nextSibling;
var b = a.nextSibling.nextSibling;
var result = document.body.appendChild(b);
</script>
</body>
</html>
除了appendChild,還有insertBefore,replaceChild,removeChild,cloneNode
cloneNode接收一個參數,true,false。表示是否執行深複製(包含子節點true),淺複製(不包含子節點false)
(4)Document類型
Document表示文檔,document是HTMLDocument的一個實例,表示整個HTML頁面,document也是window對象的
一個屬性.可做全局對象來訪問,Document結點具有以下屬性
nodeType = 9;
nodeName = "#document"
nodeValue = null;
parentNode = null;
ownerDocument(返回元素的根元素) = null;
document.documentElement
,document.body
獲得對<html>``<body>
的引用
document.title
,document.URL
(5)查找元素
document.getElementById
document.getElementByTagName
namedItem
document.getElementByName
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<p >123</p>
<p name = "myP">456</p>
<p>789</p>
<a href="http://www.baidu.com"></a>
<script type="text/javascript">
var a = document.body.firstChild.nextSibling;
var b = a.nextSibling.nextSibling;
var c = document.getElementsByTagName("p");
var d = document.getElementsByTagName("*");
alert(c.namedItem("myP").childNodes[0].nodeValue);
alert(d.length);
</script>
</body>
</html>
(6)文檔寫入write
,writeln
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<p>123</p>
<p>456</p>
<p>789</p>
<script type="text/javascript">
document.write("<strong>"+"fsdfdsfdsfdsf"+"</strong>")
</script>
</body>
</html>
(7)Element類型
具有以下特性:
nodeType = 1
nodeName = 標籤名
nodeValue = null
parentNode = Document或Element
html元素
id,title,dir,className
取得屬性getAttribute
(可獲取自定義屬性),setAttribute
,removeAttribute
創建元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<p id="a" dir="rtl" dd="adsad">123</p>
<p>456</p>
<p>789</p>
<script type="text/javascript">
var div= document.createElement("div");
div.id = "myDiv";
document.body.appendChild(div);
</script>
</body>
</html>
(8)Text類型
Text結點具有以下特徵
nodeType= 3;
nodeName = "#text";
nodeValue = "包含的文本";
parentNode = 一個Element;
沒有子節點
操作結點文本
var a = document.getElementById("a").childNodes[0];
a.appendData("zzzz");
a.deleteData(0,3);
a.insertData(0,"0000");
a.replaceData(0,3,"asdasd");
a.splitText(1);
a.substringData(1,2);
alert(a.nodeValue);
a.length;
創建文本節點
var a = document.getElementById("a");
var t = document.createTextNode("Hello world");
a.appendChild(t);
(9)Comment類型
註釋在DOM中是通過Comment類型來表示的
具有以下特徵
nodeType = 8;
nodeName = "#comment"
nodeValue = 註釋的內容
parentNode = Document或Element
沒有子節點
Comment與Text具有相同的基類,因此操作方法相似
(10)DocumentType類型:包含着與文檔doctype有關的信息
(11)DocumentFragment類型:文檔片段
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<ul id="myList"></ul>
<script type="text/javascript">
var fra = document.createDocumentFragment();
var ul = document.getElementById("myList");
var li = null;
for (var i = 0; i < 3; i++) {
li = document.createElement("li");
li.appendChild(document.createTextNode("Item"+(i+1)));
fra.appendChild(li);
}
ul.appendChild(fra);
</script>
</body>
</html>
(12)Attr類型
元素的特性在DOM中以Attr類型表示,不推薦使用,推薦setAttribute
,getAttribute
,removeAttribute
DOM擴展
1.CSS選擇符
querySelector()方法:返回匹配的第一個元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<p class="a">123</p>
<p class="a">456</p>
<p>789</p>
<script type="text/javascript">
var body = document.querySelector("body");
var a = document.querySelector(".a");
alert(a.nodeName);
</script>
</body>
</html>
querySelectorAll()方法:返回匹配元素的NodeList.
2.預防空格的元素遍歷
childElementCount:返回子元素個數,不包含文本節點和註釋
firstElementChild:指向第一個子元素,對比於firstChild
lastElementChild, previousElementSibling, nextElementSibling
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<p class="a">123</p>
<p class="a">456</p>
<p>789</p>
<script type="text/javascript">
var a = document.body;
alert(a.firstElementChild.nodeName);
</script>
</body>
</html>
3.HTML5新增
getElementByClassName()方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<div class="a" id="q">
aaa
<div class="b">
b1b1b1
<div class="b">
b2b2b2
</div>
</div>
</div>
<div class="c">
ccccc
<div class="b">cbcbcb</div>
</div>
<script type="text/javascript">
// var a = document.getElementsByClassName("a");
//var a = document.getElementsByClassName("a b");
// var a = document.getElementById("q").getElementsByClassName("b");
// alert(a[1].childNodes[0].nodeValue);
</script>
</body>
</html>
焦點管理
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<button id="a">Button</button>
<script type="text/javascript">
var a = document.getElementById("a");
a.focus();
alert(document.activeElement == a);
</script>
</body>
</html>
自定義數據屬性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<button id="a" data-age="17">Button1</button>
<script type="text/javascript">
var a = document.getElementById("a");
alert(a.dataset.age);
</script>
</body>
</html>
4.插入標記
innerHTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<p id="a">111</p>
<script type="text/javascript">
var b = document.getElementById("a");
b.innerHTML = "<strong>asdasd</strong>";
</script>
</body>
</html>
outerHTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<p id="a">111</p>
<script type="text/javascript">
var b = document.getElementById("a");
alert(b.outerHTML);
b.outerHTML = "<div>222</div>"
</script>
</body>
</html>
5.scrollIntoView()
6.children屬性
只包含元素子節點
7.插入文本
innerText 和 outerText
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<p>pppp</p>
<div>divdivdiv</div>
<script type="text/javascript">
var a = document.body;
a.innerText = "newText";
alert(a.innerText);
</script>
</body>
</html>
DOM2和DOM3
1.訪問元素的樣式
任何支持style特性的HTML元素在js中都對應一個style屬性。對於使用短劃線(如background-image
)的CSS屬性,
必須將其轉換成駝峯大小寫形式。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<style>
#a{
width:200px;
height:200px;
background-image: url("");
}
</style>
</head>
<body>
<div id="a">
aaaaaaaaaaa
</div>
<script type="text/javascript">
var a = document.getElementById("a");
a.style.width = "300px";
a.style.border = "5px solid black";
a.style.backgroundImage = "url('aaa')";
alert(a.style.width);
</script>
</body>
</html>
多數情況下,都可以簡單地轉換屬性名來實現轉換,有一個特殊的屬性float,由於float是js中的保留字,
因此不能用作屬性名。屬性名爲cssFloat(Firefox,Safari,Opera,Chrome),IE爲styleFloat.
2.元素大小
(1)偏移量
offsetHeight:元素在垂直方向上佔用的空間大小
offsetWidth:元素在水平方向上佔用的空間大小
offsetLeft:元素的左外邊框至包含元素左內邊框之間的像素距離
offsetTop:元素的上外邊框至包含元素的上內邊框之間的像素距離
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<style>
#a{
width:200px;
height:200px;
background: blue;
}
#b{
width:200px;
height:200px;
margin-top: 20px;
background: red;
}
</style>
</head>
<body>
<div id="a" style="width: 300px">
aaaaaaaaaaa
<div id="b">
bbbbbbbbbbb
</div>
</div>
<script type="text/javascript">
var a = document.getElementById("a");
var b = document.getElementById("b");
alert(b.offsetTop);
</script>
</body>
</html>
(2)客戶區大小
clientHeight:元素內容區高度加上上下內邊距的高度
clientWidth:元素內容區寬度加上左右邊距的寬度
(3)滾動大小
scrollLeft scrollTop
document.body.scrollTop = 250;
alert(document.body.scrollTop);
ES6入門
1.ECMAScript和JavaScript的關係
1996年11月,JavaScript的創造者Netscape公司,決定將JavaScript提交給國際標準化組織ECMA,
希望這種語言能夠成爲國際標準。
次年,ECMA發佈262號標準文件(ECMA-262)的第一版,規定了瀏覽器腳本語言的標準,並將這種語
言稱爲ECMAScript,這個版本就是1.0版。該標準從一開始就是針對JavaScript語言制定的,但是之
所以不叫JavaScript,有兩個原因。一是商標,Java是Sun公司的商標,根據授權協議,只有Netsca
pe公司可以合法地使用JavaScript這個名字,且JavaScript本身也已經被Netscape公司註冊爲商標。
二是想體現這門語言的制定者是ECMA,不是Netscape,這樣有利於保證這門語言的開放性和中立性。
因此,ECMAScript和JavaScript的關係是,前者是後者的規格,後者是前者的一種實現。
在日常場合,這兩個詞是可以互換的。
2.let和const命令
(1)塊級作用域
function test(){
var a = 1;
if(a==1){
var b = 2;
let c = 3;
}
alert(b);
alert(c);
}
test();
function test(){
for(var i =0;i<3;i++){
alert("haha");
}
alert(i);
}
test();
(2)let無變量提升現象
function test(){
alert(a);
alert(b);
var a = 1;
let b = 2;
}
test();
(3)暫時性死區
只要塊級作用域內存在let命令,它所聲明的變量就“綁定”這個區域,不再受外部的影響。
(4)const
const也用來聲明變量,但是聲明的是常量。一旦聲明,常量的值就不能改變。
(5)let命令、const命令、class命令聲明的全局變量,不屬於全局對象的屬性。
ES6推薦使用let取代var聲明變量
3.變量的解構賦值(模式匹配)
(1)數組和對象的解構賦值
var [a,b,c] = [1,2,3];
alert(a);
var [a,[b,c],d] = [1,[2,3],4];
var {a,b} = {a:1,b:2};
let [{a,b},[c,d]] = [{a:1,b:2},[3,4]];
function f1(a,b,c){
return [a,b,c];
}
var [i,j,k] = f1(1,2,3);
var [a = 1,b] = ["123",2];
(2)用途
交換變量的值
[x,y] = [y,x];
函數返回多個值
function f1(a,b,c){
return [a,b,c];
}
var [x,y,z] = f1(1,2,3);
alert(x);
function f2(a,b){
return {name:a,age:b};
}
var {name,age} = f2("Mike",17);
alert(name);
4.字符串的擴展
(1)for..of遍歷
var s ="abcdefg";
for(let a of s){
alert(a);
}
(2)charAt()方法
(3)repeat()方法
5.函數的拓展
(1)形參默認值
(2)拓展運算符...
將數組轉爲用參數分隔的參數序列
let a = [1,2,3,4];
let b = [1,2,3,4,5,6,7];
let c = a.concat([5,6,7]);
let d = [...a,5,6,7];
alert(b);
alert(c);
alert(d);
並推薦使用...
拷貝數組
(3)箭頭函數
ES6允許用=>
定義函數
var f1 = function(v){
return v;
}
var f = (v) => v;
alert(f(1));
alert(f1(1));
var f = (a) => {a = 1;return a};
alert(f(4));
作用:簡化回調函數
// 正常函數寫法
[1,2,3].map(function (x) {
return x * x;
});
// 箭頭函數寫法
[1,2,3].map(x => x * x);
匿名立即執行函數推薦寫成箭頭函數的形式。
(() => {
alert('Hello!');
})();
6.Class
(1)對比於ES5之前創建類的方法,更加簡單易懂,
ES6推薦使用Class取代prototype
的操作
class People{
constructor(name,age){
this.name = name;
this.age = age;
}
sayHello(){
alert("Hello");
}
toString(){
return "名字是:"+this.name+","+"年齡是:"+this.age;
}
}
var a = new People(1,1);
a.sayHello();
(2)繼承,ES6推薦使用extends語法糖取代原型鏈等複雜的方式
class People{
constructor(name,age){
alert("父類構造!")
this.name = name;
this.age = age;
}
sayHello(){
alert("Hello");
}
toString(){
return "名字是:"+this.name+","+"年齡是:"+this.age;
}
}
class Student extends People{
constructor(name,age,stuId){
super(name,age);
this.stuId =stuId;
alert("子類構造!");
}
}
var a = new Student("Mike",19,20155555);
alert(a.stuId);
事件
1.事件流
(1)事件冒泡
div -> body -> html -> Document
2.事件處理程序
事件就是用戶或瀏覽器自身執行的某種動作。諸如click,load等,都是事件的名字。
而響應某個事件的函數就叫做事件處理程序。事件處理程序的名字以"on"開頭,因此click
時間的處理程序就是onclick,load事件的處理程序就是onload。
(1)HTML事件處理程序(不推薦)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<button onclick="f1()">Button</button>
<script type="text/javascript">
function f1(){
alert('點擊事件!')
}
</script>
</body>
</html>
(2)DOM0級事件處理程序
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<input type="button" id="myBtn" value="Button"/>
<script type="text/javascript">
var a= document.getElementById("myBtn");
a.onclick = function(){
alert(this.id);
}
a.onclick = null; //刪除事件處理程序
</script>
</body>
</html>
(3)DOM2級事件處理程序
DOM2級事件包括三個階段,事件捕獲階段,處於目標階段和事件冒泡階段。
DOM2級事件定義了兩個方法,用於處理指定和刪除事件處理程序的操作:addEventListener()
和
removeEventListener
var a= document.getElementById("myBtn");
a.addEventListener("click",function(){
alert(this.id);
})
removeEventListener無法移除匿名函數
var a= document.getElementById("myBtn");
var f1 = function(){
alert(this.id);
}
a.addEventListener("click",f1);
(4)IE事件處理程序(支持的只有IE和Opera)
IE實現了與DOM中類似的兩個方法,attachEvent()
和detachEvent
.這兩個方法接受相同
的兩個參數。
3.事件對象
(1)DOM中的事件對象
在觸發DOM上的某個事件時,會產生一個事件對象event
,這個對象中包含着所有與事件有關的信息,
包括事件的元素,事件的類型以及其他與特定事件相關的信息。而this
始終等於處理事件的那個元素。
(2)IE中的事件對象
4.事件類型
(1)UI事件:當用戶與頁面上的元素交互時觸發
(2)焦點事件:當元素獲得或失去焦點
(3)鼠標事件:當用戶通過鼠標在頁面上執行操作時觸發
(4)滾輪事件:當使用鼠標滾輪時觸發
(5)文本事件:當在文檔中輸入文本時觸發
(6)鍵盤事件:當用戶通過鍵盤在頁面上執行操作時觸發
(7)合成事件:當爲IME(輸入法編輯器)輸入字符時觸發
(8)變動事件:當底層DOM結構發生變化時觸發
除了這幾類事件,HTML5也新增定義了一組事件。
(1)UI事件
UI事件指的是那些不一定與用戶操作有關的事件。
load:當頁面完全加載後在window上面除法觸發,window對象上發生的
window.onload = function(){
var a = document.getElementById("myBtn");
alert(a);
};
resize:當窗口或框架的大小發生變化時在window或框架上面觸發
window.addEventListener("resize", function () {
alert("Resize");
})
scroll:當頁面滾動位置發生變化時觸發
(2)焦點事件:
blur:當元素失去焦點時觸發,該事件不會冒泡
focus:當元素獲得焦點時觸發,該事件不會冒泡
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
姓名:<input id="name" type="text"/>
學號:<input id="stuId" type="text"/>
<script>
document.getElementById("name").onfocus = function () {
alert("focus");
}
document.getElementById("name").onblur = function () {
alert("Blur");
}
</script>
</body>
</html>
document.getElementById("name").onblur = function () {
if(this.value ==""){
alert("不能爲空!");
document.getElementById("name").focus();
}
}
(3)鼠標與滾輪事件
click:單擊主鼠標(左鍵)時觸發
dblclick:雙擊主鼠標(左鍵)時觸發
mouseover:鼠標移入觸發
mouseout:鼠標移出觸發
mousedown:用戶按下任意鼠標按鈕時觸發
document.getElementById("name").onmousedown = function(){
alert(event.button);
}
獲取鼠標在視口位置event.clientX
,event.clientY
獲取鼠標在頁面位置event.pageX
,event.pageY
mousewheel:當用戶通過鼠標滾輪與頁面交互,在垂直方向上滾動頁面時觸發
wheelDelta是120的倍數
document.body.onmousewheel = function () {
alert(event.wheelDelta);
}
(4)鍵盤與文本事件
keydown:當用戶按下鍵盤上的任意鍵時觸發,按住不放會重複觸發此事件
keypress:當用戶按下鍵盤上的字符鍵時觸發,按住不放會重複觸發此事件
keyup:當用戶釋放鍵盤上的按鍵時觸發
textInput:在文本插入文本框前觸發此事件(DOM3級事件),輸入的字符event.data
當用戶按了鍵盤上的字符集鍵時,首先會觸發keydown事件,緊接着是keypress,最後是keyup事件
鍵碼:event.keyCode
(5)HTML5事件
contextmenu事件:通過右鍵調出上下文菜單
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<div id="myDiv" style="width: 800px;height: 800px;background-color: #ccc">右鍵</div>
<ul id="myMenu" style="width:50px;position: absolute;visibility: hidden;background-color: red;z-index: 12">
<li><a href="">1</a></li>
<li><a href="">2</a></li>
<li><a href="">3</a></li>
</ul>
<script>
window.onload = function(){
var div = document.getElementById("myDiv");
div.oncontextmenu = function () {
event.preventDefault(event);
var menu = document.getElementById("myMenu");
menu.style.left = event.clientX + "px";
menu.style.top = event.clientY + "px";
menu.style.visibility = "visible";
};
document.addEventListener("click",function(){
document.getElementById("myMenu").style.visibility = "hidden";
});
}
</script>
</body>
</html>
(2)HTML5拖放事件
5.模擬事件
UIEvents:一般化UI事件
MouseEvents:一般化鼠標事件
MutationEvents:一般化DOM變動事件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<div id="myDiv" style="width: 800px;height: 800px;background-color: #ccc">右鍵</div>
<script>
var a = document.getElementById("myDiv");
a.onclick = function(){
alert("click");
}
var event = document.createEvent("MouseEvents");
event.initEvent("click");
a.dispatchEvent(event);
</script>
</body>
</html>
表單腳本
1.表單獨有的屬性和方法
(1)action:接受請求的URL
(2)name:表單的名稱
(3)reset():將所有表單域重置爲默認值
(4)submit():提交表單
2.提交表單和阻止表單提交
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<form id="myForm" action="index.html">
<input type="submit" value="提交"/>
</form>
<script>
document.getElementById("myForm").onsubmit = function(){
event.preventDefault(event);
// return false;
}
</script>
</body>
</html>
3.表單重置和阻止表單重置reset
4.表單字段
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<form id="myForm" action="index.html">
姓名:<input type="text"/>
性別:<input type="radio" name="sex"/>男 <input type="radio" name="sex"/>女
<input type="submit" value="提交"/>
</form>
<script>
var myForm = document.getElementById("myForm");
alert(myForm.elements[3].nodeName);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<form id="myForm" action="index.html">
姓名:<input type="text" name="myName"/>
性別:<input type="radio" name="sex"/>男 <input type="radio" name="sex"/>女
<input type="submit" value="提交"/>
</form>
<script>
var myForm = document.getElementById("myForm");
alert(myForm.elements["myName"].nodeName);
</script>
</body>
</html>
5.表單字段屬性
(1)disable:布爾值,表示是否被禁用
(2)form:指向當前所在表單
(3)name:當前字段名稱
(4)readOnly:布爾值,當前字段是否只讀
(5)type:當前字段的類型(checkbox,radio等)
(6)value:當前字段的value值
6.必填字段required
7.選擇框腳本
選擇框是通過<select>
和<option>
元素創建的
(1)選擇框的屬性和方法
add(newOption,relOption)
multiple:布爾值,是否允許多項選擇
options:所有options的集合
remove(index):移除指定位置選項
selectedIndex:選中索引,沒有返回-1
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<form id="myForm" action="index.html">
<select name="city" id="city" >
<option value="Harbin">哈爾濱</option>
<option value="Beijing" selected>北京</option>
</select>
<input type="submit" value="提交"/>
</form>
<script>
var myForm = document.getElementById("myForm");
var a = myForm.elements[0];
alert(a.selectedIndex);
</script>
</body>
</html>
(2)option元素屬性
index:所在索引
selected:布爾值,是否被選中
text:選項的文本
value:選項的value值
定時器
1.理解js的單線程setTimeout
和setInterval
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<button id="myBtn">Button</button>
<script>
var a = document.getElementById("myBtn");
a.onclick = function(){
setTimeout(function(){
alert("定時器");
},1000);
};
</script>
</body>
</html>
2.重複的定時器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<button id="myBtn">Button</button>
<script>
var a = document.getElementById("myBtn");
a.onclick = function(){
setTimeout(function(){
alert("定時器");
setTimeout(arguments.callee,1000);
},1000);
};
</script>
</body>
</html>
3.定時器製作動畫
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<button id="myBtn" style="width: 50px;height: 50px;background-color: red;border: none">Button</button>
<script>
var a = document.getElementById("myBtn");
a.onmouseover = function () {
setTimeout(function () {
if (parseInt(a.style.width) < 900) {
a.style.width = parseInt(a.style.width) + 10 + "px";
setTimeout(arguments.callee, 20);
}
}, 20);
};
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<style>
#a {
width: 100px;
height: 100px;
background: red;
}
</style>
</head>
<body>
<div id="a">
1
</div>
<script type="text/javascript">
var a = document.getElementById("a");
var width = parseInt(getComputedStyle(a,null)['width'].split('px')[0]);
a.onclick = function(){
var timer = setInterval(function(){
width +=10;
a.style.width = width+"px";
alert(a.style.width);
if(a.style.width=="1000px"){
clearInterval(timer);
}
},10);
}
</script>
</body>
</html>
拖放
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
<div id="myDiv" class="draggable" style="width: 100px;height: 100px;position: absolute;background-color: red"></div>
<script>
var DragDrop = function DragDrop(){
var dragging = null;
var diffX = 0;
var diffY = 0;
function handleEvent(event){
var target = event.target;
switch (event.type){
case "mousedown":
if(target.className.indexOf("draggable")>-1){
dragging = target;
diffX = event.clientX - target.offsetLeft;
diffY = event.clientY - target.offsetTop;
}
break;
case "mousemove":
if(dragging!=null){
dragging.style.left = (event.clientX-diffX) + "px";
dragging.style.top = (event.clientY-diffY) + "px";
}
break;
case "mouseup":
dragging = null;
break;
}
};
return{
enable:function (){
document.addEventListener("mousedown",handleEvent);
document.addEventListener("mousemove",handleEvent);
document.addEventListener("mouseup",handleEvent);
},
disable:function(){
document.removeEventListener("mousedown",handleEvent);
document.removeEventListener("mousemove",handleEvent);
document.removeEventListener("mouseup",handleEvent);
}
}
};
DragDrop().enable();
</script>
</body>
</html>
CSS3動畫
1.rotate()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<style>
.a{
width: 100px;
height: 100px;
background: #ccc;
}
.a:hover{
-ms-transform: rotate(30deg); /* IE 9 */
-webkit-transform: rotate(30deg); /* Safari and Chrome */
-o-transform: rotate(30deg); /* Opera */
-moz-transform: rotate(30deg); /* Firefox */
}
</style>
</head>
<body>
<div class="a"></div>
</body>
</html>
var a = document.getElementsByClassName("a")[0];
a.onclick = function(){
a.style.width = "200px";
a.style.webkitTransition = "width 2s";
}
2.translate(50px,100px)
:左側移動50px,頂部移動100px
3.scale(2,4)
:把寬度轉換爲原始尺寸的2倍,把高度轉換爲原始高度的4倍。
4.skew(30deg,20deg)
圍繞X軸把元素翻轉30度,圍繞Y軸翻轉20度。
5.rotateX()
元素圍繞其X軸以給定的度數進行旋轉。-webkit-transform: rotateX(90deg);
6.過渡transition
7.@keyframes
定義動畫
用百分比來規定變化發生的時間
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<style>
@-webkit-keyframes myfirst
{
0% {background: red;}
25% {background: yellow;}
50% {background: blue;}
100% {background: green;}
}
.a{
width: 100px;
height: 100px;
background: #ccc;
}
.a:hover{
-webkit-animation: myfirst 5s;
-webkit-animation-iteration-count: infinite;
}
</style>
</head>
<body>
<center><div class="a"></div>
</center>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<style>
@-webkit-keyframes myfirst /* Safari 和 Chrome */
{
0% {background: red; left:0px; top:0px;}
25% {background: yellow; left:200px; top:0px;}
50% {background: blue; left:200px; top:200px;}
75% {background: green; left:0px; top:200px;}
100% {background: red; left:0px; top:0px;}
}
.a{
position: absolute;
width: 100px;
height: 100px;
background: #ccc;
}
.a:hover{
-webkit-animation: myfirst 5s;
/*播放次數*/
-webkit-animation-iteration-count: infinite;
/*第二次是否逆序播放*/
-webkit-animation-direction:alternate;
}
</style>
</head>
<body>
<center><div class="a"></div>
</center>
</body>
</html>