IT教程 ·

javascript中的事宜

【5min+】 对象映射只有AutoMapper?试试Mapster

一.简介

javascript中的事宜,能够明白就是在HTML文档或许浏览器中发作的一种交互操纵。

本篇文章会从以下几个点去细致引见javascript中的事宜:

>> 事宜处置惩罚程序

>> 事宜流机制

>> 事宜对象

>> 实践运用——事宜托付

二.事宜处置惩罚程序

事宜处置惩罚程序指的是处置惩罚事宜的函数,也能够称其为事宜侦听器。

所以相识事宜的第一步就是怎样去增加或许删除事宜处置惩罚程序,下面会总结几种罕见的事宜处置惩罚程序的增加/删除要领。

1.HTML事宜处置惩罚程序

HTML事宜处置惩罚程序,即直接将事宜处置惩罚程序增加在HTML元素中。

平常在代码中比较罕见,直接看示例。

<button onclick="submit()">提交</button>
<script type="text/javascript">
  function submit(){
    //事宜处置惩罚逻辑
  }
</script>

这类直接在HTML中指定事宜处置惩罚程序会有一个比较显著的瑕玷:有大概存在用户在点击按钮时,事宜处置惩罚函数submit还未剖析到,此时就会报错。

2.DOM0级事宜处置惩罚程序

DOM0级划定的事宜处置惩罚程序是在javascript中经由过程给事宜处置惩罚程序定义一个函数完成的。

<button id="submit">提交</button>
<script type="text/javascript">
  var submitEle = document.getElementById('submit');
  submitEle.onclick = function submit(){
    //事宜处置惩罚逻辑
  }
</script>

这类体式格局能够为button元素增加多个事宜处置惩罚函数,只不过只要末了一个会见效。

 

移除事宜的体式格局也比较简朴,行将事宜处置惩罚程序的值设置为null。

<button id="submit">提交</button>
<script type="text/javascript">
  var submitEle = document.getElementById('submit');
  submitEle.onclick = function submit(){
    //事宜处置惩罚逻辑
  }
  // 移除事宜
  submitELe.onclick = null;
</script>

3.DOM2级事宜处置惩罚程序

DOM2级事宜中为处置惩罚事宜新增了两个api,一个是增加事宜api:addEventListenter;一个是移除事宜api:removeEventListener。

这个两个api都能够吸收三个参数:

eventName      事宜称号

fn           事宜处置惩罚函数

booleanVal       一个布尔值,默以为false。用于指导事宜处置惩罚函数在谁人阶段实行(这个参数的作用会在事宜流机制中申明)。

api运用示例:

<button id="submit">提交</button>
<script type="text/javascript">
    var submitEle = document.getElementById('submit');
    function submit(){
        //事宜处置惩罚逻辑
    }
    // 增加事宜
    submitEle.addEventListener('click',submit);
   
    // 移除事宜
    submitEle.removeEventListener('click',submit);
    
</script>

关于这两个api的运用,我们须要注重几点。

起首第一点就是运用addEventListener能够增加多个事宜处置惩罚程序,而且事宜处置惩罚程序会依据代码增加次序顺次实行。

第二点是运用addEventListener增加的事宜处置惩罚程序,只能经由过程removeEventListener来移除。

第三个须要注重的是运用addEventListener增加事宜处置惩罚程序时,假如通报的第二个参数fn是一个匿名函数,则没法运用removeEventListener去移除。

关于第三个点中说起到的匿名函数,这个写一个简朴的示例。

<button id="submit">提交</button>
<script type="text/javascript">
    var submitEle = document.getElementById('submit');
   
    // 增加事宜
    submitEle.addEventListener('click',function(){
       console.log("这是一个匿名函数");
     
    });
   
   // 移除事宜:这类情况下运用removeEventListener是没法移除前面增加的事宜处置惩罚程序
   submitEle.removeEventListener('click',function(){

   });
    
</script>

4.IE事宜处置惩罚程序

关于IE8以及更早版本的IE浏览器来讲,它不支撑addEventListener、removeEventListener这两个api。

它支撑和这两个相似的api分别为:attachEvent和deleteEvent。

这两个api也须要吸收两个参数:

eventName     事宜称号

fn                    事宜处置惩罚函数

那话不多说,写一个示例:

<button id="submit">提交</button>
<script type="text/javascript">
    var submitEle = document.getElementById('submit');
    function submit(){
        //事宜处置惩罚逻辑
    }
    // 增加事宜
    submitEle.attachEvent('onclick',submit);
   
    // 移除事宜
    submitEle.deleteEvent('onclick',submit);
    
</script>

运用这两个api的时刻也有几个注重的处所。

第一点是api的eventName参数通报,注重是onclick而不是click

第二点就是运用attachEvent能够增加多个事宜处置惩罚程序,而且事宜处置惩罚程序会依据代码增加的相反次序顺次实行

第三点是运用attachEvent增加的事宜处置惩罚程序,只能经由过程deleteEvent来移除。

第四个须要注重的是运用attachEvent增加事宜处置惩罚程序时,假如通报的第二个参数fn是一个匿名函数,则没法运用deleteEvent去移除。

个中末了两点和addEventListener/removeEventListener这两个api用法一致。

和addEventListener/removeEventListener这两个api用法有区分的就是第一点和第二点,已用赤色标记出来,运用的时刻须要注重。

注重:IE11如今已不支撑attachEvent和deleteEvent,直接在剧本中挪用要领会报错。

 

5.通用事宜处置惩罚程序

前面引见了多种差别增加/移除事宜处置惩罚程序的体式格局。

考虑到浏览器的兼容性,我们须要有一个通用的事宜处置惩罚程序,以便我们举行疾速的项目开发。

因而,下面就写一个简朴的通用事宜处置惩罚程序。

var EventUtils = {
    //增加事宜
    addEvent: function(element, eventName, fn){
        if(element.addEventListener){
            element.addEventListener(eventName, fn, false);
        }else if(element.attachEvent){
            element.attachEvent('on' + eventName, fn)
        }else{
            element.eventName = fn;
        }
    },

    //移除事宜
    removeEvent: function(element, eventName, fn){
        if(element.removeEventListener){
            element.removeEventListener(eventName, fn, false);
        }else if (element.deleteEvent){
            element.deleteEvent('on' + eventName, fn);
        }else{
            element.eventName = null;
        }
    }
};

(这个事宜处置惩罚程序比较简朴,背面内容总结完成后会将这段代码举行补充完美。)

三.事宜流机制

关于事宜流专业的解释为:页面吸收事宜的次序。

那关于页面吸收事宜的次序,分为两种,分别是:事宜冒泡(event bubbling)和事宜捕捉(event capturing)。

1.事宜冒泡

事宜冒泡最早是IE提出来的事宜流次序。那末它指的是事宜从子元素向父元素流传。

如今我们有如许一段html文档:

javascript中的事宜 IT教程 第1张

 

当我们点击触发button元素的click事宜后,会顺次触发button元素、p元素、div元素、body元素和html元素的click事宜。

javascript中的事宜 IT教程 第2张

 

 2.事宜捕捉

事宜捕捉和事宜冒泡是相反的次序,即事宜由父元素向子元素流传。

那照样前面的那段html文档

javascript中的事宜 IT教程 第1张

关于捕捉型的事宜流,当我们触发了button的click事宜后,会顺次触发html元素、body元素、div元素、p元素和button元素的clcik事宜。

javascript中的事宜 IT教程 第4张

 

 

 

前面DOM2级的事宜处置惩罚程序中,我们引见了两个api:addEventListener和removeEventListener。

这两个api的吸收的第三个boolean参数就是用来指定事宜处置惩罚程序在谁人阶段实行。

个中false值,即指定事宜在冒泡阶段实行;相反指定true值,示意事宜在捕捉阶段实行。

而关于IE供应的两个api:attachEvent和deleteEvent,它们并不支撑第三个参数,因而IE8之前的版本只支撑事宜冒泡的机制。

四.事宜对象

当我们触发html文档中元素的某个事宜时,事宜处置惩罚程序的内部就会有一个事宜对象event发生,这个对象会包含和事宜相干的一些信息。

(下面说的事宜对象仅限于DOM0级和DOM2级事宜处置惩罚程序,IE会零丁申明)

属性/要领 范例 申明
event.type String 被触发事宜的范例。

比方触发button的click事宜,那event.type的值就为"click"。

event.target Element 本次事宜中的目的元素。

由于事宜流机制的存在,当点击button时,会依据差别的次序触发其他元素的事宜,在这个过程当中,被点击的button元素就是事宜中的目的元素。

event.currentTarget Element 本次事宜中,当前正在处置惩罚的元素。

依据事宜冒泡或许捕捉的次序处置惩罚到谁人元素的事宜,谁人元素就是当前正在处置惩罚的元素。

event.cancelable Boolean 示意是不是能够作废事宜的默许行动。

true:示意能够作废事宜的默许行动。

event.preventDefault() Function 挪用该要领能够作废事宜的默许行动,然则条件是event.cancelable的值为true。
event.bubbles Boolean 表明事宜是不是冒泡
event.stopPropagation() Function 挪用该要领能够作废事宜的下一步冒泡,但条件是event.bubbles的值为true。

   关于事宜对象event的信息,我们一个一个来实践一下。

1.event.type

<button id='btn'>点击</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function(){
    //事宜处置惩罚程序
    console.log(event.type);
}
</script>

 

javascript中的事宜 IT教程 第5张

 

 

 

2.event.target和event.currentTarget

  

<body>
    <div id='box'>
        <p id='pbox'>
            <button id='btn'>点击</button>
        </p>
    </div>
</body>
<script>
var btn = document.getElementById('btn');
btn.onclick = function(){
    //事宜处置惩罚程序
    console.log("btn click");
    console.log("event.target:");
    console.log(event.target);
    console.log("event.currentTarget");
    console.log(event.currentTarget);
}

var box = document.getElementById('box');
box.onclick = function(){
    //事宜处置惩罚程序
    console.log("box click")
    console.log("event.target:");
    console.log(event.target);
    console.log("event.currentTarget");
    console.log(event.currentTarget);
}
</script>

javascript中的事宜 IT教程 第6张

能够看到运用DOM0级体式格局增加的事宜处置惩罚程序,默许的事宜流机制是事宜冒泡。

即事宜触发次序有子元素button流传到父元素div。

那这个操纵中,我们点击的目的元素是button,因而event.target一直是button元素。

而event.currentTarget跟着事宜触发的次序一直在变化,触发到谁人元素的事宜event.currentTarget就是谁人元素。

 

3.event.cancelable和event.preventDefault

前面我们说在event.cancelable为true的条件下,能够挪用event.preventDefault来阻挠事宜的默许行动。

那什么是事宜的默许行动呢?

比方:

浏览器中单击右键,涌现浏览器默许的菜单栏选项;

点击a标签会发作跳转行动;

form表单中点击提交按钮会提交表单数据;

接下来写一个示例。

<a id='link' href='https://www.baidu.com'>跳转</a>
<script>
var link = document.getElementById('link');
link.onclick = function(){
    //事宜处置惩罚程序
    console.log("link click");
    console.log(event.cancelable);
    event.preventDefault();
}
</script>

在这个示例中,一般情况下点击"跳转"会跳转到百度首页,然则我们在a标签的onclick事宜中挪用了event.preventDefault()要领阻挠了a标签默许的跳转行动。

所以我们点击"跳转"后,只会在控制台打印"link click"和event.cancelable的值,页面并不会发作跳转行动。

javascript中的事宜 IT教程 第7张

 

4.event.bubbles和event.Propagation()

前面第2小节中关于event.target和event.currentTarget的示例,由于默许的事宜冒泡机制,致使click事宜从button元素流传到了父元素div

 

  那如今我们在事宜处置惩罚程序中挪用event.Propagation要领就可以够阻挠事宜冒泡。

<body>
    <div id='box'>
        <p id='pbox'>
            <button id='btn'>点击</button>
        </p>
    </div>
</body>
<script>
var btn = document.getElementById('btn');
btn.onclick = function(){
    //事宜处置惩罚程序
    console.log("btn click");
    console.log(event.bubbles);
    event.stopPropagation();
}

var box = document.getElementById('box');
box.onclick = function(){
    //事宜处置惩罚程序
    console.log("box click")
}
</script>

javascript中的事宜 IT教程 第8张

从结果能够看到,挪用event.stopPropagation()后,父元素的click要领已胜利被阻挠。

那这里事宜对象的信息基础就总结完了,上面的示例均运用DOM0级的事宜处置惩罚程序完成的,那实际上关于DOM2级的事宜处置惩罚程序也是实用的。

所以DOM2事宜处置惩罚程序就不写在示例。

 

5.IE中的事宜对象

IE中的事宜对象和DOM0、DOM2中的事宜对象照样有很大区分的。

它包含的属性和要领以下:

属性/要领 范例 申明
type String 被触发事宜的范例
cancelBubble Boolean 设置事宜是不是冒泡。

默许值为false,将其设置为true就可以够作废事宜冒泡。

returnValue Boolean 设置事宜的默许行动。

默许值为true,将其设置为false就可以够作废事宜的默许行动。

srcElement Element 本次事宜中的目的元素。

(同DOM1、DOM2级中的target)

IE事宜对象的这些属性和要领就不代码演示了,也比较简朴。

只是IE中运用事宜对象时,须要注重下面的几点。

(下面示例的演示,差别版本的结果运用的是IE浏览器自带的仿真东西举行的)

起首第一点是运用DOM0级增加事宜处置惩罚程序时,事宜处置惩罚程序内部的事宜对象event是作为window的一个属性存在的。

<button id='btn'>点击</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function(){
    alert(window.event == event);
    // 零丁打印window.event和event,结果均是同一个对象
    // 然则只要在IE11中alert出来的结果才是true,其他版本alert均为false
}
</script>

 

第二点就是在IE事宜处置惩罚程序内部的this不一定即是目的元素,因而在事宜处置惩罚程序内部,最好用event.srcElement来替代this。

先测试一下DOM0级事宜处置惩罚程序的结果。

<button id='btn'>点击</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function(){
    alert(this); 
    // IE8-IE11 打印 [object HTMLButtonElement]
    alert(event.srcElement);  
    // IE8-IE11 打印 [object HTMLButtonElement]
}

再测试一下attachEvent和deleteEvent这两个api(IE11已不支撑这两个api了,前面已提过)

<button id='btn'>点击</button>
<script>
var btn = document.getElementById('btn');
btn.attachEvent('onclick',function(){
    alert(this);
    // IE8-IE10 结果为 [object Window]
    alert(event.srcElement);
    // IE8-IE10 结果为 [object HTMLButtonElement]
})
</script>

关于事宜对象这里就引见完了,一全部关于IE浏览器的测试代码写下来照样有些难熬痛苦。

到这里,有关javascript中的事宜内容基础总结完了,这里呢,我们须要把前面谁人通用的事宜处置惩罚程序完美一下。

<script>
    var EventUtils = {
        // 增加事宜
        addEvent: function(element, eventName, fn){
            if(element.addEventListener){
                element.addEventListener(eventName, fn, false);
            }else if(element.attachEvent){
                element.attachEvent('on' + eventName, fn)
            }else{
                element.eventName = fn;
            }
        },

        // 移除事宜
        removeEvent: function(element, eventName, fn){
            if(element.removeEventListener){
                element.removeEventListener(eventName, fn, false);
            }else if (element.deleteEvent){
                element.deleteEvent('on' + eventName, fn);
            }else{
                element.eventName = null;
            }
        },

        // 猎取事宜对象
        getEvent: function(event){
            return event?event:window.event;
        },

        // 猎取事宜范例
        getEventType: function(event){
            return event.type;
        },

        // 猎取被实行事宜的目的元素
        getEventTarget: function(event){
            return event.target | event.srcElement;
        },

        // 禁用元素的默许行动
        preventDefault: function(event){
            if(event.preventDefault){
                event.preventDefault();
            }else{ //IE8以及更低版本
                event.returnValue = false;
            }
        },

        // 阻挠元素冒泡
        stopPropagation: function(event){
            if(event.stopPropagation){                    
                event.stopPropagation();
            }else{ //IE8以及更s低版本
                event.cancelable = true;
            }
        }
    }; 
</script>

 

五.实践运用——事宜托付

末了这一部份,主如果针对事宜冒泡的一个运用。

我们假设有如许一个场景:有一个商品列表,点击个中某一个商品,弹框显现商品标题。同时用户能够在商品列表增加商品。

如今我们完成一下这个需求。

<html>
    <head>
        <meta charset="utf-8"/>
        <title>事宜托付</title>
        <style>
            li{
                cursor: pointer;
                padding: 20px;
            }
        </style>
    </head>
    <body>
        <h1>事宜托付</h1>
        <div class='box'>
            <button onclick="add()">增加商品</button>
            <div class='list'>
                <h3>商品列表</h3>
                <ul>
                    <li>商品1</li>
                    <li>商品2</li>
                    <li>商品3</li>
                    <li>商品4</li>
                </ul>
            </div>
        </div>
        <script type="text/javascript">
            // 遍历商品列表增加点击事宜
            var liEle = document.getElementsByTagName('li');
            for(var i = 0; i<liEle.length; i++){
                var element = liEle[i];
                element.addEventListener('click', function(){
                    alert(this.innerHTML);
                })
            }

            // 增加商品
            function add(){
                var ulEle = document.getElementsByTagName('ul')[0];
                var liLength = document.getElementsByTagName('li').length;
                var newLiEle = document.createElement('li');
                newLiEle.innerHTML = "商品"+(liLength+1);
                ulEle.appendChild(newLiEle);
            }
        </script>
    </body>
</html>

我们看一下浏览器结果。

javascript中的事宜 IT教程 第9张

能够看到,轮回li元素增加的点击事宜均能够一般实行,而点击【增加商品】按钮增加的商品5,点击以后并没有click事宜,因而没有弹窗显现。

这个需求实际上能够转化为如许的运用场景:事宜增加个数不确定。

那末依据前面提说的事宜流、事宜冒泡和事宜对象,我们很轻易就可以想到解决方法:

将click事宜增加到父元素ul元素上,应用事宜冒泡和event.target完成弹窗。

这个方法我们被称为事宜托付机制。

下面我们代码完成一下。

(修正代码:27行-32行)

 1 <html>
 2     <head>
 3         <meta charset="utf-8"/>
 4         <title>事宜托付</title>
 5         <style>
 6             li{
 7                 cursor: pointer;
 8                 padding: 20px;
 9             }
10         </style>
11     </head>
12     <body>
13         <h1>事宜托付</h1>
14         <div class='box'>
15             <button onclick="add()">增加商品</button>
16             <div class='list'>
17                 <h3>商品列表</h3>
18                 <ul>
19                     <li>商品1</li>
20                     <li>商品2</li>
21                     <li>商品3</li>
22                     <li>商品4</li>
23                 </ul>
24             </div>
25         </div>
26         <script type="text/javascript">
27             // 将click事宜增加到父元素ul元素上,应用事宜冒泡和event.target完成弹窗
28             var ulEle = document.getElementsByTagName('ul')[0];
29             ulEle.addEventListener('click', function(){
30                 var target = event.target;
31                 alert(target.innerHTML);
32             })
33            
34             // 增加商品
35             function add(){
36                 var ulEle = document.getElementsByTagName('ul')[0];
37                 var liLength = document.getElementsByTagName('li').length;
38                 var newLiEle = document.createElement('li');
39                 newLiEle.innerHTML = "商品"+(liLength+1);
40                 ulEle.appendChild(newLiEle);
41             }
42         </script>
43     </body>
44 </html>

结束!!!

假如以为有效的话,点个赞勉励一下~

转载请先说明出处~

 

 

 

迎接人人扫码关注~

go微服务框架kratos学习笔记八 (kratos的依赖注入)

参与评论