JavaScript學(xué)習(xí)筆記

筆記來自慕課網(wǎng)的js和《JavaScript DOM編程藝術(shù)》一書以及《JavaScript權(quán)威指南》一書的學(xué)習(xí)逃贝。

js基本概念

  • 給網(wǎng)頁增加交互性的腳本語言
  • 簡單易學(xué)易用
  • 常用來給HTML網(wǎng)頁添加動態(tài)功能伶唯,比如響應(yīng)用戶的各種操作
  • 可以彌補HTML語言的缺陷舌涨,實現(xiàn)web頁面客戶端的動態(tài)效果
  1. 動態(tài)的改變網(wǎng)頁內(nèi)容
  2. 動態(tài)改變網(wǎng)頁的外觀
  3. 驗證表單數(shù)據(jù)
  4. 響應(yīng)事件
  • 幾乎所有瀏覽器都支持JavaScript

  • JavaScript的特點之一:腳本語言JavaScript只需要經(jīng)過編寫淹冰、運行這兩個步驟亦歉,不需要編譯脯燃、鏈接嵌牺。

js代碼的位置

  • <script src="script.js">js代碼</script>放在<head></head>標(biāo)簽中帮辟;
  • <script src="script.js">js代碼</script>放在body中速址;
  • 將js代碼寫在一個單獨的js文件中,在<head>中引用:
    tip:在JS文件中由驹,不需要<script>標(biāo)簽,直接編寫JavaScript代碼就可以了芍锚。
    eg:
<head>
    <script src="script.js"></script>
</head>

最好的做法是把<script>標(biāo)簽放到HTML文檔的最后昔园,</body>標(biāo)簽之前。

js注釋

  • 單行注釋并炮,在注釋內(nèi)容前加符號 “//”默刚。
  • 多行注釋以"/"開始,以"/"結(jié)束逃魄。

js變量

  • 從編程角度講荤西,變量是用于存儲某種/某些數(shù)值的存儲器。
  • 定義變量使用關(guān)鍵字var,語法如下:
    var 變量名

變量名可以任意取名伍俘,但要遵循命名規(guī)則:
1.變量必須使用字母邪锌、下劃線()或者美元符($)開始。
2.然后可以使用任意多個英文字母癌瘾、數(shù)字寡痰、下劃線(
)或者美元符($)組成膝藕。
3.不能使用JavaScript關(guān)鍵詞與JavaScript保留字并巍。

tip:
變量最好先聲明再賦值(JavaScript是一種弱類型的語言锭魔,變量可以不用先聲明,但是最好先聲明咬荷,比較規(guī)范)嚣伐,如下:
var mychar;
mychar="javascript";

如果未在var聲明語句中給變量指定初始值,那么雖然聲明了這個變量萍丐,但在給它存入一個值之前轩端,它的初始值就是undefined。

  • 變量的作用域
    • 全局變量擁有全局作用域逝变,在js代碼中的任何地方都是有定義的基茵。
    • 函數(shù)內(nèi)聲明的變量是局部變量,只在函數(shù)體內(nèi)有定義壳影。
    • 函數(shù)參數(shù)也是局部變量拱层,它們只在函數(shù)體內(nèi)有定義。
    • 在函數(shù)體內(nèi)宴咧,局部變量的優(yōu)先級高于同名的全局變量根灯。

eg:

var scope = "global";//聲明一個全局變量
    function checkscope(){
        var scope = "local";//聲明一個同名的局部變量
        return scope;  //返回局部變量的值,而不是全局變量的值
    }
    checkscope();  //結(jié)果為“l(fā)ocal”

eg:

scope = "global";//聲明一個全局變量掺栅,甚至不用var聲明
    function checkscopes2() {
        scope = "local";  //這種做法將修改全局變量的值
        return scope;
    }
    checkscopes2();//結(jié)果為“l(fā)ocal”

eg:

var scope = "global scope";
    function checkscope() {
        var scope = "local scope";
        function nested() {
            var scope = "nested scope";
            return scope;
        }
        return nested();
    }
    checkscope();//結(jié)果是什么呢烙肺?      "nested scope"
  • 函數(shù)作用域和聲明提前
    塊級作用域:類似C語言的編程中,變量在聲明它的這段花括號內(nèi)是可見的氧卧,花括號外是不可見的桃笙。
    函數(shù)作用域:js使用函數(shù)作用域,變量在聲明它們的函數(shù)體以及這個函數(shù)體嵌套的任意函數(shù)體內(nèi)都是有定義的沙绝。
    eg:
function test(o) {
        var i  = 0;//i在整個函數(shù)體內(nèi)均是有定義的
        if (typeof o == "object") {
            var j = 0;//j在函數(shù)體內(nèi)是有定義的搏明,不僅僅是if這個代碼段內(nèi)
            for (var k=0; k < 10; k++) {//k在函數(shù)體內(nèi)是有定義的鼠锈,不僅僅是在循環(huán)內(nèi)
                console.log(k);//輸出數(shù)字0-9
            }
            console.log(k);//k已經(jīng)定義了,輸出10
        }
        console.log(j);//j已經(jīng)定義了星著,但可能沒有初始化
    }
    test("haha");//例如购笆,“haha”是一個字符串,不是對象虚循,所以IF判斷為假同欠,不進行if里面的代碼,但是雖然j是在if內(nèi)聲明的邮丰,但它在整一個test函數(shù)內(nèi)都是可見的行您,即j已經(jīng)聲明铭乾,僅僅未賦值剪廉,所以輸出undefined。
Paste_Image.png

eg2:

var testObject = {
        x:2,y:3
    }
    function test(o) {
        var i  = 0;
        if (typeof o == "object") {
            var j = 0;
            for (var k=0; k < 10; k++) {
                console.log(k);
            }
            console.log(k);
        }
        console.log(j);
    }
    test(testObject);//此處testObject是一個對象炕檩,滿足if的判斷條件斗蒋,執(zhí)行if花括號內(nèi)的語句,j則在if花括號內(nèi)賦值為0笛质,因此j輸出的值為0
Paste_Image.png

js的函數(shù)作用域是指在函數(shù)內(nèi)聲明的所有變量在函數(shù)體內(nèi)始終可見的泉沾,這意味著變量在聲明之前甚至已經(jīng)可用。js的這個特性被非正式地稱為聲明提前妇押,即js函數(shù)里聲明的所有變量跷究,都被提前至函數(shù)體的頂部,是在js引擎的“預(yù)編譯”時進行的敲霍,是在代碼開始運行之前俊马。

eg:

var scope = "global";
    function f() {
        console.log(scope);//輸出“undefined”,而不是“global”
        var scope = "local";//變量在這里賦初始值肩杈,但變量本身在函數(shù)體內(nèi)任何地方均是有定義的
        console.log(scope);//輸出“l(fā)ocal”
    }
    f();
Paste_Image.png

解析:
第一句聲明了一個全局變量柴我,然后調(diào)用函數(shù)f(),函數(shù)f()中的第一句console.log(scope)扩然,輸出的不是全局變量的scope(“global”)艘儒,因為f函數(shù)中的第二句聲明了局部變量的 scope,雖然這句聲明在第二行夫偶,但是聲明會提前到函數(shù)的開始界睁,所以f函數(shù)中第一句的scope是局部變量的scope,而不是f函數(shù)外的scope兵拢,所以輸出的是undefined晕窑,因為雖然聲明提前了,但是賦值還是在后面卵佛,所以第二個console.log(scope)輸出的是“l(fā)ocal”
即杨赤,以上的代碼可以等效為:

var scope = "global";
    function f() {
        var scope;
        console.log(scope);
        scope = "local";
        console.log(scope);
    }
    f();

即<strong>函數(shù)體內(nèi)的變量聲明提前敞斋,而賦值不會提前,賦值在賦值語句所在位置才進行疾牲。</strong>

數(shù)據(jù)類型

字符串

  • 如果字符串包含雙引號植捎,就把整個字符串放在單引號里;
  • 如果字符串包含單引號阳柔,就把整個字符串放在雙引號里焰枢;
  • 轉(zhuǎn)義字符:用反斜杠
    eg:var mood ='don't ask';

數(shù)值

JavaScript允許使用帶小數(shù)點的數(shù)值,并且允許任意位小數(shù)舌剂。
eg: var age =20;
var temperature = -20.33333;

布爾值

布爾數(shù)據(jù)只有兩個可選值:true或false济锄。
eg:var sleeping =true;(注意true不用加雙引號)

數(shù)組

  • 創(chuàng)建數(shù)組

  • 聲明:
    var team = Array(4); //聲明的同時說明數(shù)組的長度
    var team = Array(); //只聲明數(shù)組;

  • 數(shù)組元素賦值:
    team[0]="Jane";
    team[1]="John";
    team[2]="Linda";
    team[3]="Alin";

  • 聲明同時賦值:
    var team=Array("Jane","John","Linda","Alin");
    或者
    var team=["Jane","John","Linda","Alin"];

  • 數(shù)組中的元素可以是不同類型霍转,也可以包含其他數(shù)組:
    eg:
    var lennon=["Jane",1995,false];

var lennon=["Jane",1995,false];
var team=[];
team[0]=lennon;

對象

  • js的基本數(shù)據(jù)類型之一
  • 是一種復(fù)合值荐绝,將很多值聚合在一起,也可看做是屬性(名/值對)的無序集合避消。
  • 創(chuàng)建對象:
  • 名/值對中間用冒號分隔低滩;
  • 名/值對之間用逗號分隔;
  • 屬性名可以是js標(biāo)識符也可以是字符串直接量岩喷;
  • 保留字作為屬性名要用引號括起來恕沫;
  • 屬性的值可以是任意類型的表達式;
  • 全部名/值對用一個花括號括起來纱意。

eg:

var empty = {};//沒有任何屬性的對象
var point = { x:0, y:0 };//兩個屬性婶溯,一個屬性名是x,屬性值是0偷霉;另一個屬性名是y迄委,屬性值是0.
var point2 = { x:point.x, y:point.y+1 };//更復(fù)雜的值
var book = {
        "main title": "javascript",//屬性名里有空格,必須用字符串表示
        'sub-title': "the definitive guide",//屬性名里有連字符腾它,必須用字符串表示
        "for": "all audiences",//"for"是保留字跑筝,因此必須用引號
        author: {                //這個屬性的值時一個對象
            firstname: "david",//注意:這里的屬性名都沒有引號
            surname: "flanagan"
        }
    };

eg:通過new創(chuàng)建對象

    var o = new Object();
    var a = new Array();
    var d = new Date();
    var r = new RegExp("js");
  • 原型對象
  • 通過js代碼Object.prototype獲得對原型對象的引用
  • 通過new關(guān)鍵字和構(gòu)造函數(shù)調(diào)用創(chuàng)建的對象的原型就是構(gòu)造函數(shù)的prototype屬性的值
    eg:
//定義一個構(gòu)造函數(shù)以初始化一個新的Point對象   
    function Point(x,y) {//構(gòu)造函數(shù)均以大寫字母開始
        this.x = x;
        this.y = y;
    }
    var p = new Point(1,1);//使用new關(guān)鍵字和構(gòu)造函數(shù)來創(chuàng)建一個實例
    var p2 = new Point(2,2);
    Point.prototype.r = function() {//Point.prototype是Point對象的原型對象,每一個實例化的Point對象都繼承這個原型對象的方法瞒滴,因此才此處寫原型對象的某個方法后曲梗,每一個實例化的Point對象都繼承了這個方法并且可以調(diào)用
        return Math.sqrt(this.x*this.x+this.y*this.y);
    }
    p.r();
    p2.r();
  • new Object()創(chuàng)建的對象繼承自O(shè)bject.prototype
  • new Array() 創(chuàng)建的對象的原型是Array.prototype
  • new Date()創(chuàng)建的對象的原型就是Date.prototype
  • Object.create()創(chuàng)建一個新對象,第一個參數(shù)是這個對象的原型妓忍,第二個參數(shù)可選虏两,用以對對象的屬性進行進一步描述。這是一個靜態(tài)函數(shù)世剖,不是用來調(diào)用的定罢。使用方法:傳入所需的原型對象,則創(chuàng)建的 新對象繼承了傳進去的這個原型對象的屬性旁瘫。
    eg:
var o1 = Object.create({x:1,y:2});//o1繼承了屬性x和y
var o2 = Object.create(Object.prototype);//創(chuàng)建了一個普通的空對象祖凫,和{}和new Object()一樣

任意對象都可以被繼承琼蚯,即可以將任意一個對象當(dāng)成原型,然后用這個原型創(chuàng)建一個新對象惠况,則這個新對象繼承了那個原型的屬性遭庶。
eg:

    function inherit(p) {//這整一個inherit函數(shù)返回了一個新的對象,它的原型對象是傳入的參數(shù)p稠屠,繼承了p的屬性
        if (p == null) throw TypeError();//p可以是一個對象但不可以是null
        if (Object.create)//判斷是否存在Object.create()
            return Object.create(p);//存在峦睡,直接使用Object.create();
        var t = typeof p;//否則進一步檢測p的類型
        if(t !== "object" && t !== "function") throw TypeError();//不是對象或者函數(shù)就不行
        function f() {};//定義一個空的構(gòu)造函數(shù)权埠;
        f.prototype = p;//設(shè)置其原型對象為p
        return new f();//使用f()創(chuàng)建p的繼承對象
    }
var o3 = inherit({x:1,y:2});//o3是一個實例化的對象榨了,它的原型對象是{x:1,y:2},繼承了它的屬性
  • 獲得屬性值和設(shè)置屬性值
  • 獲得屬性:用xxx.yyy或者xxx["yyy"];
  • 屬性訪問錯誤:如果這個屬性不存在攘蔽,則返回“undefined”龙屉;
    eg:
    var book = {
        "main title": "javascript",
        'sub-title': "the definitive guide",
        author: {
            firstname: "david",
            surname: "flanagan"
        }
    };
    var title = book["main title"];//得到book的“main title”屬性
var subtitle = book.subtitle;//=>undefined,屬性不存在
    var author = book.author;//得到book的”author“屬性,是一個對象
    var name = book.author.surname;//得到book的”author“屬性的surname屬性秩彤,也可以var name = author.surname;叔扼,因為前面已經(jīng)把 book.author賦給author這個變量了
var len = book.subtitle.length;//book.subtitle是undefined,沒有l(wèi)ength事哭,所以拋出一個類型錯誤異常
//避免獲取屬性時出錯的方法:
//一種冗余的但很易懂的方法:
var len = undefined;
if (book) {
    if (book.subtitle) len = book.subtitle.length;
}
//一種簡練的方法
var len = book && book.subtitle && book.subtitle.length;//由三個&&運算符連接起來的表達式漫雷,
//從左起,第一個若不是真值鳍咱,則不用繼續(xù)看后面降盹,表達式返回第一個操作數(shù)的值;如果第一個真谤辜,
//則繼續(xù)看第二個蓄坏,若第二個不是真值,就返回第二個操作數(shù)的值丑念;如果第二個也為真涡戳,
//則繼續(xù)看第三個,如果第三個為假脯倚,則返回第三個的值渔彰,如果第三個為真,則返回第三個的值推正;
//此處恍涂,第一個操作數(shù)book為真值,是一個對象植榕,所以繼續(xù)看第二個操作數(shù)再沧,
//第二個由于book不存在subtitle屬性,所以第二個操作數(shù)是undefined尊残,為假值炒瘸,
//所以不用繼續(xù)看第三個的值淤堵,表達式的值為第二個操作數(shù)的值,即undefined顷扩。

補充:即使上例存在subtitle屬性粘勒,上面那個表達式最后返回的值即len的值也是undefined,因為object對象不存在length屬性屎即。要獲得object對象中的length庙睡,可用如下方法:
eg:

var a = {a:1,b:2,c:3,d:4};
Object.prototype.length = function() {
    var count = 0;
    for(var i in this){
        count ++;
    }
    return count;
};
alert(a.length());    //5,不是4,因為每個對象都有一個內(nèi)部屬性(__proto__指向原型)技俐。

tip:xxx.yyy,點運算符后面的yyy不能是保留字或關(guān)鍵字乘陪,比如不能是xxx.for或xxx.class,如果屬性名是保留字雕擂,必須用方括號的形式訪問啡邑,比如xxx["for"],xxx["class"]

  • 設(shè)置屬性
    eg:
book.edition = 6;//給book創(chuàng)建一個名為“edition”的屬性
book["main title"] = "ECMAScript";//給“main title”屬性重新賦值
  • 繼承

假設(shè)要查詢對象o的屬性x,如果o中不存在x,那么將會繼續(xù)在o的原型對象中查詢屬性x.如果原型對象中也沒有x,但這個原型對象也有原型井赌,那么繼續(xù)在這個原型對象的原型上執(zhí)行查詢谤逼,直到找到x或者查找到一個原型是null的對象為止。

eg:

    function inherit(p) {
        if (p == null) throw TypeError();
        if (Object.create)
            return Object.create(p);
        var t = typeof p;
        if(t !== "object" && t !== "function") throw TypeError();
        function f() {};
        f.prototype = p;
        return new f();
    }
    var o = {};//o從Object.prototype繼承對象的方法
    o.x = 1;//給o定義一個屬性x并賦值為1
    var p = inherit(o);//p繼承o和Object.prototype
    p.y = 2;//給p定義一個屬性y并賦值為2
    var q = inherit(p);//q繼承p仇穗、o和Object.prototype
    q.z = 3;//給q定義一個屬性z并賦值為3
    var s = q.toString();//toString()繼承自O(shè)bject.prototype
    console.log(q.x + q.y);//=>3:x和y分別繼承自o和p
    q.x = 3;//修改q的屬性x的值為3
    console.log(q.x);//=>3,q的屬性x的值已被修改成3
    console.log(o.x);//=>1,o的屬性值沒有被修改
    console.log(p.x);//=>1,q的屬性值也沒有被修改
控制臺運行截圖.png

給q的屬性x賦值流部,只會改變q的屬性值,而它的原型對象的屬性值不會被修改纹坐,即“繼承”只關(guān)乎讀取屬性值而不關(guān)乎設(shè)置屬性值枝冀。

  • 檢測屬性
  • in運算符
    eg;
    var o = { x:1 };
    console.log("x" in o);//true,x是o的屬性
    console.log("y" in o);//false:y不是o的屬性
    console.log("toString" in o);//true:o繼承toString屬性
  • hasOwnProperty()方法:檢測給定的名字是否是對象的自有屬性,對于繼承屬性耘子,返回false
    eg:
    var o = { x:1 };
    console.log(o.hasOwnProperty("x"));//true:o有一個自有屬性x
    console.log(o.hasOwnProperty("y"));//false:o中不存在屬性y
    console.log(o.hasOwnProperty("toString"));//false:toString是繼承屬性
  • propertyIsEnumerable():檢測對象的可枚舉的自有屬性
    eg:
    function inherit(p) {
        if (p == null) throw TypeError();
        if (Object.create)
            return Object.create(p);
        var t = typeof p;
        if(t !== "object" && t !== "function") throw TypeError();
        function f() {};
        f.prototype = p;
        return new f();
    }
    var o = inherit({ y:2 });
    o.x = 1;
    console.log(o.propertyIsEnumerable("x"));//true果漾,o有一個可枚舉的自有屬性x
    console.log(o.propertyIsEnumerable("y"));//false:y是繼承來的
    console.log(Object.prototype.propertyIsEnumerable("toString"));//false,不可枚舉
  • 用!==直接判斷是否是undefined
    eg:
    var o = { x:1 };
    console.log(o.x !== undefined);//true,o中有屬性x
    console.log(o.y !== undefined);//false,o中沒有屬性y
    console.log(o.toString !== undefined);//true,o繼承了toString屬性
  • tip:in可以區(qū)分不存在的屬性和存在但值為undefined的屬性
    eg:
    var o = { x:undefined };//屬性值被顯式賦值為undefined
    console.log(o.x !== undefined);//false谷誓,屬性存在绒障,但值為undefined
    console.log(o.y !== undefined);//false,屬性不存在
    console.log("x" in o);//true捍歪,屬性存在
    console.log("y" in o);//false户辱,屬性不存在
    delete o.x;//刪除了屬性x
    console.log("x" in o);//false,屬性不再存在

操作

算術(shù)操作符

  • “+”號:
    連接字符串:
    eg:var message = "I am feeling"+"happy";
    eg: alert("10"+20); //返回1020字符串费封,字符串和數(shù)值拼接是更長的字符串焕妙;
    加法: alert(10+20); //返回數(shù)值30;
  • “++”自增:eg:year++; //等效:year=year+1;

函數(shù)

  • 定義一個函數(shù):
    function 函數(shù)名(參數(shù)) {
    函數(shù)體弓摘;
    }
    eg:
    function add(a,b){
    var sum=a+b;
    return sum;
    }
    var result=add(2,5); //result的值為7焚鹊;

認識DOM

文檔對象模型DOM定義訪問和處理HTML文檔的標(biāo)準(zhǔn)方法。DOM將文檔呈現(xiàn)為帶有元素、屬性和文本的樹結(jié)構(gòu)(節(jié)點樹)末患。

節(jié)點

  • 元素節(jié)點 eg:< body>研叫、< p>、< ul>
  • 文本節(jié)點 eg: < p>xxx< /p> ;包含文本節(jié)點“xxx"璧针;
  • 屬性節(jié)點eg: < p title="i am a title">xxx< /p> 中 title="i am a title"是一個屬性節(jié)點嚷炉。

獲取元素

  • getElementById
    eg:var a=document.getElementById("purchase"); //a為一個對象(object),對應(yīng)著ID值為purchase的元素探橱。

  • getElementsByTagName:返回一個對象數(shù)組申屹,每個對象分別對應(yīng)著文檔里有著給定標(biāo)簽 的一個元素。
    eg:
    HTML代碼:
    < ul>
    < li>abc< /li>
    < li>def< /li>
    < li>ghi< /li>
    < /ul>
    js代碼:var a=document.getElementsByTagName("li");
    //js代碼:返回一個數(shù)組隧膏,每個對象分別對應(yīng)著document對象中的一個列表項元素哗讥,即a是一個數(shù)組,數(shù)組中的每個對象是一個li元素胞枕;
    //alert(a.length);可以獲得列表項元素的個數(shù)“3”杆煞;
    //可以通過for循環(huán)遍歷數(shù)組中的每個對象:
    for(var i=0;i<a.length;i++){
    alert(typeof a[i]);//typeof可以告訴我們獲得的類型(object);
    }

  • getElementsByClassName(html5 DOM中新增的方法):返回一個對象數(shù)組腐泻,每個對象分別對應(yīng)著文檔里有著給定 的一個元素决乎。
    eg:var b=document.getElementsByClassName("red select");//b對應(yīng)文檔中同時擁有“red”和“select”類的元素。(如果多個元素都同時擁有這兩個類派桩,則b為一個數(shù)組仍然可以通過b.length獲得數(shù)組長度和通過for循環(huán)遍歷數(shù)組中的對象)

  • summary:

  • 一份文檔就是一棵節(jié)點樹构诚;

  • 節(jié)點分為不同的類型:元素節(jié)點、屬性節(jié)點窄坦、文本節(jié)點唤反;

  • getElementById將返回一個對象凳寺,該對象對應(yīng)著文檔里的一個特定的元素節(jié)點鸭津;

  • getElementsByTagName和getElementsByClassName將返回一個對象數(shù)組,它們分別對應(yīng)著文檔里的一組特定的元素節(jié)點肠缨;

  • 每個節(jié)點都是一個對象逆趋。

獲取和設(shè)置屬性

  • getAttribute:xxx.getAttribute(屬性名);
    eg:
    var c = document.getElementsByTagName("p");
    for (var i=0;i<c.length;i++){
    alert(c[i].getAttribute("title"));//彈出文檔中每一個標(biāo)簽為p的元素的title屬性的值,如果沒有這個屬性晒奕,則會返回null
    }

  • setAttribute:xxx.setAttribute(屬性名闻书,我們要設(shè)置的屬性值);
    eg:var d=document.getElementById("choose");
    d.setAttribute("title","choose something");//為ID值為choose的元素設(shè)置title屬性的屬性值為“choose something”
    tip:如果為已經(jīng)擁有指定屬性的屬性設(shè)置屬性值則會改變原有的屬性值。例如原來的title屬性值為“哈哈”脑慧,后來設(shè)置為“choose something”魄眉,則title的屬性值為“choose something”。

tip:通過setAttribute對文檔做出修改后闷袒,在通過瀏覽器查看源代碼時看到的仍然是修改前的屬性坑律,也就是說setAttribute做出的修改不會反映在文檔本身的源代碼里。這種“表里不一”的現(xiàn)象源自DOM的工作模式:先加載文檔的靜態(tài)內(nèi)容囊骤,再動態(tài)刷新晃择,動態(tài)刷新不影響文檔的靜態(tài)內(nèi)容冀值。這正是DOM的真正威力:對頁面內(nèi)容進行刷新卻不需要在瀏覽器里刷新頁面。

事件處理函數(shù)

  • <a href="xxx" onclick="show();return false;">click me</a>
    原本點擊這個鏈接是會跳轉(zhuǎn)到相關(guān)鏈接去的宫屠,但是在onclick設(shè)置了return false列疗,則鏈接的默認行為不會被觸發(fā),僅執(zhí)行onclcik中的函數(shù)浪蹂。(通過return false禁用默認行為)抵栈。

childNodes屬性

xxx.childNodes; //獲得xxx的全體子元素(數(shù)組)

tip:返回的數(shù)組包含所有類型的節(jié)點,不僅僅是元素節(jié)點坤次,甚至連空格和換行都會被解釋為節(jié)點竭讳。

nodeType屬性

  • 元素節(jié)點的nodeType屬性值為1;
  • 屬性節(jié)點的nodeType屬性值為2浙踢;
  • 文本節(jié)點的nodeType屬性值為3.

nodeValue屬性:改變文本節(jié)點的值

eg:< p id="description">xxx< /p>
var description=document.getElementById("description");
如果直接:alert(description.nodeValue);將返回null绢慢,因為description是< p>,而< p>中的文本是< p>的第一個子節(jié)點,所以要獲得< p>中的文本洛波,則應(yīng)為:alert(decription.childNodes[0].nodeValue);

firstChild和lastChild屬性

xxx.firstChild等價于xxx.childNodes[0],第一個子節(jié)點胰舆;
xxx.lastChild等價于xxx.childNodes[xxx.childNodes.length-1],最后一個子節(jié)點蹬挤。

分離JavaScript

例如為一個鏈接添加點擊事件:
法一:<a onclick="popUp(this.getAttribute('href'));return false;">example</a>
當(dāng)點擊此鏈接文本時缚窿,將調(diào)用popUp函數(shù),并且由于return false焰扳,a標(biāo)簽的默認行為(打開一個鏈接)將被禁用倦零。
如果要將js代碼與HTML文檔分離:
法二:<a class="popup">example</a>
步驟:

  1. 把文檔里的鏈接全放入一個數(shù)組里;
  2. 遍歷數(shù)組吨悍;
  3. 如果某個鏈接的class屬性等于popUp扫茅,就表示這個鏈接在被點擊時應(yīng)該調(diào)用popUp()函數(shù)。
window.onload=prepareLinks;
function prepareLinks(){
        var links=document.getElementsByTagName("a");
        for(var i=0;i<links.length;i++){
            if(links[i].getAttribute("class")=="popup"){
                links[i].onclick=function(){
                    popUp(this.getAttribute("href"));
                    return false;
                }
            }
        }
}

向后兼容

對于不支持DOM的一些瀏覽器應(yīng)有相應(yīng)的處理育瓜,比如一些不支持DOM的瀏覽器就沒有g(shù)etElementById這些方法葫隙,因此先進行對象檢測。

對象檢測

eg:

function myFunction(){
     if(document.getElementById){//檢測瀏覽器是否支持這個方法
        xxxx;//如果支持該方法躏仇,則執(zhí)行這段語句恋脚,如果不支持,則永遠不會執(zhí)行
     }
}

改進:

window.onload=function(){
     if(!document.getElementsByTagName||document.getElementById)return false;//使用邏輯非和邏輯或焰手,可以檢測多種方法糟描;如果不支持,則跳出整個函數(shù)书妻,如果支持船响,繼續(xù)往下執(zhí)行。
     xxxx;
}

性能考慮

  • 盡量減少訪問DOM和盡量減少標(biāo)記
    eg:
if(document.getElementById("haha").length>0){
    for(var i=0;i<document.getElementById("haha").length;i++){
        xxx;
    }
}

這樣子的代碼重復(fù)訪問了DOM樹,降低了性能灿意。
改進:

var links=document.getElementById("haha");
    if(links.length>0){
        for(var i=0;i<links.length;i++){
            xxx;
        }
    }

這樣僅一次搜索DOM樹即可實現(xiàn)相同的功能估灿。

  • 合并和放置腳本
    eg:
<script src="script/functionA.js></script>
<script src="script/functionB.js></script>
<script src="script/functionC.js></script>
<script src="script/functionD.js></script>

應(yīng)合并成一個js文件,這樣可以減少加載頁面發(fā)送的請求數(shù)量缤剧,提高性能馅袁。
而且建議把<script>標(biāo)簽放在文檔的末尾,</body>的前面荒辕,可以讓頁面變得更快汗销。

  • 壓縮腳本:把腳本文件中不必要的字節(jié),如空格和注釋都刪除抵窒。
    精簡后的代碼失去了可讀性弛针,解決方法:把壓縮前的腳本文件保存為副本,把壓縮后的腳本文件命名為xxx.min.js文件放在站點上李皇。

動態(tài)創(chuàng)建標(biāo)記

document.write

eg:document.write("< p>This is inserted.< /p>");//插入一段文本

tip:使用document.write 不能很好地將行為與表現(xiàn)分開削茁,因此應(yīng)避免使用這個方法。

innerHTML

  • 讀:eg:
    < div id="testdiv">
    < p>this id < em>my< /em>content.< /p>
    < /div>
    js:alert(document.getElementById("testdiv").innerHTML);
    結(jié)果:< p>this id < em>my< /em>content.< /p>

  • 寫:eg:
    < div id="testdiv">< /div>
    js:var testdiv=document.getElementById("testdiv");
    testdiv.innerHTML="< p>this id < em>my< /em>content.< /p>";

DOM方法

  • createElement方法和appendChild方法
    document.createElement方法創(chuàng)建一個新的元素節(jié)點掉房,但是創(chuàng)建后的節(jié)點仍然是游離的茧跋,要把它添加到DOM節(jié)點樹種。
    eg:
< div id="testdiv">< /div>
var para=document.createElement("p");<!--創(chuàng)建了一個<p>元素節(jié)點-->
var testdiv=document.getElementById("testdiv");
testdiv.appendChild(para);<!--把創(chuàng)建的節(jié)點添加為div的子節(jié)點-->
  • createTextNode方法
    eg:
< div id="testdiv">< /div>
var para=document.createElement("p");<!--創(chuàng)建了一個<p>元素節(jié)點-->
var testdiv=document.getElementById("testdiv");
var txt =document.createTextNode("hello");<!--創(chuàng)建文本節(jié)點-->
testdiv.appendChild(para);<!--把創(chuàng)建的節(jié)點添加為div的子節(jié)點-->
para.appendChid(txt);<!--將文本節(jié)點添加為p元素的子節(jié)點-->
  • insertBefore()方法
    parentElement.insertBefore(newElement,targetElement);
    新元素(newElement):你想插入的新元素
    目標(biāo)元素(targetElement):你想把新元素插入到哪個元素之前卓囚;
    父元素(parentElement):目標(biāo)元素的父元素瘾杭。
    eg:(要把一張圖片插入到ul前面)
<body>
<ul id="gallery">
<li>xxx</li>
<li>xxx</li>
</ul>
</body>

js:
var gallery=document.getElementById("gallery");
gallery.parentNode.insertBefore(placeolder,gallery);//假設(shè)placeolder是新生成的一個圖片的元素節(jié)點,則這句代碼實現(xiàn)將placeolder插入到gallery之前

  • insertAfter方法哪亿?
    沒有粥烁。
    但是可以編寫一個:
    function insertAfter(newElement,targetElement){
    var parent=targetElement.parentNode;//目標(biāo)元素的父元素
    if(parent.lastChild==targetElement){如果目標(biāo)元素是最后一個元素,要把新元素插入蝇棉,只要為父元素append一個子節(jié)點讨阻,自然就是在目標(biāo)元素的后面了;
    parent.appendChild(newElement);
    }else{//如果目標(biāo)元素不是最后一個元素银萍,那么就把新元素插在目標(biāo)元素和目標(biāo)元素后面一個元素的之間变勇,所以就是用insertBefore,插在targetElement.nextSibling之前贴唇;
    parent.insertBefore(newElement,targetElement.nextSibling);
    }
    }

className屬性

可讀可寫;
xxx.className=aClass; //aClass是一個類名飞袋。

tip: 這樣寫是替換某個元素的class屬性戳气,原來有的class屬性將被覆蓋,如果原來沒有class屬性巧鸭,則為添加class屬性瓶您。

如果只是想要增加一個class而不替換原來的class,就要:
xxx.className+=" info"; //注意:info是一個要新增加的類,前面要有一個空格呀袱,表示將原來的類名和新的類名用空格連接起來贸毕,所以就不會把原來的類替換掉。

可以先判斷原來是否已經(jīng)有類夜赵,即檢查className屬性的值是否為null明棍;
如果是,即原來沒有類寇僧,就把新的class設(shè)置值直接賦值給className屬性摊腋;
如果不是,即原來已經(jīng)存在類嘁傀,就把一個空格和新的class設(shè)置值追加到className屬性上去兴蒸。
封裝成一個函數(shù):
function addClass(element,value){//element是需要添加類的元素,value是要添加的類名
if(!element.className){//如果element的className值為null细办,即原來沒有類
element.className=value;//直接把新的類名賦值給className橙凳;
}
else{如果element的className值不為null,即原來有類
newClassName=element.className+" value";//將新舊類連接笑撞;
element.className=newClassName;
}
}

用js實現(xiàn)動畫效果

原理:讓元素的某個屬性值隨時間的變化而變化痕惋。

setTimeout

xxx=setTimeout("function",interval);//function是要執(zhí)行的函數(shù),interval是以毫秒為單位設(shè)定了需要經(jīng)過多長時間后才開始執(zhí)行函數(shù)
eg:movement=setTimeout(“moveMessage()”娃殖,5000)值戳;//5秒之后執(zhí)行moveMessage函數(shù)

  • clearTimeout(xxx)//取消要執(zhí)行的函數(shù),xxx為setTimeout函數(shù)調(diào)用返回值的變量eg:clearTimeout(movement)炉爆;

parseInt函數(shù)

可以把字符串里的數(shù)值信息提取出來堕虹。
parseInt("39 steps"); //返回數(shù)值39

由elem.style.left得到的值比如為50px,是字符串芬首,就可以通過parseInt函數(shù)來獲得數(shù)值進行計算赴捞。

待續(xù)。郁稍。赦政。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市耀怜,隨后出現(xiàn)的幾起案子恢着,更是在濱河造成了極大的恐慌,老刑警劉巖财破,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掰派,死亡現(xiàn)場離奇詭異,居然都是意外死亡左痢,警方通過查閱死者的電腦和手機靡羡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門系洛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人略步,你說我怎么就攤上這事描扯。” “怎么了趟薄?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵绽诚,是天一觀的道長。 經(jīng)常有香客問我竟趾,道長憔购,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任岔帽,我火速辦了婚禮玫鸟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘犀勒。我一直安慰自己屎飘,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布贾费。 她就那樣靜靜地躺著钦购,像睡著了一般。 火紅的嫁衣襯著肌膚如雪褂萧。 梳的紋絲不亂的頭發(fā)上押桃,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音导犹,去河邊找鬼唱凯。 笑死,一個胖子當(dāng)著我的面吹牛谎痢,可吹牛的內(nèi)容都是我干的磕昼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼节猿,長吁一口氣:“原來是場噩夢啊……” “哼票从!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起滨嘱,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤峰鄙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后九孩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體先馆,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年躺彬,在試婚紗的時候發(fā)現(xiàn)自己被綠了煤墙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡宪拥,死狀恐怖仿野,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情她君,我是刑警寧澤脚作,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站缔刹,受9級特大地震影響球涛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜校镐,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一亿扁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鸟廓,春花似錦从祝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至员咽,卻和暖如春毒涧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贝室。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工契讲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人档玻。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓怀泊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親误趴。 傳聞我的和親對象是個殘疾皇子霹琼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Learn JS NoteBook 基本概念 1.變量: (1)js的變量是松散類型的,可以用來保存任何類型的數(shù)據(jù)...
    冰鎮(zhèn)小籠包閱讀 898評論 0 20
  • 參考 學(xué)習(xí)網(wǎng)站 廖雪峰的JavaScript教程 w3cshool 阮一峰的JavaScript全棧工程師培訓(xùn)教程...
    HuangJn閱讀 333評論 0 1
  • 學(xué)習(xí)材料————廖雪峰js教程 數(shù)據(jù)類型 ===與== == 自動轉(zhuǎn)換數(shù)據(jù)類型再比較凉当;=== 不轉(zhuǎn)換類型 (更好...
    ccminn閱讀 1,757評論 0 4
  • 白帶增多是廣大女性朋友常見的一種疾病枣申,你知道白帶增多的異常癥狀有哪些?白帶增多怎么辦看杭,白帶增多又暗示那些疾仓姨佟?作者...
    天涯佳音閱讀 170評論 0 0
  • 思考一下這樣的變量聲明: const element = Hello, world! ; 上面這個好玩的標(biāo)記語法...
    編碼的哲哲閱讀 3,436評論 0 0