zoukankan      html  css  js  c++  java
  • 前端基础:JavaScript DOM对象

    JavaScript DOM对象

    通过HTML DOM,可以访问JavaScript HTML文档的所有元素。
    一、HTML DOM(文档对象模型)
    当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。HTML DOM模型被构造为对象的树:

    通过可编程的对象模型,JavaScript获得了足够的能力来创建动态的HTML。

    • JavaScript能够改变页面中的所有HTML元素;
    • JavaScript能够改变页面中的所有HTML属性;
    • JavaScript能够改变页面中的所有CSS样式;
    • JavaScript能够对页面中的所有事件作出反应;

    二、DOM节点
    1.节点类型:HTML文档中的每个成分都是一个节点,DOM是这样规定的:

    • 整个文档是一个文档节点;
    • 每个HTML标签是一个元素节点;
    • 包含在HTML元素中的文本是文本节点;
    • 每一个HTML属性是一个属性节点;

    其中,document与element节点是重点。

    2.节点关系
    节点树中的节点彼此拥有层级关系,父(parent),子(child)和同胞(sibling)等属于用于描述这些关系。父节点拥有子节点,同级的子节点被称为同胞(兄弟或者姐妹)。

    • 在节点树中,顶端节点被称为根(root);
    • 每个节点都有父节点,除了根(它没有父节点);
    • 一个节点可以拥有任意数量的子节点;
    • 同胞是拥有相同父节点的节点;
      下图展示了部分节点树的节点关系:

    3.节点查找:有两种方式
    方式一:直接查找节点

            // 节点查找(节点也就是一个个的标签)
            document.getElementById('idname');        //按照id查找,拿到的是一个标签对象
            document.getElementsByClassName('classname');        //按照class标签去找,得到的是一个数组里存放的标签
            document.getElementsByTagName('tagname');        //通过标签名去找,拿到的也是一个数组
            var a = document.getElementsByName('yuan');         //按照name属性去找,拿到的也是一个数组
            console.log(a);
    

    length属性

        var ele = document.getElementById('div1');
        console.log(ele.length);        //返回undified
    
        var ele2 = document.getElementById('div3');
        console.log(ele2.length);        //返回undified
    
        var ele3 = document.getElementsByClassName('div2');
        console.log(ele3.length);         //返回1
    
        var ele4 = document.getElementsByTagName('p');
        console.log(ele4.length) ;        //返回1
    
        var ele5 = document.getElementsByName('haiyan');
        console.log(ele5.length); //返回1
    
        // id和name的不支持
       var div1=document.getElementById("div1");
    
        //支持;
       var ele= div1.getElementsByTagName("p");
       alert(ele.length);
        //支持
       var ele2=div1.getElementsByClassName("div2");
       alert(ele2.length);
        //不支持
       var ele3=div1.getElementById("div3");
       alert(ele3.length);
        //不支持
       var ele4=div1.getElementsByName("yuan");
       alert(ele4.length)
    

    方式二:间接查找(导航查找节点,通过某个标签的位置去查找另一个标签,这是一个导航属性)

    parentElement           // 父节点标签元素
    children                // 所有子标签
    firstElementChild       // 第一个子标签元素
    lastElementChild        // 最后一个子标签元素
    nextElementtSibling     // 下一个兄弟标签元素
    previousElementSibling  // 上一个兄弟标签元素
    
    //    方式二:导航查找
    //<div id ='div1'>
    //     <div class="div2" name = 'haiyan'>lallala</div>
    //     <div name="haiyan">lkkaakkka</div>
    //     <div id ='div3'>aaaaaaaaaaaaaa</div>
    //    <p>hrllo</p>
    //</div>
    
    //注意:1.如果是数组的话后面切记getElementsByClassName('div2')[0]
    //        2.查找元素的那些方法Elements加了s的打印的就是数组
    //    1,==================
        var ele = document.getElementsByClassName('div2')[0];
        var ele1= ele.parentElement;
        console.log(ele1)  ;//找div2标签的父亲
    //    2.===============
        var ele = document.getElementById('div1');
        var ele1 = ele.children;
        console.log(ele1) ; //找到div1下的所有的子标签
    //    3.===================
        var ele = document.getElementById('div1');
        var ele1 = ele.firstElementChild;
        console.log(ele1);  //找到div1下的第一个子标签的元素
    //    4.==================
        var ele = document.getElementById('div1');
        var ele1 = ele.lastElementChild;
        console.log(ele1);  //找到div1下的最后一个子标签的元素
    //    5.===============
        var ele = document.getElementsByName('haiyan')[0];
        var ele1 = ele.nextElementSibling;
        console.log(ele1) ; //下一个兄弟标签元素
    //    6.===============
        var ele = document.getElementsByName('haiyan')[0];
        var ele1 = ele.previousElementSibling;
        console.log(ele1)  //上一个兄弟标签元素
    

    4.节点操作
    1)创建节点

    createElement(标签名):创建一个指定名称的标签;
    
    例如:
    var tag = document.createElement("input");
    tag.setAttribute("type", "text");
    

    2)添加节点

    追加一个子节点(作为最后的子节点)
    somenode.appendChild(newnode);
    
    把增加的节点放到某个节点的前面
    somenode.inserBefore(newnode, 某个节点);
    

    3)删除节点

    removeChild():获得要删除的元素,通过父元素调用删除
    

    4)替换节点

    somenode.replaceChild(newnode, 某个节点);
    

    5)节点属性操作

    • 获取文本节点的值:innerText、innerHTML
      innerText:不管是赋值还是取值,只能识别纯文本;innerHTML:既可以识别纯文本,也可以识别标签;
    //    文本属性
    //  1.innerText:不管你是赋值还是取值,只能识别纯文本
            var a1 = document.getElementsByClassName('c2')[0];
    //        console.log(a1);
            //取值操作
            console.log(a1.innerText); //你好吗/
            console.log(a1.innerHTML); //你好吗/
            //赋值操作
            a1.innerText='Egon';
            a1.innerHTML='<a href="">hello</a>';
    
    //  2.innerHtml:既可以识别纯文本,也可以识别标签
            var b1 = document.getElementsByClassName('c2')[1];
    //        console.log(b1);
            //取值操作
            console.log(b1.innerText);
            console.log(b1.innerHTML);
            //赋值操作
            b1.innerText = 'lala';
            b1.innerHTML = '<input type="text">';
    
    • 属性(attribute)操作
      泛指所有的属性,getAttribute可以操作其他的,但是不可以操作class
        elementNode.setAttribute(name,value)    
        elementNode.getAttribute(属性名)        <-------------->elementNode.属性名(DHTML)
        elementNode.removeAttribute(“属性名”);
    
    <body><div class="c1" id="d1">DIV</div>
    <script>
        var ele = document.getElementsByClassName('c1')[0];
        ele.id='d2';//修改id
        console.log(ele);
    
    //取属性值 :
    //    方式一
        console.log(ele.getAttribute('id'));
    //    方式二
        console.log(ele.id);
    / 属性赋值
    //    方式一
        ele.setAttribute('id','d3');
        console.log(ele);
    //    方式二
        ele.id = 'd3';
        console.log(ele);
    
    • value获取当前选中的value值
      input
      select(selectIndex)
      textarea

    • 关于class的操作

    //    class属性=============
         var ele = document.getElementsByClassName('c1')[0];
         console.log(ele.className); //打印类的名字
         
         ele.classList.add('hide');
         console.log(ele); //<div class="c1 hide" id="d1">
    
         ele.classList.remove('hide');//吧添加的remove移除了
         console.log(ele)
    
    • 改变css样式
    // 如需改变 HTML 元素的样式,请使用这个语法
    document.getElementById(id).style.property=新样式
    
    下面这个例子会改变<p>元素的样式
    
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>JavaScript DOM 改变CSS样式</title>
    </head>
    <body>
     
    <p id="p1">Hello World!</p>
    <p id="p2">Hello World!</p>
    <script>
    document.getElementById("p2").style.color="blue";
    document.getElementById("p2").style.fontFamily="Arial";
    document.getElementById("p2").style.fontSize="larger";
    </script>
    <p>以上段落通过脚本修改。</p>
     
    </body>
    </html>
    

    三、DOM Event(事件)
    1.事件类型

    onclick        当用户点击某个对象时调用的事件句柄。
    ondblclick     当用户双击某个对象时调用的事件句柄。
    
    onfocus        元素获得焦点。               练习:输入框
    onblur         元素失去焦点。               应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证.
    onchange       域的内容被改变。             应用场景:通常用于表单元素,当元素内容被改变时触发.(三级联动)
    
    onkeydown      某个键盘按键被按下。          应用场景: 当用户在最后一个输入框按下回车按键时,表单提交.
    onkeypress     某个键盘按键被按下并松开。
    onkeyup        某个键盘按键被松开。
    
    onload         一张页面或一幅图像完成加载。
    
    onmousedown    鼠标按钮被按下。
    onmousemove    鼠标被移动。
    onmouseout     鼠标从某元素移开。
    onmouseover    鼠标移到某元素之上。
    onmouseleave   鼠标从元素离开
    
    onselect       文本被选中。
    onsubmit       确认按钮被点击
    

    2.绑定方式
    方式一

    <!--绑定事件的方式一-->
    <div onclick="foo(this)">div</div>
    <div class="c1">div2</div>
    <script>
        function foo(self) {
            console.log(self); //<div onclick="foo(this)" style="color: red;">
            self.style.color = 'red';
        }
    

    方式二

    //方式二
    //    事件的绑定方式2:标签对象.on事件 = function (){}
         var ele=document.getElementsByClassName("c1")[0];
         ele.onclick=function () {
            console.log(this); // this 代指: 当前触发时间的标签对象;
            this.style.fontSize="30px"
        }
    

    3.onload事件
    onload事件开发中,只给body元素加。这个事件的触发标志着页面内容被加载完成,应用场景:当有些事情我们希望页面加载完成立刻执行,就可以使用该事件(什么时候加载完,什么时候触发)

    // onload事件:基于节点操作的修改
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>节点操作</title>
        <style>
            .c1 {
                 300px;
                height: 200px;
                border: 1px solid red;
            }
        </style>
        <script>
            //如果要把script写在body的上面就可以用onload事件
            //onload什么时候加载完什么时候触发这个事件
            window.onload = function () {
                var ele_add = document.getElementsByClassName('addBtn')[0];
                var ele_del = document.getElementsByClassName('delBtn')[0];
                var ele_repleace = document.getElementsByClassName('replaceBtn')[0];
                console.log(ele_add);
                //绑定的添加节点的事件
                ele_add.onclick = function () {
                    //先创建一个标签
                    var ele_a = document.createElement('a');
                    console.log(ele_a); //<a></a>
                    ele_a.innerHTML = '点击'; //<a>点击</a>
                    ele_a.href = 'http://www.baidu.com'; //<a href='http://www.baidu.com'>点击</a>
                    //先创建一个标签
                    var ele_img = document.createElement('img');
                    ele_img.src = '1.png';
                    ele_img.width = 50;
                    ele_img.height = 50;
                    //找到父标签
                    var ele_parent = document.getElementsByClassName('c1')[0];
                    //然后添加
                    ele_parent.appendChild(ele_a);
                    ele_parent.appendChild(ele_img);
                };
                //绑定的删除节点的事件
                ele_del.onclick = function () {
                    //先获取要删除的元素
                    var ele_p = document.getElementById('p1');
                    //获取它的父元素
                    var ele_parent = document.getElementsByClassName('c1')[0];
                    //然后删除(注意是父元素删除子元素)
                    ele_parent.removeChild(ele_p)
                };
                //绑定的替换节点的事件
                ele_repleace.onclick = function () {
                    //找被替换的标签(旧标签)
                    var ele_p = document.getElementById('p2');
                    //创建一个替换后的标签(新标签)
                    var ele_img = document.createElement('img');
                    ele_img.src = '2.png';
                    ele_img.width = 100;
                    ele_img.height = 50;
                    //找到父节点
                    var ele_parent = document.getElementsByClassName('c1')[0];
                    //做替换(父节点替换子节点中的某一个节点):相当于一次删除加一次添加
                    ele_parent.replaceChild(ele_img, ele_p);
                };
                //表格绑定删除节点的事件
                var ele_dels = document.getElementsByClassName('delbtn');
                for (var i = 0; i < ele_dels.length; i++) {
                    ele_dels[i].onclick = function () {
                        //获取删除的元素
                        var ele_tr = this.parentElement.parentElement;
    //            console.log(ele_tr)
                        //找到父节点
                        var ele_tbody_parent = document.getElementById('t1');
                        //然后删除
                        ele_tbody_parent.removeChild(ele_tr)
                    }
                }
            }
        </script>
    </head>
    <body>
    <div class="c1">
        <p id="p1">年后</p>
        <p id="p2">hello</p>
    </div>
    <button class="addBtn">ADD</button>
    <button class="delBtn">DEL</button>
    <button class="replaceBtn">Replace</button>
    <ul>
        <li>创建节点:var ele_a = document.createElement('a');</li>
        <li>添加节点:ele_parent.appendChild(ele_img);</li>
        <li>删除节点:ele_parent.removeChild(ele_p);</li>
        <li>替换节点:ele_parent.replaceChild(新标签,旧标签);</li>
    </ul>
    <table border="1">
        <tbody id="t1">
        <tr>
            <td><input type="checkbox"></td>
            <td><input type="text"></td>
            <td>
                <button class="delbtn">del1</button>
            </td>
        </tr>
        <tr>
            <td><input type="checkbox"></td>
            <td><input type="text"></td>
            <td>
                <button class="delbtn">del2</button>
            </td>
        </tr>
        <tr>
            <td><input type="checkbox"></td>
            <td><input type="text"></td>
            <td>
                <button class="delbtn">del3</button>
            </td>
        </tr>
        <tr>
            <td><input type="checkbox"></td>
            <td><input type="text"></td>
            <td>
                <button class="delbtn">del4</button>
            </td>
        </tr>
        </tbody>
    </table>
    </body>
    </html>
    
    // onload实例二
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
        <script>
             /*
                  window.onload=function(){
                       var ele=document.getElementById("ppp");
                       ele.onclick=function(){
                       alert(123)
                    };
                 };
             
             */
    
    
    
              function fun() {
                  var ele=document.getElementById("ppp");
                   ele.onclick=function(){
                    alert(123)
                };
              }
    
        </script>
    </head>
    <body onload="fun()">
    
    <p id="ppp">hello p</p>
    
    </body>
    </html>
    

    4.onkeydown事件
    Event对象代表事件的状态,比如事件在其发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。事件通常与函数结合使用,函数不会再事件发生前被执行。event对象在事件发生时系统已经创建好了,并且在事件函数被调用时传给事件函数,我们获取仅仅只需要接手一下即可。比如:onkeydown,我们想知道哪个键被按下了,需要问下event对象的属性,这里就是keycode:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <input type="text" class="test">
    <input type="text" id="t1"/>
    <script>
        //测试event对象
        var ele = document.getElementsByClassName('test')[0];
    //    event :每次触发事件时所有的状态信息
    //    event.keyCode :保存着所有的状态信息
        ele.onkeydown =function (event) {
    //        onkeydown按下键盘触发的事件
            console.log(event);
            console.log(event.keyCode);
            if (event.keyCode==13){
                //按回车就会弹出
                alert(666)
            }
        }
    </script>
    <script type="text/javascript">
        var ele=document.getElementById("t1");
        ele.onkeydown=function(e){
            e=e||window.event;
            var keynum=e.keyCode;
            var keychar=String.fromCharCode(keynum);
    //        console.log(keynum); //每次键盘敲下的状态信息
    //        console.log(keychar);  //输入的字符
    //        alert(keynum);
    //        alert(keychar)  //你键盘输入的字符
        };
    </script>
    </body>
    </html>
    

    5.onsubmit事件
    当表单再提交时触发,该事件也只能给form表单使用。应用场景:在表单提交验证用户输入是否正确,如果验证失败,在该方法中,我们应该阻止表单的提交:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>onsubmit事件</title>
        <!--onsubmit事件:确定按钮被点击-->
        <!--在表单提交前验证用户输入是否正确.如果验证失败.在该方法中我们应该阻止表单的提交.-->
        <!--提交按钮本身就有一个默认事件(你点击提交的时候就会把数据发过去)-->
    
    </head>
    <body>
    <form action="" id="submit">
        <p>姓名:<input type="text" class="name"></p>
        <p>年龄:<input type="text" class="age"></p>
        <input type="submit">
    </form>
    <input type="text" class="test">
    <script>
        var ele_form = document.getElementById('submit');
        var ele_name = document.getElementsByClassName('name')[0];
        var ele_age = document.getElementsByClassName('age')[0];
        ele_form.onsubmit = function (event) {
            var username = ele_name.value;
            var age = ele_age.value;
            alert(username);
            alert(age);
            if (username=='haiyan'){
                //阻止默认事件的两种方式
    //            方式一:
    //            return false;
    //            方式二
    //            给函数给一个形参,这个形参写什么都行,一般我们写成event
                event.preventDefault() //阻止默认事件(表单的提交)
            }
        }
    </script>
    <script>
        //测试event对象
        var ele = document.getElementsByClassName('test')[0];
    //    event :每次触发事件时所有的状态信息
    //    event.keyCode :保存着所有的状态信息
        ele.onkeydown =function (event) {
    //        onkeydown按下键盘触发的事件
            console.log(event);
            console.log(event.keyCode);
            if (event.keyCode==13){
                //按回车就会弹出
                alert(666)
            }
        }
    </script>
    </body>
    </html>
    

    6.事件传播

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件传播</title>
        <style>
            .box1 {
                 300px;
                height: 300px;
                background-color: rebeccapurple;
            }
            .box2{
                 150px;
                height: 150px;
                background-color: yellow;
            }
        </style>
    </head>
    <body>
    <div class="box1">
        <div class="box2"></div>
    </div>
    <script>
        //因为盒子1是盒子2的父亲,所以当给父亲绑定一个事件,给儿子也绑定一个事件,就像
    //    继承一样,儿子会继承父亲的事件,所以现在运行的时候如果点击盒子2,会把自己的是事件和
    //    父亲的事件都执行了。所以如果只想让儿子执行自己的事件,那么就得阻止发生事件传播
        var ele1 = document.getElementsByClassName('box1')[0];
        var ele2 = document.getElementsByClassName('box2')[0];
        ele1.onclick = function () {
            alert(123)
        };
        ele2.onclick = function (event) {
            alert(456);
            console.log(event);
            console.log(event.keyCode);
            //    阻止事件传播的方式
            event.stopPropagation();
        };
    
    
    </script>
    </body>
    </html>
    

    7.search实例
    模拟placeholder属性的功能,placeholder和value的区别:

    • placeholder:只是一个提示功能,不传值;
    • value:是一个默认的值,如果输入框中不写数据时,它会将默认的数据发送出去
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模拟placeholder属性的功能</title>
    </head>
    <body>
    <input type="text" placeholder="username" id="submit">
    <input type="text" value="username" id="submit1">
    <script>
    //    var ele = document.getElementById('submit1');
        var ele = document.getElementById('submit1');
        ele.onfocus = function () {
            //先获取焦点,点击输入框就获取到焦点,光标一上去就把值设成空
            this.value=""
        };
        ele.onblur = function () {
    //        当光标不点击那个输入框的时候就失去焦点了
            //当失去焦点的时候,判断当前的那个值是不是为空,是否含有空格
    //        如果为空或者有空格,用trim()去掉空格。然后赋值为username
            if (this.value.trim()==""){
                this.value='username'
            }
        }
    </script>
    </body>
    </html>
    

    8.onchange事件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>onchange事件</title>
    </head>
    <body>
    <select name="" id="s1">
        <option value="">甘肃省</option>
        <option value="">安徽省</option>
        <option value="">湖北省</option>
    </select>
    <script>
        var ele = document.getElementById('s1');
        //下拉菜单,和你当前事件不同的时候出发事件
        ele.onchange= function () {
            alert(123)
        }
    </script>
    </body>
    </html>
    
    // 使用onchange事件实现菜单二级联动
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>二级联动</title>
    </head>
    <body>
    <select name="" id="s1">
        <option value="">请选择省份</option>
        <option value="gansu">甘肃省</option>
        <option value="hebei">河北省</option>
        <option value="henan">河南省</option>
    </select>
    <select name="" id="c1">
        <option value="city">请选择城市</option>
    </select>
    <script>
        var data = {'gansu':['兰州市','天水市','武威市'],'hebei':['保定','石家庄'],'henan':['郑州','开封']}
        var ele_select = document.getElementById('s1');
        var ele_critys = document.getElementById('c1');//父亲标签
        ele_select.onchange  =function () {
    //        alert(123)
    //        console.log(this.value)
            var ele_provice = this.value;
            var citys = data[ele_provice];
            console.log(citys);
            //要在没有添加之间清空,不然你点一次添加一次,点一次添加一次
            //方式一
    //        ele_critys.children.length=1;  //不可行。。但是原理和方式二的一样
            //方式二
    //        ele_critys.options.length = 1; //留一个,一般多的是设成0了
            for (var i =0;i<citys.length;i++) {
                //创建一个option标签
                var ele_option = document.createElement('option'); //<option></option>
                ele_option.innerHTML = citys[i];  //得到有文本的option标签
                ele_option.value = i + 1; //设置属性值
                console.log(ele_option);
                ele_critys.appendChild(ele_option);
            }
        }
    </script>
    
    </body>
    </html>
    

    9.onmouse事件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>onmouse事件</title>
        <style>
            .box{
                 300%;
                height: 200px;
            }
            .title{
                background: steelblue;
                line-height: 40px;
            }
            .con{
                background: slategray;
                line-height: 30px;
            }
            .hide{
                display: none;
            }
        </style>
    </head>
    <body>
    <div class="box">
        <div class="title">onmouse</div>
        <div class="con hide">
            <div><a href="" class="item">你好吗?</a></div>
            <div><a href="" class="item">我好啊</a></div>
            <div><a href="" class="item">好就好呗</a></div>
        </div>
    </div>
    <script>
        var ele_title = document.getElementsByClassName('title')[0];
        var ele_box = document.getElementsByClassName('box')[0];
        //鼠标指上去的事件
        ele_title.onmouseover = function () {
            this.nextElementSibling.classList.remove('hide');
        };
        //鼠标移走的事件的两种方式
    //    方式一(推荐)
         ele_box.onmouseleave= function () {
            ele_title.nextElementSibling.classList.add('hide');
        };
    //    方式二
    //    ele_title.onmouseout = function () {
    //       this.nextElementSibling.classList.add('hide');
    //    }
    //    方式一和方式二的区别:
    //    不同点
    //      onmouseout:不论鼠标指针离开被选元素还是任何子元素,都会触发onmouseout事件
    //      onmouseleave:只有在鼠标指针离开被选元素时,才会触发onmouseleave事件
    //    相同点:都是鼠标移走触发事件
    </script>
    </body>
    </html>
    

    10.事件委派

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件委派(委派给所有的子元素)</title>
    </head>
    <body>
    <ul>
        <li>111</li>
        <li>222</li>
        <li>333</li>
    </ul>
    <button class="addbtn">点我添加</button>
    </body>
    <script>
        var ele_btn = document.getElementsByClassName('addbtn')[0];
        var ele_ul = document.getElementsByTagName('ul')[0];
        var ele_li =document.getElementsByTagName('li');
        //绑定事件
        for (var i=0;i<ele_li.length;i++){
            ele_li[i].onclick = function () {
                alert(this.innerHTML)
            }
        }
    
        //事件委派
        ele_btn.onclick = function () {
            //创建一个li标签
            var ele_li = document.createElement('li');
    //        ele_li.innerHTML= 444;
            ele_li.innerText = Math.round(Math.random()*1000);
            ele_ul.appendChild(ele_li);//吧创建的li标签添加到ul标签
            ele_ul.addEventListener('click',function (e) {
                console.log(e.target); //当前点击的标签
                console.log(e.target.tagName);//拿到标签的名字  LI
                if (e.target.tagName=='LI'){
                    console.log('ok');
    //                alert(ele_li.innerHTML)
                }
            })
        }
    </script>
    </html>
    

    四、节点操作
    前面我们知道了JavaScript的属性操作,接下来了解一下节点操作,很重要!
    创建节点:var ele= document.createElement("newnode");
    增加节点:ele_parent.appendChild(ele_other);
    删除节点:ele_parent.removeChild(ele_p);
    替换节点:ele_parent.replaceChild(新标签,就标签);

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>节点操作</title>
        <style>
            .c1 {
                 300px;
                height: 200px;
                border: 1px solid red;
            }
        </style>
    </head>
    <body>
    <div class="c1">
        <p id="p1">年后</p>
        <p id="p2">hello</p>
    </div>
    <button class="addBtn">ADD</button>
    <button class="delBtn">DEL</button>
    <button class="replaceBtn">Replace</button>
    <ul>
        <li>创建节点:var ele_a = document.createElement('a');</li>
        <li>添加节点:ele_parent.appendChild(ele_img);</li>
        <li>删除节点:ele_parent.removeChild(ele_p);</li>
        <li>替换节点:ele_parent.replaceChild(新标签,旧标签);</li>
    </ul>
    <table border="1">
        <tbody id="t1">
            <tr>
                <td><input type="checkbox"></td>
                <td><input type="text"></td>
                <td><button class="delbtn">del1</button></td>
            </tr>
            <tr>
                <td><input type="checkbox"></td>
                <td><input type="text"></td>
                <td><button class="delbtn">del2</button></td>
            </tr>
            <tr>
                <td><input type="checkbox"></td>
                <td><input type="text"></td>
                <td><button class="delbtn">del3</button></td>
            </tr>
            <tr>
                <td><input type="checkbox"></td>
                <td><input type="text"></td>
                <td><button class="delbtn">del4</button></td>
            </tr>
        </tbody>
    </table>
    <script>
        var ele_add = document.getElementsByClassName('addBtn')[0];
        var ele_del = document.getElementsByClassName('delBtn')[0];
        var ele_repleace = document.getElementsByClassName('replaceBtn')[0];
        console.log(ele_add);
        //绑定的添加节点的事件
        ele_add.onclick = function () {
            //先创建一个标签
            var ele_a = document.createElement('a');
            console.log(ele_a); //<a></a>
            ele_a.innerHTML = '点击'; //<a>点击</a>
            ele_a.href = 'http://www.baidu.com'; //<a href='http://www.baidu.com'>点击</a>
            //先创建一个标签
            var ele_img = document.createElement('img');
            ele_img.src = '1.png';
            ele_img.width = 50;
            ele_img.height = 50;
            //找到父标签
            var ele_parent = document.getElementsByClassName('c1')[0];
            //然后添加
            ele_parent.appendChild(ele_a);
            ele_parent.appendChild(ele_img);
        };
        //绑定的删除节点的事件
        ele_del.onclick = function () {
            //先获取要删除的元素
            var ele_p = document.getElementById('p1');
            //获取它的父元素
            var ele_parent = document.getElementsByClassName('c1')[0];
            //然后删除(注意是父元素删除子元素)
            ele_parent.removeChild(ele_p)
        };
        //绑定的替换节点的事件
        ele_repleace.onclick = function () {
            //找被替换的标签(旧标签)
            var ele_p = document.getElementById('p2');
            //创建一个替换后的标签(新标签)
            var ele_img = document.createElement('img');
            ele_img.src = '2.png';
            ele_img.width = 100;
            ele_img.height = 50;
            //找到父节点
            var ele_parent = document.getElementsByClassName('c1')[0];
            //做替换(父节点替换子节点中的某一个节点):相当于一次删除加一次添加
            ele_parent.replaceChild(ele_img, ele_p);
        }
    </script>
    <script>
        //绑定删除节点的事件
        var ele_dels = document.getElementsByClassName('delbtn');
        for(var i=0;i<ele_dels.length;i++){
            ele_dels[i].onclick = function () {
                //获取删除的元素
                var ele_tr = this.parentElement.parentElement;
    //            console.log(ele_tr)
                //找到父节点
                var ele_tbody_parent =document.getElementById('t1');
                //然后删除
                ele_tbody_parent.removeChild(ele_tr)
            }
        }
    </script>
    </body>
    </html>
    

    五、JavaScript DOM总结
    1.JavaScript中for循环遍历,for循环遍历有两种:

    • 有条件遍历,例如:for(var i=0;i<ele.length;i++){}
    • for(var ele in ele_list){}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <script>
        var arr = [11,22,33,44,55];
        var obj = {'username':'zzz','agr':20};          //js中的这个类似字典的不叫字典,而是一个对象
        for (var i in obj){
            console.log(i);          //拿到的是键
            console.log(obj[i]);        //值
        }
        for (var j in arr){
            console.log(j);         //拿到索引
            console.log(arr[j]);          //拿到值
        }
    </script>
    </body>
    </html>
    

    2.获取value属性值

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>获取value值</title>
    </head>
    <body>
    <input type="text" id="c1">
    <select name="pro" id="s1">
            <option value="1">河北省</option>
            <option value="2">河南省</option>
            <option value="3">北京省</option>
    </select>
    <button>show</button>
    <script>
         var ele_button=document.getElementsByTagName("button")[0];
    
        ele_button.onclick=function () {
            var ele_input=document.getElementById("c1");
            var ele_select=document.getElementById("s1");
            console.log(ele_select.value)
        };
    </script>
    </body>
    </html>
    

    3.表格示例(全选,反选,取消)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>表格示例</title>
    </head>
    <body>
    <button class="select">全选</button>
    <button class="reserve">反选</button>
    <button class="cancel">取消</button>
    <table border="1">
        <tr>
            <td><input type="checkbox" class="check"></td>
            <td>111</td>
            <td>222</td>
            <td>333</td>
        </tr>
         <tr>
            <td><input type="checkbox" class="check"></td>
            <td>111</td>
            <td>222</td>
             <td>333</td>
        </tr>
         <tr>
            <td><input type="checkbox" class="check"></td>
            <td>111</td>
            <td>222</td>
             <td>333</td>
        </tr>
         <tr>
            <td><input type="checkbox" class="check"></td>
            <td>111</td>
            <td>222</td>
            <td>333</td>
        </tr>
    </table>
    <script>
    //    方式一:分别给每个button增加事件
        var ele_select = document.getElementsByClassName('select')[0];
        var ele_reserve = document.getElementsByClassName('reserve')[0];
        var ele_cancel = document.getElementsByClassName('cancel')[0];
        var ele_input = document.getElementsByClassName('check');
        //全选
        ele_select.onclick = function () {
            for (var i = 0; i < ele_input.length; i++) {
                //添加一个checked属性
                ele_input[i].checked = 'checked'
            }
        };
        //取消
        ele_cancel.onclick = function () {
             for (var i =0;i<ele_input.length;i++){
                //删除checked属性,直接设置为空就行了
                ele_input[i].checked = ''
            }
        };
        //反选
        ele_reserve.onclick = function () {
            for (var i = 0; i < ele_input.length; i++) {
                var ele = ele_input[i];
                if (ele.checked) {//如果选中了就设置checked为空
                    ele.checked = '';
                }
                else {//如果没有就设置checked = checked
                    ele.checked = 'checked';
                }
             }
        };
    
    
    
    
        //方式二:方式一的优化循环增加事件
    //    var ele_button = document.getElementsByTagName('button');
    //    var ele_input = document.getElementsByClassName('check');
    //    for(var i=0;i<ele_button.length;i++) {
    //        ele_button[i].onclick = function () {
    //            if (this.innerHTML == '全选') {
    //                for (var i = 0; i < ele_input.length; i++) {
    //                    //添加一个checked属性
    //                    ele_input[i].checked = 'checked'
    //                }
    //            }
    //            else if (this.innerHTML == '取消') {
    //                for (var i = 0; i < ele_input.length; i++) {
    //                    //删除checked属性,直接设置为空就行了
    //                    ele_input[i].checked = ''
    //                }
    //            }
    //            else {
    //                for (var i = 0; i < ele_input.length; i++) {
    //                    var ele = ele_input[i];
    //                    if (ele.checked) {//如果选中了就设置checked为空
    //                        ele.checked = '';
    //                    }
    //                    else {//如果没有就设置checked = checked
    //                        ele.checked = 'checked';
    //                    }
    //                }
    //            }
    //        }
    //    }
    
    
    </script>
    </body>
    </html>
    

    4.模态对话框

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .back{
                background-color: white;
                height: 2000px;
            }
    
            .shade{
                position: fixed;
                top: 0;
                bottom: 0;
                left:0;
                right: 0;
                background-color: grey;
                opacity: 0.4;
            }
    
            .hide{
                display: none;
            }
    
            .models{
                position: fixed;
                top: 50%;
                left: 50%;
                margin-left: -100px;
                margin-top: -100px;
                height: 200px;
                 200px;
                background-color: wheat;
    
            }
        </style>
    </head>
    <body>
    <div class="back">
        <input class="c" type="button" value="click">
    </div>
    
    <div class="shade hide handles"></div>
    
    <div class="models hide handles">
        <input class="c" type="button" value="cancel">
    </div>
    
    
    <script>
    
    
        var eles=document.getElementsByClassName("c");
        var handles=document.getElementsByClassName("handles");
        for(var i=0;i<eles.length;i++){
            eles[i].onclick=function(){
    
                if(this.value=="click"){
    
                    for(var j=0;j<handles.length;j++){
    
                        handles[j].classList.remove("hide");
    
                     }
    
                }
                else {
                    for(var j=0;j<handles.length;j++){
    
                        handles[j].classList.add("hide");
                    }
    
                }
            }
        }
    
    </script>
    
    </body>
    </html>
    

    5.搜索框

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模拟placeholder属性的功能</title>
    </head>
    <body>
    <input type="text" placeholder="username" id="submit">
    <input type="text" value="username" id="submit1">
    <script>
    //    var ele = document.getElementById('submit1');
        var ele = document.getElementById('submit1');
        ele.onfocus = function () {
            //先获取焦点,点击输入框就获取到焦点,光标一上去就把值设成空
            this.value=""
        };
        ele.onblur = function () {
    //        当光标不点击那个输入框的时候就失去焦点了
            //当失去焦点的时候,判断当前的那个值是不是为空,是否含有空格
    //        如果为空或者有空格,用trim()去掉空格。然后赋值为username
            if (this.value.trim()==""){
                this.value='username'
            }
        }
    </script>
    </body>
    </html>
    

    6.tab切换

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>tab</title>
      <style>
        *{margin:0; padding:0; list-style:none;}
        body{
            font-family: "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei", "9ED14F53", Arial, sans-serif;
        }
        h3{
            text-align: center;
            color:darkcyan;
            margin-top: 30px;
            letter-spacing: 5px;
        }
        .box{
           1000px;
          margin:50px auto 0px;
        }
        #title{
          line-height: 40px;
          background-color: rgb(247,247,247);
          font-size: 16px;
          font-weight: bold;
          color: rgb(102,102,102);
        }
        #title span{
          float: left;
           166px;
          text-align: center;
        }
        #title span:hover{
          /*color: black;*/
          cursor: pointer;
        }
        #content{
          margin-top: 20px;
        }
        #content li{
           1050px;
          display: none;
          background-color: rgb(247,247,247);
        }
        #content li div{
           156px;
          margin-right: 14px;
          float: left;
          text-align: center;
        }
        #content li div a{
          font-size: 14px;
          color: black;
          line-height: 14px;
        /*  float: left;*/
        display: inline-block;
          margin-top: 10px;
        }
        #content li a:hover{
          color: #B70606;
        }
        #content li div span{
            font-size: 16px;
            line-height: 16px;
            /*float: left;*/
            display: block;
            color: rgb(102,102,102);
            margin-top: 10px;
          }
        #content img{
          float: left;
           155px;
          height: 250px;
        }
        #title .select{
          background-color: #2459a2;
          color: white;
            border-radius: 10%;
        }
        #content .show{
          display: block;
        }
    
        .show span{
            color: red!important;
            font-size: 30px;
        }
      </style>
    </head>
    
    <body>
        <h3 id="wel">京东商城欢迎您</h3>
        <!--  direction="right up down left" -->
    <!--  behavior:滚动方式(包括3个值:scroll、slide、alternate) -->
    <!--  说明:scroll:循环滚动,默认效果;slide:只滚动一次就停止;alternate:来回交替进行滚动。 -->
    <!--  scrollamount="5" 滚动速度 -->
    
    <marquee behavior="scroll" direction="right">欢迎海燕来访</marquee>
        <script>
    
        function test(){
    
            var mywel = document.getElementById("wel");
            var content = mywel.innerText;
    
            var f_content = content.charAt(0);
            var l_content = content.substring(1,content.length);
    
            var new_content = l_content + f_content;
            mywel.innerText = new_content;
    
        }
    
        // setInterval("test();", 500);
    </script>
        <div class="box">
          <p id="title">
            <span class="select">家用电器</span>
            <span>家具</span>
            <span>汽车</span>
            <span>食品</span>
            <span>女鞋</span>
            <span>医疗保健</span>
          </p>
    
          <ul id="content">
            <li class="show">
    
              <div><img src="https://img10.360buyimg.com/n1/s450x450_jfs/t4786/325/2470647304/119102/9e1a4ed5/59005841Nd786a8df.jpg" alt="冰箱"><a href="#">容声(Ronshen)冰箱</a><span>价格:5600</span></div>
              <div><img src="https://img12.360buyimg.com/n1/s450x450_jfs/t3037/347/1290968859/201366/7c1028a0/57c00194N9d0a54c6.jpg" alt="洗衣机"><a href="#">海尔洗衣机</a><span>价格:5400</span></div>
              <div><img src="https://img11.360buyimg.com/n1/jfs/t3289/128/2393835119/236360/af1d283b/57e0f300N53dde603.jpg" alt="电饭煲"><a href="#">福库(CUCKOO)电饭煲</a><span>价格:3999</span></div>
              <div><img src="https://img13.360buyimg.com/n1/jfs/t3235/137/2361713777/152258/a6908440/57e098c2N44a90a5d.jpg" alt="智能电视"><a href="#">三星智能电视</a><span>价格:8999</span></div>
              <div><img src="https://img10.360buyimg.com/n1/jfs/t2053/101/1391591157/215066/572e131b/5696ee9bN2376492d.jpg" alt="净水器"><a href="#">净水器</a><span>价格:1300</span></div>
              <div><img src="https://img14.360buyimg.com/n1/jfs/t3175/78/2357430273/262835/9a8e7f65/57e0a3e9Nbda39dd2.jpg" alt="空气净化器"><a href="#">空气净化器</a><span>价格:5300</span></div>
            </li>
    
            <li>
    
              <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>
              <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>
              <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>
              <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>
              <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>
              <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>
    
            </li>
            <li>
              <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
              <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
              <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
              <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
              <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
              <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
            </li>
            <li>
    
              <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>
              <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>
              <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>
              <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>
              <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>
              <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>
    
            </li>
            <li>
    
              <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>
              <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>
              <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>
              <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>
              <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>
              <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>
    
            </li>
            <li>
    
              <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>
              <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>
              <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>
              <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>
              <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>
              <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>
    
            </li>
    
    
          </ul>
        </div>
    
        <script>
          var title=document.getElementById('title');
          var content=document.getElementById('content');
          var category=title.getElementsByTagName('span');
          var item=content.getElementsByTagName('li');
    
          for (var i = 0; i < category.length; i++) {
    
              category[i].index=i;
    
              category[i].onclick=function(){
    
                for (var j = 0; j < category.length; j++) {
                  category[j].className='';
                  item[j].className='';
                }
                this.className='select';
                item[this.index].className='show';
              }
    
    
          }
    
        </script>
    </body>
    </html>
    

    7.作用域链

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>作用链域</title>
    </head>
    <body>
    <script>
        var s = 12;
        function f() {
            console.log(s); //undefined
            var s=12;
            console.log(s);//12
        }
        f();
    </script>
    </body>
    </html>
    

    8.JavaScript 作用域
    任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。

    • 全局作用域(Global Scope)

    在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作用域:(1)最外层函数和在最外层函数外定义的变量拥有全局作用域

    var name="yuan";
    
        function foo(){
            var age=23;
            function inner(){
                console.log(age);
            }
    
            inner();
        }
    
        console.log(name);    // yuan
        //console.log(age);   // Uncaught ReferenceError: age is not defined
        foo();                // 23
        inner();              // Uncaught ReferenceError: inner is not defined
    

    (2)所有未定义直接赋值的变量自动声明为拥有全局作用域

    var name="yuan";
    
        function foo(){
            age=23;
    
            var sex="male"
        }
        foo();
        console.log(age);   //  23
        console.log(sex);   // sex is not defined
    

    变量age拥有全局作用域,而sex在函数外部无法访问到。
    (3)所有window对象的属性拥有全局作用域
    一般情况下,window对象的内置属性都拥有全局作用域,例如:window.alert(),window.location,window.top等。

    • 局部作用域(Local Scope)
      和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所以在某些地方这种作用域被称为函数作用域。

    • 作用域链(Scope Chain)
      在JavaScript中,函数也是对象,实际上JavaScript中一切都是对象。函数对象和其他对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是Scope,由ECMA-262标准定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

    //-----**********************例1*********************************
    
    var s=12;
        function f(){
            console.log(s);
             var s=12;          // if s=12
            console.log(s)
        }
        f();
    
    //-----**********************例2*********************************
    
    var s=10;
    function foo(){
      console.log(s);
      var s=5;
      console.log(s);
      function s(){console.log("ok")}// 函数的定于或声明是在词法分析时完成的,执行时已不再有任何操作
    
      console.log(s);
    }
    
    foo();
    
    //-----***********************例3********************************
    
    function bar(age) {
    
            console.log(age);
            var age = 99;
            var sex= 'male';
            console.log(age);
            function age() {
                alert(123)
            };
            console.log(age);
            return 100;
    }
    
    result=bar(5);
    
    //-----********************************************************
    

    结果分析
    这里我们以例3来分析整个过程:当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充。在函数bar创建时,它的作用域链中会填入一个全局对象,该全局对象包含了所有全局变量,如下图:

    解析到函数调用时,即bar(5),会生成一个active object的对象,该对象包含了函数所有的局部变量、命名参数、参数集合以及this,然后此对象会被推入作用域链的顶端,当运行期上下文被销毁,活动对象也随之销毁。新的作用域链如下图:

    过程解析:

    function bar(age) {
    
            console.log(age);
            var age = 99;
            var sex="male";
            console.log(age);
            function age(){
                alert(123);
            } ;
            console.log(age);
            return 100;
    }
    
    result=bar(5);
    
    一 词法分析过程(涉及参数,局部变量声明,函数声明表达式):
        1-1 、分析参数,有一个参数,形成一个 AO.age=undefine;
        1-2 、接收参数 AO.age=5;
        1-3 、分析变量声明,有一个 var age, 发现 AO 上面有一个 AO.age ,则不做任何处理
        1-4 、分析变量声明,有一个 var sex,形成一个 AO.sex=undefine;
        1-5 、分析函数声明,有一个 function age(){} 声明, 则把原有的 age 覆盖成 AO.age=function(){};
    二 执行过程:
        2-1 、执行第一个 console.log(age) 时,当前的 AO.age 是一个函数,所以输出的一个函数
        2-2 、这句 var age=99; 是对不 AO.age 的属性赋值, AO.age=99 ,所以在第二个输出的age是 99;
        2-3 、同理第三个输出的是 99, 因为中间没有改变 age 值的语句了。
    
              注意:执行阶段:
                            function age(){
                                alert(123)
                            } ;
    
                不进行任何操作,将执行语句复制给age这部操作是在词法分析时,即运行前完成的。
    
  • 相关阅读:
    在IIS上搭建WebSocket服务器(三)
    在IIS上搭建WebSocket服务器(二)
    在IIS上搭建WebSocket服务器(一)
    RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->Web版本模块管理界面新增模块排序功能
    C#在WinForm中使用WebKit传递js对象实现与网页交互的方法
    c#用webkit内核支持html5
    .NET下WebBrowser的一个BUG以及其替代品——geckofx
    HTML5浏览器嵌入窗口程序解决方案
    saprk里面的action
    解释为什么word2vec也被称作deep learning
  • 原文地址:https://www.cnblogs.com/love9527/p/9120923.html
Copyright © 2011-2022 走看看