70-77

Dom事件操作

之前讲过的onclick,onblur,onfocus都属于事件操作

行为、内容、样式分离

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <style>
        #test{
            background-color: red;
            width: 300px;
            height: 400px;
        }
    </style>

</head>
<body>
    <div id="test">
        abcd
    </div>

    <script>
        var mydiv = document.getElementById("test");
        mydiv.onclick = function () {
            console.log("123456");
        }
    </script>

</body>
</html>

代码:可以看到内容是一块, 内容的样式(style)是一块, 内容的行为(script)是一块, 都是相分离的,编写前端的标准就应该使用分离的方式编写。

JS中的鼠标聚焦操作

  • 方法1
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table border="1" width="300px">
        <tr onmouseover="t1(0);" onmouseout="t2(0);"><td>1</td><td>2</td><td>3</td></tr>
        <tr onmouseover="t1(1);" onmouseout="t2(1);"><td>1</td><td>2</td><td>3</td></tr>
        <tr onmouseover="t1(2);" onmouseout="t2(2);"><td>1</td><td>2</td><td>3</td></tr>
    </table>

    <script>
        function t1(n) {
            var myTrs = document.getElementsByTagName("tr")[n];
            myTrs.style.backgroundColor = "red";
        }

        function t2(n) {
            var myTrs = document.getElementsByTagName("tr")[n];
            myTrs.style.backgroundColor = "";
        }

    </script>

</body>
</html>

代码说明
onmouseover:当鼠标聚焦在tr标签上时会调用t1这个函数,且会将0、1、2参数传给函数;
t1函数:通过TagName调用tr标签,并根据[n]来获取tr标签的下标,下标0表示第一个tr标签;
t1函数中会让背景颜色变成红色。
onmouseout:当鼠标离开tr标签时会调用t2函数;
t2函数:会将背景颜色清空。

enter description here

enter description here

上2图:当鼠标聚焦在哪一个tr标签上时,背景颜色就会变成红色,鼠标离开时就清空颜色。

  • 方法2
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table border="1" width="300px">
    <tr><td>1</td><td>2</td><td>3</td></tr>
    <tr><td>1</td><td>2</td><td>3</td></tr>
    <tr><td>1</td><td>2</td><td>3</td></tr>
</table>

<script>
    var myTrs = document.getElementsByTagName("tr");
    var len = myTrs.length;
    for(var i=0;i<len;i++){
        myTrs[i].onmouseover = function () {
            this.style.backgroundColor = "red";
        };

        myTrs[i].onmouseout = function () {
            this.style.backgroundColor = "";
        }
    }
</script>

</body>
</html>

代码说明
myTrs获取所有tr标签。
len获取myTrs长度。
通过for循环调用函数。
this表示谁调用当前这个函数,这个this就表示是谁; 当前是myTrs这个标签调用function这个匿名函数,所以这个this表示鼠标所触发的myTrs标签; 这里为什么不能直接使用myTrs[i]呢,这是因为当代码执行过后因为for循环,当前的i等于下标2,此时无论我们鼠标放在哪里这个i都是2,不能达到我们触发标签的效果,而使用this可以触发当前鼠标所在标签并将其背景色改为红色。

在实际中项目一般使用方法2的方式,这个方式做到了内容、行为、样式分离。

同一事件,多个绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <style>
        #test{
            background-color: red;
            width: 300px;
            height: 400px;
        }
    </style>

</head>
<body>
<div id="test">
    abcd
</div>

<script>
    var mydiv = document.getElementById("test");

    mydiv.addEventListener("click",function () {
        console.log('aaa')
    },false);

    mydiv.addEventListener("click",function () {
        console.log('bbb')
    },false);

</script>

</body>
</html>

代码
通过使用addEventListener可以多同一个事件,多次绑定。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <style>
        #main{
            background-color: red;
            width: 300px;
            height: 400px;
        }
        #content{
            background-color: pink;
            width: 150px;
            height: 200px;
        }
    </style>

</head>
<body>

    <div id="main">
        <div id="content"></div>
    </div>

    <script>
        var mymain = document.getElementById("main");
        var mycontent = document.getElementById("content");
        mymain.addEventListener("click",function () {
            console.log("main");
        },false);
        mycontent.addEventListener("click",function () {
            console.log("content");
        },false);

    </script>

</body>
</html>

代码说明
false表示从下到上显示行为事件;默认等于false。

enter description here

上图:点击粉色部分,相当于同时点击了content标签和main标签; 在代码中正常应该从上到下执行,但是如果是false的话就从下到上执行,如果是true的话就是从上到下执行。

jS词法分析解析

先来看个常见的面试题如下:

var a = 10;
function test(){
    alert(a);  //undefined
    var a = 20;
    alert(a); //20
}
test();

疑问: 为什么呢?test()执行时,虽然a=20没有赋值,但是父级作用域里是有a=10的,不应该是undefined呀,js是按顺序执行的,此时的var num = 20;根本没有执行,所以应该是10!!你是不是也是这么认为的,就和我当初一样???

分析: 众所周知,js代码是自上而下执行的,JavaScript并不是传统的块级作用域,而是函数作用域。JavaScript引擎会在代码执行前进行词法分析,所以事实上,js运行分为此法分析和执行两个阶段。

JavaScript代码运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤:

  • 分析参数

  • 再分析变量的声明

  • 分析函数声明

具体步骤如下:

函数在运行的瞬间,生成一个活动对象(Active Object),简称AO

第一步:分析参数:

1.函数接收形式参数,添加到AO的属性,并且这个时候值为undefined,即AO.name=undefined

2.接收实参,添加到AO的属性,覆盖之前的undefined

第二步:分析变量声明: 如var name;或var name='mary';

1.如果上一步分析参数中AO还没有name属性,则添加AO属性为undefined,即AO.name=undefined

2.如果AO上面已经有name属性了,则不作任何修改

第三步:分析函数的声明:

如果有function name(){}把函数赋给AO.name ,覆盖上一步分析的值

分析下面这个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<script>
    var a = 10;
    function test(a){
        console.log(a);           //function a (){}
        var a = 20;
        console.log(a);           //20
        function a (){}
        console.log(a);           //20
    }

    test(100);

</script>

</body>
</html>

enter description here

词法分析:

第一步,分析函数参数:

 形式参数:AO.a = undefined
 接收实参:AO.a = 100

第二步,分析局部变量:

第4行代码有var a,但是此时已有AO.a = 100,所以不做任何修改,即AO.a = 100

第三步,分析函数声明:

第6行代码有函数a,则将function a(){}赋给AO.a,即AO.a = function a(){}

执行代码时:

第3行代码运行时拿到的a时词法分析后的AO.a,即AO.a = function a(){};
第4行代码:将20赋值给a,此时a=20;
第5行代码运行时a已经被赋值为20,结果20;
第6行代码是一个函数表达式,所以不做任何操作;
第7行代码运行时仍是20;

举例:

var a = 10;
function test(a){
    var a;               //证明词法分析第二步。
    alert(a);           //100
    a = 20;
    alert(a);           //20
}
test(100);

举例:

var a = 10;
function test(a){
    alert(a);         //100
    var a = 20;
    alert(a);         //20
    a = function(){}        //是赋值,只有在执行时才有效
    alert(a);         //function(){}
}
test(100);

举例:

var a = 10;
function test(a){
    alert(a);                //100
    var a = 20;
    alert(a);                //20
    var a = function(){}        //是赋值,只有在执行时才有效
    alert(a);                //function(){}
}
test(100);

补充说明:函数声明与函数表达式

//函数声明
function a(){
}
//函数表达式
var b = function(){
}

a和b在词法分析时,区别:

a在词法分析时,就发挥作用;
b只有在执行阶段,才发挥作用。

猜你喜欢

转载自blog.51cto.com/daimalaobing/2445615
77
70
今日推荐