Javascript(十二)javascript 事件详解

一、事件定义

  1. 关于事件实际上我们已经初步接触过了,指的就是用户与浏览器交互的一瞬间。
  2. 我们通过为指定事件绑定回调函数的形式来处理事 件,当指定事件触发以后我们的回调函数就会被调用,这样我们的页面就可以完成和用户的交互了。
  3. 这里还要更加深入的聊一聊事件的其他内容。

二、事件处理程序

• 我们可以通过两种方式为一个元素绑定事件处理程序:

  1. 通过HTML元素指定事件属性来绑定
  2.  通过DOM对象指定的属性来绑定

• 这两种方式都是我们日常用的比较多的,但是更推荐使 用第二种方式。

• 还有一种方式比较特殊我们称为设置事件监听器。使用 如下方式:

-元素对象.addEventListener()

2.1、通过HTML标签的属性设置

  • 通过HTML属性来绑定事件处理程序是最简单的方式。
<button οnclick="alert('hello');alert('world')">按钮</button>
  • 这种方式当我们点击按钮以后,onclick属性中对应的JS代码将 会执行,也就是点击按钮以后,页面中会弹出两个提示框。
  • 这种方式我们直接将代码编写到了onclick属性中,可以编写多 行js代码,当然也可以事先在外部定义好函数。

  • 这种方式的优点在于,设定步骤非常简单,并且能够确保事件 处理程序会在载入时被设定。

  • 如果在函数的最后return false则会取消元素的默认行为。

2.2、通过DOM对象的属性绑定

  • 但是其实上面的写法虽然简单,但却将JS和HTML 的代码编写到了一起,并不推荐使用,我们更推荐 如下的写法:

var btn = document.getElementById('btn'); btn.onclick = function(){

      alert("hello");
   };
  • 这种写法将HTML代码和JS写在不同的位置,维护 起来更加容易。

三、设置事件的监听器

• 前边两种方式都可以绑定事件处理程序,但是它们都有一个缺 点就是都只能绑定一个程序,而不能为一个事件绑定多个程序。

• 这是我们就可以使用addEventListener()来处理,这个方法需 要两个参数:一个是事件字符串,一个是响应函数。

btn.addEventListener('click' , function(){alert("hello");});

• 但是要注意的是ie8以下的浏览器是不支持上边的方法的,需要 使用attachEvent代替。

• 也可以使用removeEventListener()和detachEvent()移除事件。

3.1、事件处理中的this

• 在事件处理程序内的 this 所引用的对象即是设定了该事件处理程序的元素。

• 也就是事件是给那个对象绑定的this就是哪个对象。

3.2、事件对象

  • 在DOM对象上的某个事件被触发时,会产生一个 事件对象Event,这个对象中包含着所有事件有关 的信息。包括导致事件的元素、事件的类型以及其 他与特定事件相关的信息。

  • 例如,鼠标操作导致的事件对象中,会包含鼠标位 置的信息,而键盘操作导致的事件对象中,会包含与按下的键有关的信息。所有浏览器都支持 event对象,但支持方式不同。

  • DOM标准的浏览器会将一个event对象传入到事件的处理程序 当中。无论事件处理程序是什么都会传入一个event对象。

  •  可以通过这种方式获取:

    btn.onclick = function(event){ alert(event.type);

    };

  •  Event对象包含与创建它的特定事件有关的属性和方法。触发 的事件类型不一样,可用的属性和方法也不一样。

3.3、Event对象的通用属性/方法

属性/方法

类型

读/写

说明

bubbles

Boolean

只读

事件是否冒泡

cancelable

Boolean

只读

是否可以取消事件的默认行为

currentTarget

Element

只读

当前正在处理的事件元素

defaultPrevented

Boolean

只读

是否调用了preventDefault()

detail

Number

只读

与事件相关的细节信息

eventPhase

Number

只读

阶段 1:捕获 2:目标 3:冒泡

preventDefault()

Function

只读

取消事件的默认行为

stopImmediatePropagation()

Function

只读

取消事件的进一步捕获或冒泡

stopPropagation()

Function

只读

取消事件的进一步捕获或冒泡

target

Element

只读

事件的目标

trusted

Boolean

只读

是否是浏览器内置事件

type

String

只读

被触发的事件的类型

3.4、IE中的事件对象

  • 与访问DOM中的event对象不同,要访问IE中 的 event 对象有几种不同的方式,取决于指定事件 处理程序的方法。

  • 在IE中event对象作为window对象的属性存在的, 可以使用window.event来获取event对象。
  • 在使用attachEvent()的情况下,也会在处理程序中 传递一个event对象,也可以按照前边的方式使用。

3.5、Event对象的通用属性/方法

属性/方法

类型

读/写

说明

cancelBubble

Boolean

读/写

是否取消冒泡

returnValue

Boolean

读/写

是否执行默认行为

srcElement

Element

只读

事件的目标

type

String

只读

被触发的事件的类型

四、事件的触发

  • 事件的发生主要是由用户操作引起的。

  • 比如mousemove这个事件就是由于用户移动鼠标引起的,在鼠标指针移动的过程中该事件会持续发生。

  • 当指定事件被触发时,浏览器就会调用对应的函数去响 应事件,一般情况下事件没触发一次,函数就会执行一 次。

  • 因此设置鼠标移动的事件可能会影响到鼠标的移动速度。 所以设置该类事件时一定要谨慎。

4.1、事件的传播

• 在网页中标签与标签之间是有嵌套关系的,比如这样一个页面:

<html> <body>

<div id="foo">
<button id="bar">sample</button>

</div> </body>

</html>

• 如果这时用户点击了sample按钮,则会以该按钮作为事件目标触发一次点击事件。

• 这时,事件的处理将会分为捕获阶段、目标阶段、事件冒泡这三个阶段。

4.2、事件的传播流程

• 捕获阶段
– 这一阶段会从window对象开始向下一直遍历到目标对象,如果发现有对象绑定了响应事件则做相应的处理。

• 目标阶段

– 这一阶段已经遍历结束,则会执行目标对象上绑定的响应函数。

• 事件冒泡阶段

– 这一阶段,事件的传播方式和捕获阶段正好相反,会从事件目标一直向 上遍历,直至window对象结束,这时对象上绑定的响应函数也会执行。

4.3、取消事件传播

• 我们可以使用event对象的两个方法完成:

– stopPropagation()
– stopImmediatePropagation()

• 取消默认行为:
– preventDefault()

五、常用简单例子

5.1、事件冒泡

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            #box1{
                width: 200px;
                height: 200px;
                background-color: yellowgreen;
            }
            #s1{
                background-color: yellow;
            }
        </style>
        <script type="text/javascript">
            window.onload = function(){
                /*
                 * 事件的冒泡(Bubble)
                 *     - 所谓的冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
                 *     - 在开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡
                 */
                //为s1绑定一个单击响应函数
                var s1 = document.getElementById("s1");
                s1.onclick = function(event){
                    event = event || window.event;
                    alert("我是span的单击响应函数");
                    //取消冒泡
                    //可以将事件对象的cancelBubble设置为true,即可取消冒泡
                    // event.cancelBubble = true;
                };
                //为box1绑定一个单击响应函数
                var box1 = document.getElementById("box1");
                box1.onclick = function(event){
                    event = event || window.event;
                    alert("我是div的单击响应函数");
                    // event.cancelBubble = true;
                };
                //为body绑定一个单击响应函数
                document.body.onclick = function(){
                    alert("我是body的单击响应函数");
                };
            };
        </script>
    </head>
    <body>
        <div id="box1">
            我是box1
            <span id="s1">我是span</span>
        </div>
    </body>
</html>

效果:

当点击子结点对象时其所有父节点都触发事件。

5.2、事件的绑定

/*
             * 参数:
             *     obj 要绑定事件的对象
             *     eventStr 事件的字符串(不要on)
             *  callback 回调函数
             */
            function bind(obj , eventStr , callback){
                if(obj.addEventListener){
                    //大部分浏览器兼容的方式
                    obj.addEventListener(eventStr , callback , false);
                }else{
                    /*
                     * this是谁由调用方式决定
                     * callback.call(obj)
                     */
                    //IE8及以下
                    obj.attachEvent("on"+eventStr , function(){
                        //在匿名函数中调用回调函数
                        callback.call(obj);
                    });
                }
            }

调用:

bind(btn01 , "click" , function(){
    alert(this);
});

5.3、事件的拖拽

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            #box1{
                width: 100px;
                height: 100px;
                background-color: red;
                position: absolute;
            }
            #box2{
                width: 100px;
                height: 100px;
                background-color: yellow;
                position: absolute;
                left: 200px;
                top: 200px;
            }
        </style>
        <script type="text/javascript">
            window.onload = function(){
                /*
                 * 拖拽box1元素
                 *  - 拖拽的流程
                 *         1.当鼠标在被拖拽元素上按下时,开始拖拽  onmousedown
                 *         2.当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove
                 *         3.当鼠标松开时,被拖拽元素固定在当前位置    onmouseup
                 */
                //获取box1
                var box1 = document.getElementById("box1");
                //为box1绑定一个鼠标按下事件
                //当鼠标在被拖拽元素上按下时,开始拖拽  onmousedown
                box1.onmousedown = function(event){
                    event = event || window.event;
                    //div的偏移量 鼠标.clentX - 元素.offsetLeft
                    //div的偏移量 鼠标.clentY - 元素.offsetTop
                    var ol = event.clientX - box1.offsetLeft;
                    var ot = event.clientY - box1.offsetTop;
                    //为document绑定一个onmousemove事件
                    document.onmousemove = function(event){
                        event = event || window.event;
                        //当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove
                        //获取鼠标的坐标
                        var left = event.clientX - ol;
                        var top = event.clientY - ot;
                        //修改box1的位置
                        box1.style.left = left+"px";
                        box1.style.top = top+"px";
                    };
                    //为document绑定一个鼠标松开事件
                    document.onmouseup = function(){
                        //当鼠标松开时,被拖拽元素固定在当前位置    onmouseup
                        //取消document的onmousemove事件
                        document.onmousemove = null;
                        //取消document的onmouseup事件
                        document.onmouseup = null;
                    };
                };
            };
        </script>
    </head>
    <body>
        <div id="box1"></div>
        <div id="box2"></div>
    </body>
</html>

效果:

鼠标按下红色方块能拖动。

5.5、滚轮事件

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            #box1{
                width: 100px;
                height: 100px;
                background-color: red;
            }
        </style>
        <script type="text/javascript">
            window.onload = function(){
                //获取id为box1的div
                var box1 = document.getElementById("box1");
                //为box1绑定一个鼠标滚轮滚动的事件
                /*
                 * onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发,
                 *     但是火狐不支持该属性
                 * 在火狐中需要使用 DOMMouseScroll 来绑定滚动事件
                 *     注意该事件需要通过addEventListener()函数来绑定
                 */
                box1.onmousewheel = function(event){
                    event = event || window.event;
                    //event.wheelDelta 可以获取鼠标滚轮滚动的方向
                    //向上滚 120   向下滚 -120
                    //wheelDelta这个值我们不看大小,只看正负
                    //alert(event.wheelDelta);
                    //wheelDelta这个属性火狐中不支持
                    //在火狐中使用event.detail来获取滚动的方向
                    //向上滚 -3  向下滚 3
                    //alert(event.detail);
                    /*
                     * 当鼠标滚轮向下滚动时,box1变长
                     *     当滚轮向上滚动时,box1变短
                     */
                    //判断鼠标滚轮滚动的方向
                    if(event.wheelDelta > 0 || event.detail < 0){
                        //向上滚,box1变短
                        box1.style.height = box1.clientHeight - 10 + "px";
                    }else{
                        //向下滚,box1变长
                        box1.style.height = box1.clientHeight + 10 + "px";
                    }
                    /*
                     * 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
                     * 需要使用event来取消默认行为event.preventDefault();
                     * 但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错
                     */
                    event.preventDefault && event.preventDefault();
                    /*
                     * 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,
                     * 这是浏览器的默认行为,如果不希望发生,则可以取消默认行为
                     */
                    return false;
                };
                //为火狐绑定滚轮事件
                bind(box1,"DOMMouseScroll",box1.onmousewheel);
            };
            function bind(obj , eventStr , callback){
                if(obj.addEventListener){
                    //大部分浏览器兼容的方式
                    obj.addEventListener(eventStr , callback , false);
                }else{
                    /*
                     * this是谁由调用方式决定
                     * callback.call(obj)
                     */
                    //IE8及以下
                    obj.attachEvent("on"+eventStr , function(){
                        //在匿名函数中调用回调函数
                        callback.call(obj);
                    });
                }
            }
        </script>
    </head>
    <body style="height: 2000px;">
        <div id="box1"></div>
    </body>
</html>

效果:

当鼠标进入红色方块,鼠标向上滚向上滚,box1变短,反之变长。当然,Mac系统正好相反。

5.6、键盘事件

/*
                 * 键盘事件:
                 *     onkeydown
                 *         - 按键被按下
                 *         - 对于onkeydown来说如果一直按着某个按键不松手,则事件会一直触发
                 *         - 当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快
                 *             这种设计是为了防止误操作的发生。
                 *     onkeyup
                 *         - 按键被松开
                 *  键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document
                 */
                document.onkeydown = function(event){
                    event = event || window.event;
                    /*
                     * 可以通过keyCode来获取按键的编码
                     *     通过它可以判断哪个按键被按下
                     * 除了keyCode,事件对象中还提供了几个属性
                     *     altKey
                     *     ctrlKey
                     *     shiftKey
                     *         - 这个三个用来判断alt ctrl 和 shift是否被按下
                     *             如果按下则返回true,否则返回false
                     */
                    //console.log(event.keyCode);
                    //判断一个y是否被按下
                    //判断y和ctrl是否同时被按下
                    if(event.keyCode === 89 && event.ctrlKey){
                        console.log("ctrl和y都被按下了");
                    }
                };

效果:

同时按下ctrl+y在控制台打印:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值