学习笔记-JavaScript
学习笔记-JavaScript

学习笔记-JavaScript

1.前言

因为前段时间一直在学东西,所以学习笔记一直攒着没发出来,这几天闲了一点就一起把存货发出来了。越学越发现大佬太多了,自己的路还很长,继续加油。


2.JavaScript介绍

JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式(如函数式编程)风格。

JavaScript与python类似是一种编译语言,但在结构语法上与C语言很相似,如果学过C语言会好理解一点。


3.JavaScript学习

3.1.概述与基础语法:

JavaScript是一种运行于JavaScript解释器/引擎中的解释型脚本语言
JS组成:1、核心(ECMAScript)
       2、文档对象模型(DOM),让JS有能力与网页进行对话
       3、浏览器对象模型(BOM),让JS有能力与浏览器进行对话
JS特点:1、开发工具简单,记事本即可
       2、弱类型语言,由数据来决定数据类型
       3、无需编译,直接由JS引擎负责执行
       4、面向对象
浏览器内核作用:负责页面内容的渲染。
        组成:1、内容排版引擎解析 HTML和CSS
             2、脚本解释引擎解析 Javascript
运行环境:1、在Nodejs在运行
        2、嵌入在浏览器内核中的引擎,F12打开控制台在Console中嵌入js代码
将JS脚本嵌入在HTML页面中执行的步骤:(与CSS类似)
    1、将JS代码嵌入在元素“事件”中  
       onclick:当单击元素时所做的操作
       <div id="" onclick="JS代码">xxx</div>
       <body>
            <button onclick="console.iog('Hello World');">
                             打印消息
            </button>
       </body>
    2、将代码嵌入在<script>标记中
        <script></script> 允许出现在网页的任意位置处
    3、将JS代码写在外部脚本文件中(**.js)
        1、创建js文件,并编写js代码
        2、在页面中引入js文件
            <script src="js文件路径"></script> 标签内不能出现任何内容,
           出现不会执行
语法规范:使用分号结束语句;大小写敏感;英文标点符号

3.2.变量:

定义:内存:保持程序在运行过程中,所需要用到的数据,8bit(比特是表示信息
            的最小单位)=1byte 1024byte=1KB
     变量:程序中一个已经命名的储存单位,它的主要作用就是为数据操作提供存
           放信息的容器
语法:
    var 变量名 = 值;   如果省略var关键字声明的就是全局变量
        var price = 25;    var age;age = 25;
    一次声明多个变量:
        var stuName="PP.XZ", stuAge=25, stuHeight;
变量命名:
    1.不允许使用JS的关键字和保留关键字
    2.由字母、数字、下划线以及$组成
    3.不能以数字开头
    4.尽量见名知意,如var stuName, stuAge;
    5.可以采用“驼峰命名法”,变量名为合成词时,第一个单词全小写,从第二
      个单词开始首字母大写,只有一个单词则全小写
变量使用:
    1.变量声明后要赋值,不赋值直接使用会报错,不声明直接使用也会报错
    2.获取变量的值-GET操作
        var userPwd='123456';

        console.log(userPwd);
        document.write(userPwd);
        var newPwd=userPwd;
    3.保存(设置)变量的值-SET操作
        var oldPwd='123';

        oldPwd='456';
        oldPwd=newPwd;

3.3.数据类型:

1.数字类型:
    整数:32位即4字节
        十进制:生活中常用的数字
        八进制:逢八进一  var n1=0123;
        十六进制:逢十六进一 0-9 A-F组成  var n2=0a123;
    浮点数:即小数,64位,8字节
        var n1=34.56;
        var n2=4.5e10;
2.字符串类型:
    表示一系列的文本字符数据,由Unicode字符,数字,标点组成,占2字节
        "张".charCodeAt().toString(16)
        查看字符“张”的十六进制表现方式,结果为5f20
    汉字的起始字符:\u4e00
    汉字的结束字符:\u9fa5
    转义字符:
        \n换行 \r回车 \t一个制表符
3.布尔类型:
    作用:用于表示条件的结果
    取值:true;真,肯定的结果;false:假,否定的结果;
    除条件判断外,做运算时,true可以当1运算,false当0运算
4.空:
    null:声明对象未赋值
5.未定义
    undefined:1.声明对象未赋值;2。访问对象不存在的属性
6.数据类型转换:
    弱类型由数据决定类型
        数字+数字=数字nuimber
        数字+字符=字符string
    隐式转换:
        1.typeof()或typeof
            var s = typeof(nunm1); 获取num1的数据类型
        2.NaN
            Not a Number
            isNaN(数据):判断数据是否为非数字,结果为boolean类型
                结果为true:is not a number,不是一个数字
                结果为false:not not a number,是一个数字
        所有数据类型与string做+运算时,最后结果都为字符型
    强制转换:
        1.toString():
            将任意类型的数据转换为string类型
        2.parseInt():
            获取指定数据的整数部分
            整型:Integer
                var result=parseInt(数据);
            从左向右依次转换,碰到第一个非整数字符,则停止转换。如果第一
            个字符就是非整数字符,结果为NaN
        3.parseFloat():
            Float:浮点类型->小数
            作用:将指定数据转换成小数
            语法:var result=parseFloat(数据);
                var result=parseFloat("你好35.2");//NaN
            遇到非浮点数停止转换
        4.Number():
            作用:将一个数字字符串解析为number
            语法:var result=Number(数据);
                console.log(Number('12.3'));//=>12.3
                console.log(Number('12.5px'));//=>NaN
                console.log(Number(1.5.5));//=>NaN
                console.log(Number(''));//=>0
            注意:如果包含非数字字符(不分前后),返回NaN

3.4.运算符和表达式:

算数运算符:
    +:可表示加法,也可用于字符串的连接
    -:可表示减法,也可表示一个负数
        var num1=15;
        var str1="15";
        console.log(num1+str1);//=>1515
    *和/:乘法和除法
    %:取余
        判断数字奇偶
        获取数字最后几位
    ++:自增
    --:自减
        i=1
        j=i++   //i=2,j=1
        i=1
        j=++i   //i=2,j=2
        运算优先级+不大于=,所以运算从左到右进行一式先赋值后i自增,二式
        在取得i的值前,i先做了一次自增
关系运算符:
    ==:判断等于   不比较类型,只比较数值
    ===:全等      除数据外,连同类型一起比较
    关系表达式运算结果为boolean类型,非真即假
        var input=prompt("请输入一个数据:");
        console.log(isNaN(input));
        判断输入是否为数字
逻辑运算符:
    作用:关联条件
    逻辑运算符:逻辑与:&&
                 var result=score>=60 & score<=80
                 结果为true或者false
              逻辑或:||
              逻辑非:!
                逻辑非只有一个操作数
                语法:!条件
    短路逻辑:
        1.短路&&:第一个条件结果为false则不会再判断第二个条件
                 如果第一个为true,则判断第二个条件,并且以第二个表达式
                 的值,作为整个表达式的值
        2.短路||:第一个条件为true,则不会判断第二个条件
                 如果第一个条件为false,则判断第二个条件,并且以第二个表
                 达式的值,作为整个表达式的值
    三目运算符:运算需要三个操作
        语法:表达式1?表达式2:表达式3;
            表达式1是一个条件,值为boolea类型。
            若表达式1为true,则执行表达式2的操作,以表达式2的结果作为整
            个式子的结果
            若表达式1为false,则执行表达式3的操作,以表达式3的结果作为整
            个表达式的结果
            var msg = age>18?"成年人":"未成年人";
        条件嵌套:
            var score = 85;
            var result = score >= 80? "优秀" : (
                score >= 60 ? "合格" : "不合格"
                );

3.5.函数:

定义:函数(function),也可称方法(method)或过程(procedure)
    是一段预定义好的,并且可以被反复使用的代码块。其中可以包含多条可执行
    语句
语法:
    function 函数名() {
        可执行语句;
    }
调用:执行函数中的内容,任何JS的合法位置处,都允许调用
    function judge(){
        var input = prompt("请输入一个数据:");
        var input = isNaN ?  console.log(typeof(input)) : 
        console.log("输入成功");
    }
    judge();
定义带参数的函数:
    function 函数名(参数列表声明) {
        代码块(函数体,功能体,方法体)
    }
    参数列表:由一个或多个变量名称来组成
    声明函数时定义的参数,可以称之为“形参”(调用的时候没有具体的值,只
    是一个形式参数)
    function printInfo(userName, userPwd) {
        console.log('用户名:'+userName + '密码:'+userPwd)
    }
    printInfo('Tom','123');
带返回值的函数:
    function 函数名(0或多个参数){
        //代码块;
        return值;
    }
    调用:var 变量 = 函数名(参数);
        function add(num1. num2) {
            return num1 + num2;
        }
        var result = add(10,20);
        console.log(result);
变量的作用域:
    定义:变量或函数的可访问范围。它控制着变量或函数的可见性和生命周期
        在JS中,变量或函数的作用域可分为:
            1.函数作用域,只在当前函数内可访问
            2.全局作用域,一经定义,代码的任何位置都可访问
        局部变量:
        function add(){
            var sum = 1+2;              //局部变量
            console.log(sum);           //正确
        }
        console.log(sum);               //脚本错误
        全局变量:
        var sum = 0;                    //全局变量
        function add(){
            sum = 1 + 2;
            console.log(sum);           //正确
        }
        console.log(sum);               //正确
声明提前:
    JS在正式执行前,会将所偶var声明的变量和function声明的函数,预读到所
    在作用域的顶部,但对变量的赋值还保留在原来的位置
    console.log(a);         //不会出错
    var a=100;
    console.log(a);         //100
    相当于
    var a
    console.log(a);
    a = 100;
    console.log(a);
按值传递:
    传参时,实际上是将实参复制了一份副本传给了函数。在函数体内对变量进行
    修改,实际上是不会影响到外部的实参变量的
    var n=100;                  //全局变量n
    function fun(num){            //参数变量也是全局变量
        num-=3;                   //修改的是局部变量num
        console.log(num);         //输出的是局部变量num
    }
    fun(n);                     //按值传递,方法内输出97
    console.log(n);             //输出全局变量的值:100

3.6.分支结构:

结构:
    if (条件表达式){
        语句块;
    }
流程:
    1、判断条件表达式的结果
    2、结果为true,则执行语句块的内容
       如果为false,则不执行语句块的内容
注意:1、if语句,条件位置处,必须为boolean的值/表达式/变量,如果不是
         boolean类型,JS会自动转化
        以下情况,if都会认为是false
        if(0/0.0/null/undefined/NaN){}
        除以上情况外,一律为真
        if (1) {
            console.log("真");
        }
        if ("我帅吗") {
            console.log("真!!!");
        }
     2、if后{}可以省略,省略后if只能控制第一个语句,同c语言规则相同
if-else结构:
    if (条件) {
        语句块1;
    } else {
        语句块2;
    }
if ,else if结构:
    if (条件1) {
        语句1;
    } else if (条件2) {
        语句2;
    } else if (条件3) {
        语句3;
    } else {
        语句4
    }
    最后的else可以选择性添加
switch-case:
    使用场合:优先用于等值判断的条件中
    switch case语句是一种特殊的分支结构,可以根据一个表达式的不同取值,
    从不同的程序入口开始执行
    结构:
        switch (表达式) {
            case 值1 :
                语句1;
                break;
            case 值2 :
                语句2;
                break;
            default ;
                语句3
        }
    结构过程与c语言相同
alert(): 弹出个提示框 (确定)
confirm(): 弹出个确认框 (确定,取消)
prompt(): 弹出个输入框 让你输入东西

3.7.循环结构:(同C语言相同)

while循环:
     while (boolea表达式) {
         循环操作;
     }
循环流程控制:
    1.break:用在循环中,终止整个循环结构
    2.continue:用在循环中,用于终止本次循环,继续执行下次循环
    注意:break可以在if-else中使用直接跳出当前循环。
        在多层循环中, 一个break语句只向外跳一层。
        continue语句的作用是跳过循环体中剩余的语句并到循环末尾而强行执行
        下一次循环。
        continue语句只用在for、while、do-while等循环体中, 常与if条件语句
        一起使用, 用来加速循环。
do-while循环:
    do {
        可执行语句;
    } while (boole表达式);
for循环:
    for (表达式1;表达式2;表达式3;) {
        循环语句体;
    }
    执行过程:1.计算表达式1的值
            2.计算表达式2(boole类型)的值,如果为true执行循环,否则退出循
              环
            3.执行循环体
            4.执行表达式3
            5.计算表达式2
            6.如此循环往复,直到表达式2的值为false
    for循环一般用于实现固定次数的循环
for, while, do-while之间的区别:
    1.for,while
        最少执行0次
        while:多数用于不确定循环次数时使用
        for;多数用于确定循环次数时使用
    2.do-while
        最少执行一次
        适合用于不确定循环次数时使用

3.8.数组:

1.索引数组:
    1.创建空数组:2种
        数组直接量:var arr=[];
        用new:var arr=new Array();
      var arr1 = [];        //定义一个不包含元素的数组
      var arr2 = [97,86,94];    //定义一个包含三个元素的数组
      var arr3 = new Array();   //定义一个不包含元素的数组
      var arr4 = new Array("Tom","Mary","John");    //定义一个三个字符串
                                                      元素的数组
    2.先声明空数组,再添加元素
        var empArray = [];
        empArray[0] = 'Scott';
        empArray[1] = 'Smith';

        var mArray = new Array();
        mArray[0] = '三国志';
        mArray[2] = 195;
        mArray[5] = true;   //混合元素数组
    3.访问数组中的元素
        元素:数组中每个数据都是一个元素
        访问;下标;数组中唯一标识每个元素存储位置的序列
        特点:从0开始,连续不重复
        何时:只要访问数组元素,只能用下标
    4.数组GET操作和SET操作:
        SET操作:
            var scores = [95,88,100];
            scores[2] = 98;     //将值为100的元素重新赋值为98
            scores[3] = 75;     //在数组尾部添加一个新的元素
            下标从0开始,最大到length-1
        GET操作:
            var cities = new Array('南京','杭州','青岛');
            console.log(cities[1]);     //杭州
            console.log(cities[3]);     //undefined,没有该值,不会抛出数
                                          组下标越界异常
        数组的length属性:记录了数组中理论上的元素个数,length属性的值永
                          远时最大下标+1
            var arr4 = new Array(10);
            console.log(arr4.length);       //长度为10
            var arr5 =  [];     //长度为0
            arr5[0] = 87;       //长度变为1
            arr5[3] = 98;       //长度变为4
    5.数组遍历
        var nums = [50,90,80,20];
        for ( var i=0; i<nums.length; i++ ) {
            nums[i] += 10;
            console.log(nums[i]);
        }
    6.固定套路:
        1.获得数组最后一个元素:arr[arr.length-1]
        2.获得倒数第n个元素的位置:arr[arr.length-n]
        3.数组缩容:减小arr.length的数值,会删除结尾的多余元素
        4.遍历数组:依次访问数组中每个元素,对每个元素执行相同的操作 for
                    循环
    7.特殊:三个不限制
        1.不限制数组的元素个数:长度可变
        2.不限制下标越界:
            获取元素值:不报错!返回undefined
            修改元素值:不报错!自动在指定位置创建新元素,并自动修改
                        length属性为最大下标+1
            如果下标不连续的数组--稀疏数组
        3.不限制元素的数据类型
2.关联数组:
    介绍:可自定义下标名称的数组
    步骤:创建空数组;
         向空数组中添加新元素,并自定义下标名称
    var bookInfo = [];
    bookInfo['bookName'] = '西游记';
    bookInfo['price'] = 35.5;
    关联数组的length属性无法获取其中元素的数量,遍历关联数组只能使用for 
    in循环
    for (var key in hash) {
        key     //只是元素的下标名
        hash[key]   //当前元素值
    }
对比:
    关联数组不能用字符串输出,索引数组以字符串输出
    关联数组使用for in循环遍历,索引数组使用for循环遍历
    关联数组length属性失效,索引数组可以使用length属性
    快速查找元素可以使用关联(hash)数组

3.9.数组API函数:

1.数组转字符串:
    1.String(arr):将arr中每个元素转化为字符串,用逗号分隔
        固定套路:对数组拍照,用于鉴别是否数组被修改过
    2.arr.join("连接符"):将1arr中每个元素转化为字符串,
                          用自定义的连接符分隔
        var chars=["H","e","l","l","o"];
        console.log(chars.join(""));        //输出Hello
    用处:1.将字符组成单词:chars.join("")->无缝拼接
            可判断数组是空数组:arr.join("")==""
         2.将单词组成句子:words.join("")
         3.将数组转化为页面元素的内容
            "<开始标签>"+
                arr.join("</结束标签><开始标签>")
            +"</结束标签>"
2.拼接和选取:
    不直接修改原数组,而返回新数组!
    拼接:
         concat()拼接两个或更多数组,并返回结果
         var newArr=arr1.concat(值1,值2,arr2,值3,...)
         将值和数组中每个元素接到arr1的元素之后返回新数组,
         其中arr2的元素会被先*打散*,再拼接
    选取:
        slice()返回现有数组的一个字数组
        var subArr=arr.lice(starti,endi+1)
        选组arr中starti位置开始,到endi结束的所有
        元素组成新数组返回-原数组保持不变
        强调:凡是两个参数都是下标的函数,都有一个特性:含头不含尾
        var arr1 = [10,20,30,40,50];
        var arr2 = arr1.slice(1,4);     //20,30,40
        var arr3 = arr1.slice(2);       //30,40,50
        var arr4 = arr1.slice(-4,-2);   //20,30

        console.log(arr1);              //现有数组元素不变
        选取简写:
            1.一直选取到结尾:省略第二个参数
            2.如果选取的元素离结尾近:可用倒数下标:(从-1开始计数)
                arr.slice(arr.length-n,arr.lengtg-m+1)
                可简写为:arr.slice(-n,-m+1);
            3.复制数组:
                arr.slice(0,arr.length);
                可简写为:arr.slice();
    删除:
        splice(starti,n)直接修改原数组
        删除arr中starti位置开始的n个元素不考虑含头不含尾
        其实:var deletes=arr.splice(starti,n);
        返回值deletes保存了被删除元素组成的临时数组
        var arr1 = [10,20,30,40,50];
        var arr2 = arr.splice(2,1);
        //var arr2 = arr1.splice(2,2,21,22,23);         
             在删除位置插入新元素      
        //var arr2 = arr1.splice(2,2,[91,92,93]);       
             在删除位置插入新数组
    插入:
        arr.splice(starti,0,值1,值2)
        在starti位置删除0个元素,插入新值1,2,
             原starti位置的值及其之后的值被向后顺移
        证明插入时插在starti元素之前
    替换:
        删除旧的,插入新的
        arr.splice(starti,n,值1,值2)
        删除的元素数不一定要和插入的相等
3.颠倒数组:
    颠倒:
        reverse()颠倒数组中元素的位置
        var arr1 = [10,20,30,40,50];
        arr1.reverse();
        强调:仅仅负责原样颠倒数组,不会排序
4.排序:
    排序API:
        arr.sort():默认将所有元素转化为字符串再排列
        问题:只能排列字符串类型的元素
        解决:使用自定义比较器函数
    排序算法:
        (手写)冒泡 快速 插入排序

3.10.DOM查找:

定义:DOM时W3C(万维网联盟)的标准,是中立于平台和语言的接口,它允许程序
      和脚本动态地访问和更新文档的内容和样式。对网页进行增删查改的操作
1.按id属性,精确查找以一个元素对象
    var elem=document.getElementById("id")
    getElementById只能用在document上
    只能用于精确查找一个元素,而有的元素没有id
    <ul id="mylist"></ul>
    var ul = document.getElementById("mylist");
    console.log(ul)
2.按标签名查找
    var elems=parent.getElementsByTagName("tag");
    查找指定parent节点下的所有标签为tag的子代节点
    强调:可用在任意父元素上
         不仅查直接子节点,而且查所有子代节点
         返回一个动态集合,即使只找到一个元素,也返回集合,必须用[0],
         取出唯一元素
    不足:不能直接查找,而是找所有子代
        <ul id=""mylist></ul>
        var ul = document.getElementById("menulist");
        var list = ul.getElementsByTagName('li');
        console.log(list);
3.通过name属性查找:
    document.getElementsByName('name属性')
    可以返回DOM树中具有指定name属性值的所有子元素
        <form id="registerForm">
            <input type="checkbox" name="boy"/>
            <input type="checkbox" name="boy"/>
        </form>
        var list = document.getElementsByName('boy');
        console.log(typeof list);
4.通过class查找:
    查找父元素下指定的class属性的元素
    var elems=parent.getElementsByClassName("class");
    有兼容性问题:IE9+
        var list=div.getElementsByClassNane("mainTitle");
5.通过CSS选择器查找;
    1.只找一个元素:
        var elem = parent.querySelector("selector")
        selector支持一切css中选择器
        如果选择器匹配的有多个,只返回第一个
    2.找多个:
        var elems = parent.qeurySelectorAll("selector");
        selector API返回的是非动态集合

案列:随机验证码

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Document</title>
   <style>
   #code{
      width: 100px;
      height: 50px;
      background-color: lightblue;
      font-size: 44px;
      letter-spacing: 5px;
   }
   </style>
</head>
<body>
   <script>
   function createRandCode(){
      var chars=['a','b','c','1','2','3'];
      var randcode="";
      for(var i=0;i<3;i++){//3位随机码
         var randpos =Math.floor(Math.random() * chars.length); 
         randcode+= chars[randpos];
      }
      document.getElementById("code").innerHTML=randcode;
   }
   </script>
   <div id="code"></div>
   <button onclick="createRandCode()">验证码</button>
</body>
</html>
innerHTML属性:
    innerHTML在JS是双向功能:获取对象的内容  或  向对象插入内容;
    如:<div id="aa">这是内容</div> ,
    我们可以通过  document.getElementById('aa').innerHTML 来获取id为aa的
    对象的内嵌内容;
    也可以对某对象插入内容,如
    document.getElementById('abc').innerHTML='这是被插入的内容';
    这样就能向id为abc的对象插入内容。

JavaScript floor()方法:
    floor()方法可对一个数进行下舍入
    语法:Math.floor(x)
    floor()方法执行的是向下取整计算,它返回的是小于或等于函数参数,并且
    与之最接近的整数

random方法:
    返回介于0~1之间的一个随机数
    Math.random()
    返回最大最小值间的一个数(两端包含)
        return Math.floor(Math.random() * (max - min + 1) ) + min;

3.11.DOM修改:

1.修改
    核心DOM:可操作一切结构化文档的API,包括HTML和XML,万能但繁琐
    HTML DOM:专门操作HTML文档的简化版DOM,仅仅对常用的复杂API进行了简
              化,不是万能但简单
2.修改属性:
    核心DOM的4个操作
    1.读取属性(2种):
        1.先获得属性节点对象,再获得节点对象的值:
            var arrtNode=elem.attributes[下表/属性名];
            avr arrtNode=elem.getAttributeNode(属性名);
        2.直接获得属性值:
            var value=elem.getAttribute("属性名");
    2.修改属性值:
        elem.setAttribute("属性名",value);

        var h1 = document.getElementById("a1");
        h1.setAttributeNode("name",zhangji);
    3.判断是否包含指定属性:
        var bool=elem.hasAttribute("属性名")   //ture或者false

        document.getElementById('bt1').hasAttribute('onclick')
        直接判断bt1里有没有onclick这个属性
    4.移除属性:
        elem.removeAttribute("属性名")

        <a id="alink" class="slink" href="javascript:void(0)" 
         onclick="jump()">百度搜索</a>
        var a = document.getElementById('alink');
        a.removeAttribute("class");
3.修改样式:
    内联样式:elem.style.属性名
    属性名:去横线,变驼峰
    css:background-color=>backgroundColor
        list-style-type=>istStyleType

3.12.DOM添加:

1.创建空元素:
    var elem=document.createElement("元素名")

    var table = document.createElement('table');
2.添加元素:
    1.设置关键属性
        a.innerHTML="go to tmooc"
        a.href="http://tmooc.cn";
        <a href="http://tmooc.cn">go to tmooc</a>
    2.设置关键样式
        a.style.opacity = "1";
        a.style.cssText = "width:100px;height:100px";
    3.将元素添加到DOM树
      1.
        parentNode.appendChild(childNode)
        可用于为一个父元素追加最后一个子节点(末尾添加)

        var div = document.createElement('dic');
        var txt = document.createTextNode('版权声明');

        div.appendChild(txt);
        document.body.appendChild(div);
      2.
        parentNode.insertBefore(newChild,existingChild)
        用于在父元素中的指定子节点之前添加一个新的子节点
        <ul id="menu"></ul>
        var ul = document.getElementById('menu');
        var newLi = document.createElement('li');
        ul.insertBefore(newLi, ul.lastChild);
    4.添加元素优化:
        尽量少操作DOM树,每次修改DOM树,都导致重新layout
        1.如果同时创建父元素和子元素时,建议在内存中先将子元素添加到父元
          素中,再将父元素一次挂到页面
        2.如果只添加多个平级子元素时,就要将所有子元素,临时添加到文档片
          段中。再将文档片段整体添加到页面

        文档片段:
            内存中,临时保存多个平级子元素的虚拟父元素,用法和普通父元素
            相同
            1.创建片段
                var frag=document.createDocumentFragment();
            2.将子元素临时追加到frag中
                frag.appendChild(child);
            3.将frag追加到页面
                parent.append(frag);
            append之后,frag自动释放,不会占用元素

3.13.BOM:

定义:Browser Object Model
    专门操作浏览器窗口的API--没有标准,有兼容性问题
浏览器常用对象模型:
    window:代表整个窗口
    history:代表封装当前窗口打开后,成功访问过的历史url记录
    navigator:封装浏览器的配置信息
    document:封装当前正在加载的网页内容
    location:封装了当前窗口正在打开的url地址
    screen:封装了屏幕的信息
    event:定义了网页中的事件机制
窗口大小:
    完整窗口大小:
        window.outerWidth/outerHeight
    文档显示区大小:
        window.innerWidth/innerHeight
定时器:
    定义:让程序按指定时间间隔自动执行任务,用于网页动态效果,计时功能等
    1.周期性计时器:
        让程序按指定时间间隔周期性反复自动执行一项任务
        语法:setInterval(exp,time):周期性触发代码exp
             exp:执行语句
             time:时间周期,单位为毫秒
             setInterval(function()){
                console.log("Hello World");
             }, 1000);
    2.一次性计时器:
        让程序延迟一段时间执行
        语法:setTimeout(exp,time):一次性触发代码exp
             exp:执行语句
             time:间隔时间,单位毫秒
             setTimeout(function(){
                alert("恭喜过关")
             },3000);
    3.停止计时器:
        1.给定时器取名:var timer = setInterval(function(),1000);
        2.停止计时器:clearInterval(timer);
    只要反复执行,就用周期计时器
    执行一次,用一次性计时器