JavaScript事件对象、事件流和事件代理

1 事件对象

事件在浏览器中是以对象的形式存在的,即event。触发一个事件,就会产生一个事件对象event,该对象包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。
所有浏览器都支持event对象,但支持方式不同,在DOM中event对象必须作为唯一的参数传给事件处理函数,在IE中event是window对象的一个属性。

DOM中事件对象重要属性和方法。
属性:

  • type属性,用于获取事件类型
  • target属性 用户获取事件目标 事件加在哪个元素上。(更具体target.nodeName)

方法:

  • stopPropagation()方法 用于阻止事件冒泡
  • preventDefault()方法 阻止事件的默认行为 移动端用的多

IE中的事件对象

  • 通过DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。
  • 第二种情况:通过attachEvent()添加的事件处理程序,event对象作为参数传入。

属性:

  • type属性,用于获取事件类型(一样)
  • srcElement属性,用户获取事件目标 事件加在哪个元素上。
  • cancelBubble属性 用于阻止事件冒泡 IE中cancelBubble为属性而不是方法,true表示阻止冒泡。
  • returnValue属性 阻止事件的默认行为 false表示阻止事件的默认行为。

Event对象的一些兼容性写法:

  • 获得event对象兼容性写法
    event || (event = window.event);
  • 获得target兼容型写法
    event.target||event.srcElement
  • 阻止浏览器默认行为兼容性写法
    event.preventDefault ? event.preventDefault() : (event.returnValue = false);
  • 阻止冒泡写法
    event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);

2 事件流

事件流描述的是从页面中接收事件的顺序。事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。

事件传播的顺序对应浏览器的两种事件流模型:捕获型事件流和冒泡型事件流。
冒泡型事件流:事件的传播是从最特定的事件目标到最不特定的事件目标。即从DOM树的叶子到根。
捕获型事件流:事件的传播是从最不特定的事件目标到最特定的事件目标。即从DOM树的根到叶子。
事件捕获的思想就是不太具体的节点应该更早接收到事件,而最具体的节点最后接收到事件。
DOM标准采用捕获+冒泡。两种事件流都会触发DOM的所有对象,从document对象开始,也在document对象结束。

DOM标准规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。如图:
这里写图片描述
事件捕获阶段:实际目标(div)在捕获阶段不会接收事件。事件从document到html再到body就停止了。上图中为1~3。
处于目标阶段:事件在目标上发生并处理。但是事件处理会被看成是冒泡阶段的一部分。
冒泡阶段:事件又传播回文档。
注意:

  • 尽管“DOM2级事件”标准规范明确规定事件捕获阶段不会涉及事件目标,但是在IE9、Safari、Chrome、Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两次机会在目标对象上面操作事件。
  • 并非所有的事件都会经过冒泡阶段 。所有的事件都要经过捕获阶段和处于目标阶段,但是有些事件会跳过冒泡阶段:如,获得输入焦点的focus事件和失去输入焦点的blur事件。
    示例:
 <body>
    <div id="firstDiv">
        <div id="secondDiv">
            <button id="button1" class="clickMe">Click me</button>
        </div>
    </div>
    <script>    
        var firstDiv = document.getElementById("firstDiv"); 
        var secondDiv = document.getElementById("secondDiv");   
        var btn = document.getElementById("button1");   
        firstDiv .addEventListener('click',function(e){
            alert("firstDiv的click事件在冒泡阶段被触发,id="+this.id);
        },false);
        firstDiv .addEventListener('click',function(e){
            alert("firstDiv的click事件在捕获阶段被触发,id="+this.id);
        },true);
        secondDiv.addEventListener('click',function(e){
            alert("secondDiv的click事件在冒泡阶段被触发,id="+this.id);
        },false);
        secondDiv.addEventListener('click',function(e){
            alert("secondDiv的click事件在捕获阶段被触发,id="+this.id);
        },true);            
        btn.addEventListener('click',function(e){
            alert("button1的click事件在捕获阶段被触发,id="+this.id);
        },true);
        btn.addEventListener('click',function(e){
            alert("button1的click事件在冒泡阶段被触发,id="+this.id);
        },false);
    </script>
 </body>

虽然两次机会在目标对象上面操作事件,但其执行顺序却与代码的顺序相关,并非按照先捕获后冒泡的顺序。
这里写图片描述
这里写图片描述

3 事件处理程序##

事件就是用户或浏览器自身执行的某种动作。比如click,mouseup,keydown,mouseover等都是事件的名字。而响应某个事件的函数就叫事件处理程序(事件监听器),事件处理程序以on开头,比如click的事件处理程序就是onclick。

DOM 0级事件处理程序

DOM 0级事件处理程序:把一个函数赋值给一个事件的处理程序属性。
例如:

<input type="button" value="按钮" id="btn"/>
var oBtn=document.getElementById('btn');   //获得oBtn按钮对象
oBtn.onclick      //给oBtn添加onclick属性,属性又触发了一个事件处理程序
oBtn.onclick=function(){  }  //添加匿名函数
oBtn.onclick=null      //删除onclick属性

DOM 2级事件处理程序

DOM 2级事件定义了两个方法,用于指定和删除事件处理程序的操作。addEventListener()和removeEventListener()。需要三个参数:事件名称要分配的函数处理函数是用于冒泡阶段(false)还是捕获阶段(true),默认为冒泡阶段false。

4 事件代理

事件代理的原理用到的就是事件冒泡和目标元素,把事件处理器添加到父元素,等待子元素事件冒泡,并且父元素能够通过target(IE为srcElement)判断是哪个子元素,从而做相应处理。

示例:

<body>
<ul id="color-list">
<li>red</li>
<li>orange</li>
<li>yellow</li>
<li>green</li>
<li>blue</li>
<li>indigo</li>
<li>purple</li>
</ul>
<script>
(function(){
    var colorList=document.getElementById("color-list");
    colorList.addEventListener('click',showColor,false);
    function showColor(e)
    {
        e=e||window.event;
        var targetElement=e.target||e.srcElement;
        if(targetElement.nodeName.toLowerCase()==="li"){
        alert(targetElement.innerHTML);
        }
    }
})();
</script>
</body>

事件代理的好处

  • 将多个事件处理器减少到一个,因为事件处理器要驻留内存,这样就提高了性能。想象如果有一个100行的表格,对比传统的为每个单元格绑定事件处理器的方式和事件代理(即table上添加一个事件处理器),不难得出结论,事件代理确实避免了一些潜在的风险,提高了性能。
  • DOM更新无需重新绑定事件处理器,因为事件代理对不同子元素可采用不同处理方法。如果新增其他子元素(a,span,div等),直接修改事件代理的事件处理函数即可,不需要重新绑定处理器,不需要再次循环遍历。
MATLAB代码实现了一个基于多种智能优化算法优化RBF神经网络的回归预测模型,其核心是通过智能优化算法自动寻找最优的RBF扩展参数(spread),以提升预测精度。 1.主要功能 多算法优化RBF网络:使用多种智能优化算法优化RBF神经网络的核心参数spread。 回归预测:对输入特征进行回归预测,适用于连续值输出问题。 性能对比:对比不同优化算法在训练集测试集上的预测性能,绘制适应度曲线、预测对比图、误差指标柱状图等。 2.算法步骤 数据准备:导入数据,随机打乱,划分训练集测试集(默认7:3)。 数据归一化:使用mapminmax将输入输出归一化到[0,1]区间。 标准RBF建模:使用固定spread=100建立基准RBF模型。 智能优化循环: 调用优化算法(从指定文件夹中读取算法文件)优化spread参数。 使用优化后的spread重新训练RBF网络。 评估预测结果,保存性能指标。 结果可视化: 绘制适应度曲线、训练集/测试集预测对比图。 绘制误差指标(MAE、RMSE、MAPE、MBE)柱状图。 十种智能优化算法分别是: GWO:灰狼算法 HBA:蜜獾算法 IAO:改进天鹰优化算法,改进①:Tent混沌映射种群初始化,改进②:自适应权重 MFO:飞蛾扑火算法 MPA:海洋捕食者算法 NGO:北方苍鹰算法 OOA:鱼鹰优化算法 RTH:红尾鹰算法 WOA:鲸鱼算法 ZOA:斑马算法
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值