JavaScript 事件

一、基本概念

0x1 事件

1、定义
事件是可以被 JavaScript 侦测到的行为,通俗的讲就是当用户与Web页面进行某些交互时,解释器就会创建响应的event对象以描述事件信息。
2、事件句柄
事件句柄(又称事件处理函数、事件监听函数),指用于响应某个事件而调用的函数。每一个事件均对应一个事件句柄,在程序执行时,将相应的函数或语句指定给事件句柄,则在该事件发生时,浏览器便执行指定的函数或语句。

0x2 事件定义

一个事件的定义必须有三部:

  • 事件对象
  • 为事件对象绑定一个事件类型
  • 事件句柄

为特定事件定义监听函数有三种方式:
(1)、直接在HTML中定义元素的事件相关属性
缺点:违反了“ 内容与行为相分离” 的原则,应尽可能少用。

<button onclick="alert('hello')">按钮</button>
<body onload="init()">...</body>

(2)、 DOM0级事件
在JavaScript中为元素的事件相关属性赋值:
缺点:此语法实现了“ 内容与行为相分离” ,但元素只能绑定一个监听函数。

<button id="myBtn">点击我</button>
<script type="text/javascript">
    var btn = document.getElementById("myBtn");
    btn.onclick = function () {
        alert('Clicked');
    }

    var btn = document.getElementById("myBtn");
    btn.onclick = function () {
        alert(this.id);
    }
</script>

(3)、 DOM2级事件
高级事件处理方式,一个事件可以绑定多个监听函数
此语法可以为一个元素绑定多个监听函数,但需要注意浏览器兼容性问题
DOM2支持同一dom元素注册多个同种事件。
DOM2新增了捕获和冒泡的概念。

btn.addEventListener("click",function(){},false); // DOM
btn.attachEvent("onclick",function(){}); // IE
document.body.addEventListener("load",init);
document.body.attachEvent("onload",init);
function init(){ //... }

Demo
var btn = document.getElementById("myBtn");
btn.addEventListener("click", function () {
    alert(this.id);
}, false);

0x3 DOM事件流

1、添加移除事件

  • addEventListener()
  • removeEventListener()
element.addEventListener(event, function, useCapture)
event : 必须。字符串,指定事件名。
function:必须。指定要事件触发时执行的函数。
useCapture:可选。布尔值,指定事件是否在捕获或冒泡阶段执行
//要想移除事件成功必须要保证addEventListener和removeEventListener里面的所有参数一致,匿名函数一般不可以

2、IE事件流

  • attachEvent()
  • detachEvent()
语法:element.attachEvent(event, function)
功能:用于向指定元素添加事件句柄
event : 必须。字符串,指定事件名,必须加“on” 前缀。
function:必须。指定要事件触发时执行的函数。

事件绑定与移除的兼容性代码

var EventUtil = {
    addHandler: function (element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = null
        }
    },
    removeHandler: function (element, type, handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent("on" + type, handler);
        } else {
            element["on" + type] = null
        }
    }
}

var btn = document.getElementById("myBtn");
var handler = function () {
    alert("Clicked");
}
EventUtil.addHandler(btn, "click", handler);
EventUtil.removeHandler(btn, "click", handler);

3、事件周期
解释器创建一个event对象后,会按如下过程将其在HTML元素间进行传播

  • 第一阶段:事件捕获,事件对象沿DOM树向下传播
  • 第二阶段:目标触发,运行事件监听函数
  • 第三阶段:事件冒泡,事件沿DOM树向上传播

事件的冒泡处理机制

<div id="parent">

    <div id="child" class="child"></div>
</div>

<ul>
    <li>item1</li>
    <li>item2</li>
    <li>item3</li>
    <li>item4</li>
    <li>item5</li>
    <li>item6</li>
</ul>
<script type="text/javascript">
    // 事件冒泡
    document.getElementById("parent").addEventListener("click", function (e) {
        alert("parent事件被触发," + this.id);
    })
    document.getElementById("child").addEventListener("click", function (e) {
        alert("child事件被触发," + this.id)
    })

    // 事件捕获
    document.getElementById("parent").addEventListener("click", function (e) {
        alert("parent事件被触发," + e.target.id);
    }, true)
    document.getElementById("child").addEventListener("click", function (e) {
        alert("child事件被触发," + e.target.id)
    }, true)

    // 看个小案例
    // 这个是利用事件冒泡
    $("ul").on("mouseover", function (e) {
        $(e.target).css("background-color", "#ddd").siblings().css("background-color", "white");
    })

    // 不利用事件捕获,貌似没有任何区别
    $("li").on("mouseover", function () {
        $(this).css("background-color", "#ddd").siblings().css("background-color", "white");
    })

    // 但是$("li")已经遍历了li,还有就是如果我们要插入一个新的li,那么还要给li重新添加事件,性能太差
    $("li").on("mouseover", function () {
        $(this).css("background-color", "#ddd").siblings().css("background-color", "white");
    })

    // 如果插入一个li
    $("ul").on("mouseover", function () {
        $("<li>item7</li>").appendTo("ul");   // item7直接具有事件,无需重新绑定事件
    })
    $("li").on("mouseover", function () {
        $("<li>item7</li>").appendTo("ul");   // item7是不具有事件的,需要重新绑定事件
    })

</script>

4、Event对象
- type:事件的类型;
- srcElement/target:事件源,就是发生事件的元素;
- cancelBubble:布尔属性,设为true的时候,将停止事件进一步起泡到包容层次的元素;(e.cancelBubble = true; 相当e.stopPropagation(););
- returnValue:布尔属性,设置为false的时候可以组织浏览器执行默认
的事件动作;(e.returnValue = false; 相当于 e.preventDefault(););

<button id="myBtn">点击我</button>
<script type="text/javascript">
    // 都含有event事件
    var btn = document.getElementById("myBtn");
    btn.onclick = function (event) {
        alert(event.type);
    }
    btn.addEventListener = function (event) {
        alert(event.type);
    }

    // target和currentTarget
    var btn = document.getElementById("myBtn");
    btn.onclick = function (event) {
        alert(event.currentTarget === this);    //true
        alert(event.target === this);           //true
    }

    document.body.onclick = function (event) {
        alert(event.currentTarget === document.body);    //true
        alert(this === document.body);              //true
        alert(event.target === document.getElementById("myBtn"));  //true
    }

    // type的作用
    var btn = document.getElementById("myBtn");
    var handler = function (event) {
        switch (event.type) {
            case "click":
                alert("Clicked");
                break;
            case "mouseover":
                event.target.style.backgroundColor = "red";
                break;
            case "mouseout":
                event.target.style.backgroundColor = "";
                break;
        }
    };
    btn.onclick = handler;
    btn.onmouseover = handler;
    btn.onmouseout = handler;

    // 阻止默认行为
    var link = document.getElementById("myLink");
    link.onclick = function (event) {
        event.preventDefault();
    }

    // 取消事件捕获或者冒泡
    var btn = document.getElementById("myBtn");
    btn.onclick = function (event) {
        alert("Clicked");
        event.stopPropagation();
    }
    document.body.onclick = function (event) {
        alert("Body clicked");
    }

    // eventPhase
    var btn = document.getElementById("myBtn");
    btn.onclick = function (event) {
        alert(event.eventPhase);    //2   事件处理程序处于目标对象上
    }

    document.body.addEventListener("click", function (event) {
        alert(event.eventPhase);     //1  捕获阶段调用的事件处理程序
    }, true);

    document.body.onclick = function (event) {
        alert(event.eventPhase);       //3  冒泡阶段调用的事件处理程序
    } 
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值