事件 订阅
事件,读音是shì jiàn,汉语词语,意思是事情、事项。 展开全文
事件,读音是shì jiàn,汉语词语,意思是事情、事项。
信息
外文名
event
拼    音
shì jiàn
中文名
事件
解    释
事情、事项
事件解释
收起全文
精华内容
参与话题
问答
  • JavaScript 事件

    2020-01-21 16:29:54
    事件作用2. 鼠标事件3. 滚轮事件4. 键盘事件5. 资源事件6. window 事件 1. 事件作用 JavaScript 通过事件检测用户行为 2. 鼠标事件 onclick: 点击鼠标左键触发 onmousedown:鼠标任意键按住时触发 onmouseup:...

    1. 事件作用

    JavaScript 通过事件检测用户行为

    2. 鼠标事件
    • onclick: 点击鼠标左键触发

    • oncontextmenu: 点击鼠标右键触发

    • ondblclink: 左键双击

    • onmousedown:鼠标任意键按住时触发

    • onmouseup: 鼠标任意键抬起时触发

    • onmouseenter:鼠标进去元素时触发

    • onmousemove:鼠标在元素上移动触发

    • onmouseleave: 鼠标离开元素触发

      onclick = onmousedown + onmouseup

    触发:

    box.click() // 触发点击事件
    input.select()   // input文本选中
    ... 
    
    3. 滚轮事件
    • onmousewheel: 鼠标滚轮在元素上滚动触发

    event参数最最重要的事就event.wheelDelta属性,表示滚动的方向。这是浏览器的规定:

    鼠标往上滚, 120

    鼠标往下滚, -120

    4. 键盘事件(document)
    • onkeydown: 按住键盘上任意键触发
    • onkeyup: 按键抬起触发
    • onkeypress : 输入键触发,功能键不触发
      可编辑盒子使用键盘事件(表单或者通过contenteditable属性使容器处于可编辑状态)
      https://blog.csdn.net/gklcsdn/article/details/108687646
      或者使用document.onkeydown 使用键盘事件

    按键码:
    event.keyCode 左上右下键 对应的keyCode 为37,38,39,40
    Enter键对应的keyCode` 为13

    6. window 事件
    • onresize: 窗口大小改变时触发
    • onscroll: 页面滚动时触发
    • onload: 页面或者图片加载完成时触发
    • onerror: 页面加载错误后触发
    7. 表单事件
    • onfocus : 获取焦点后
    • onblur : 失去焦点
    • onchange: 内容发生改变
    • oninput : 实时改变刷新
    • onreset : 重置后
    • onselect : 选择后
    • onsubmit : 提交后
    8. dom 0级事件绑定
    oBox.onclick = function(){
    	...
    }
    /*===================================*/
    oBox.onclick = fn;
    
    function fn(){}
    
    9. dom 0级绑定事件处理函数次数

    返回后一个事件绑定的值;打印2

    oBox.onclick = function(){
    	console.log(1)
    }
    
    oBox.onclick = function(){
    	console.log(2)
    }
    
    10. 解除事件绑定
    oBox.onclick = null;
    
    // 使用
    oBox.onclick = function(){
    	console.log(1);
    	this.onclick = null;
    }
    
    /*=============================*/
    
    var bol = true;
    oBox.onclick = function(){
    	if(!bol) return;
    	console.log(1);
    	bol = false;
    }
    
    11. 点击事件的对应和排他
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            
            ul {
                list-style: none;
            }
            
            ul {
                width: 500px;
                height: 100px;
                border: 2px solid black;
                margin: 10px 10px;
                display: flex;
                justify-content: space-around;
            }
            
            li {
                width: 100px;
                height: 100px;
                background-color: pink;
                text-align: center;
                line-height: 100px;
            }
        </style>
    </head>
    
    <body>
        <ul id="wrap1">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
        <ul id="wrap2">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
    
        <script>
            var oUl1Li = document.querySelectorAll('#wrap1 li');
            var oUl2Li = document.querySelectorAll('#wrap2 li');
            // 信号量控制点击的li
            var num = 0;
            for (let i = 0; i < oUl1Li.length; i++) {
                oUl1Li[i].onclick = function() {
                    oUl2Li[num].style.backgroundColor = 'pink';
                    num = i;
                    oUl2Li[num].style.backgroundColor = 'green';
                }
            }
        </script>
    </body>
    
    </html>
    

    在这里插入图片描述

    12. Dom 2级事件绑定

    三个参数:事件、函数、是否监听捕获阶段。

    第1个参数: clickmouseovermouseout

    第2个参数:函数可以是匿名函数,也可以是有名函数

    第3个参数:布尔值(默认false,可以省略),true表示监听捕获、false表示监听冒泡阶段

    oBox.addEventListener("click", function(){
        consloe.log(1);
    }, false)
    

    this 指向box

    dom 0级事件只能绑定一个;
    dom 2级事件可以绑定多个

    // 不会覆盖,11,22 都会打印
    oBox.addEventListener("click", function(){
        alert(11);
    }, false);
    
    oBox.addEventListener("click", function(){
        alert(22);
    }, false);
    
    13. dom 2级事件绑定解绑
    oBox.addEventListener("click", fn, false);
    
    // 解绑通过有名函数
    oBox.removeEventListener("click",fn, false);
    function fn(){
        alert("哈哈");
    }
    
    14. 事件处理模型

    当一个dom节点触发事件后,该事件会按照HTML结构在根节点和这个元素节点之间传播,路径上所有的节点都会收到该事件

    事件流就是当你单击了某个元素,单击事件不仅仅发生在这个元素上,你也单击了它的父元素、父元素的父元素、……它的祖先元素,甚至单击了整个页面。

    冒泡:子级向父级 执行顺序
    捕获: 父级向子级

    15. dom 0级事件绑定(捕获 冒泡)

    oDiv.onclick = function(){
    }

    dom 0级事件绑定 只能监听冒泡过程(子级向父级)

    在这里插入图片描述

            wrap1.onclick = function() {
                console.log(1)
            }
            wrap2.onclick = function() {
                console.log(2)
            }
            wrap3.onclick = function() {
                console.log(3)
            }
    

    点击box3 打印 321

    15. dom 2级事件绑定(捕获 冒泡)

    oBox.addEventListener(“click”,function(){

    },false);

    第1个参数:事件名不用写on, click、mouseover 、mouseout

    第2个参数:函数可以是匿名函数,也可以是有名函数

    第3个参数:布尔值,true表示监听捕获、false表示监听冒泡阶段

    在这里插入图片描述

            wrap1.addEventListener('click', function() {
                console.log(1);
            }, false)
            wrap2.addEventListener('click', function() {
                console.log(2);
            }, false)
            wrap3.addEventListener('click', function() {
                console.log(3);
            }, false)
    
            wrap1.addEventListener('click', function() {
                console.log("a");
            }, true)
            wrap2.addEventListener('click', function() {
                console.log("b");
            }, true)
            wrap3.addEventListener('click', function() {
                console.log('c');
            }, true)
    

    点击box3 打印 ab3c21

    先执行捕获阶段再执行冒泡阶段;
    事件源box3只有冒泡阶段,谁在前面先执行谁

    1. DOM 0级的方式,只能监听冒泡阶段。不能有同名的事件,会覆盖。
      • this是触发事件的这个元素。
      • 高版本浏览器会冒泡到window,
      • 低版本浏览器冒泡到document。
    2. DOM 2级的方法,addEventListener()
      • 可以自由设置冒泡、捕获。第三个参数: true就是捕获,false就是冒泡。
      • 事件名不加on,可以有同名事件,会顺序执行,不覆盖。
      • this是触发事件的这个元素。
      • 事件会冒泡到window。
    16. 事件对象

    任何的事件处理函数,我们的浏览器、JS引擎会默认往里面传一个实参,就是事件对象。

    通常用形参event来接收:

    oDiv.onclick = function(event){
    	console.log(event);
    }
    

    1. 通用事件对象属性和方法

    1. event.type 返回事件的类型,没有on, 比如”click”

    2. event.target 返回点击的元素

    3. event.currentTarget 返回自己,this一定和event.currentTarget是一个元素

    4. event.button 区分左键0,中间1,右键2

    5. 阻止冒泡

      event.stopPropagation();   // 停止传播事件流
      
    6. 阻止默认事件

      右键出菜单 图片拖动 a标签跳转 表单提交这些网页的默认事件

      preventDefault() 阻止默认事件

      //阻止右键事件(默认事件)
      oBox.oncontextmenu = function(ev){
           ev.preventDefault();
      }
      
      event.preventDefault();
      

    2. 事件对象上储存的常用信息

    clientX/clientY 鼠标距离浏览器左上角的水平/竖直距离
    pageX/pageY 鼠标距离页面左上角的水平/竖直距离
    offsetX/offsetY 鼠标距离触发事件的元素左上角的水平/竖直距离
    layerX/layerY 鼠标距离定位元素左上角的水平/竖直距离
    screenX/screenY 鼠标距离计算机屏幕左上角的水平/竖直距离

    17. 事件委托

    利用事件冒泡的原理把子级的事件委托给祖先元素,然后通过事件源确定,事件发生在那个子元素上

    然后给对应的子元素添加响应的处理程序

    优点:

    不需要循环绑定每个子元素,可以节约浏览器性能
    添加新的子元素时,不需要再给新元素绑定事件

    在这里插入图片描述

         wrap.onclick = function(event) {
             event.target.style.backgroundColor = 'blueviolet';
             if (event.target.nodeName == 'LI') {
                 event.target.style.backgroundColor = 'red';
             }
         }
    
    展开全文
  • 事件

    2020-06-17 22:37:19
    事件 事件就是交互事件,用户点击实现回馈,是交互体验的核心功能。 绑定事件处理函数 ele.onxxxx = function(event){} 兼容性很好,但是一个元素的同一事件上只能绑定一个 基本等同于写在HTML行间上 obj....

    事件

    事件就是交互事件,用户点击实现回馈,是交互体验的核心功能。

    绑定事件处理函数

    1. ele.onxxxx = function(event){}
      兼容性很好,但是一个元素的同一事件上只能绑定一个
      基本等同于写在HTML行间上
    2. obj.addEventListener(type,fn,false)
      IE9一下不兼容,可以为一个事件绑定多个处理程序
    3. obj.attachEvent(‘on’ + type, fn);
      IE独有,一个事件同样可以绑定多个处理程序

    事件处理程序的运行环境

    1. ele.onxxx = function (event){}
      程序this指向是dom元素本身。
      //谁点击,this就指向它。
    2. obj.addEventListener(type,fn,false);
      程序this指向是dom元素本身
    3. obj.attachEvent(‘on’ + type, fn);
      程序this指向window

    给一个对象封装一个事件处理函数

    function addEvent(elem , type, handle){
        if(elem.addEventListener){
            elem.addEventListener(type,handle,false)
        }else if(elem.attachEvent){
            elem.attachEvent('on' + type, function(){
                handle.call(elem)
            })
        }else{
            elem['on' + type] = handle;
        }
    }
    

    解除事件处理程序

    1. ele.onclick = false/’’/null;
    2. ele.removeEventListener(type, fn, false);
    3. ele.detachEvent(‘on’ + type, fn)
      注意:若绑定匿名函数,则无法解除绑定

    事件处理模型,事件冒泡、捕获

    事件冒泡:

    1. 结构上(非视觉上)嵌套关系的元素,会存在事件冒泡功能,即同一事件,自子元素冒泡向父元素。(自底向上)

    事件捕获

    1. 结构上(非视觉上)嵌套关系的元素,会存在事件捕获功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)
    2. IE没有捕获事件

    触发顺序,先捕获,后冒泡

    不会触发冒泡事件的方法

    1. focus
    2. blur
    3. change
    4. submit
    5. rest
    6. select

    取消冒泡和阻止默认事件

    取消冒泡

    1. W3C标准event.stopPropagation(),不支持IE9以下版本
    2. IE独有的,event.cancaleBubble = true;
    3. 封装取消冒泡的函数stopBubble(event)
    function stopBubble(event){
        if(event.stopPropagation){
            event.stopPropagation();
        }else{
            event.cancelBubble = true;
        }
    }
    

    阻止默认事件

    1. 默认事件—表单提交,a标签跳转,右键菜单等
    2. return false;以对象属性的方式注册的时间才生效
    3. Event.preventDefault();W3C标准,IE9以下不兼容
    4. event.returnValue = false;兼容IE
    5. 封装阻止默认事件的函数 cancelHandler(event)
    function canceHandler(event){
        if(event.preventDefault){
            event.preventDefaule();
        }else{
            event.returnValue = false;
        }
    }
    

    事件对象

    1. event || window.event 用于IE
    2. 事件源对象:
      event.target 火狐只有这个
      event.srcElement IE只有这个
      谷歌浏览器都有
    3. 兼容性写法,方法
    ele.onclick = function(e){
        var event = e || window.event;
        var target = event.target || event.srcElement;
    }
    
    

    事件委托

    利用事件冒泡,和事件源对象进行处理

    优点:

    1. 性能不需要循环所有的元素一个个绑定事件
    2. 灵活,当有新的子元素时不需要重新绑定事件

    鼠标事件

    click
    鼠标点击之后
    mousedown
    鼠标按键事件
    mousemove
    鼠标移动事件
    mouseup
    区分鼠标按键
    contextmenu
    右键菜单事件
    mouseover
    鼠标放入区域
    mouseout
    鼠标离开区域
    mouseenter
    鼠标放入区域
    mouseleave
    鼠标离开区域

    用button来区分鼠标的按键,0/1/2
    DOM3标准规定:click事件只能监听左键,只能通过mousedown和mouseup来判断鼠标键
    解决mousedown和click的冲突

    键盘事件

    1. keydown
      按下键盘触发
    2. keyup
      松开键盘触发
    3. keypress
      按住连续触发
      keydown>keyoress>keyup
    4. keydown 和 keypress的区别
    5. keydown 可以响应任意键盘按键,keypress只可以响应字符类键盘按键
    6. keypress返回ASCLL码,可以转换成相应字符。
    7. oninput监测输入框输入事件
    8. onchange输入框聚焦输入再离开的时候触发
    9. onfouce当聚焦的时候触发
    10. onscroll鼠标滚动条滚动触发
    11. onload当文档解析完之后所有页面全部渲染完之后再触发
    展开全文
  • C#中的事件

    千次阅读 2018-12-18 22:33:30
    C#中的事件其实就是C#中委托的一个属性,使用事件是为了防止委托中的参数被随意调用和修改,是出于安全性考虑。 event 还限定了 delegate 只能在定义的类中被调用。 using System; namespace Lesson26_2 { //...

    C#中的事件其实就是C#中委托的一个属性,使用事件是为了防止委托中的参数被随意调用和修改,是出于安全性考虑。

    event 还限定了 delegate 只能在定义的类中被调用。

    using System;
    
    namespace Lesson26_2
    {
    	//事件 - event 就是 delegate 的属性
    	//处于安全性的考虑
    	/// <summary>
    	/// 1.事件event 和 delegate 的关系就像字段和属性的关系
    	/// 2.event 会限制 delegate 不能够直接进行赋值操作,防止将委托替换掉,只能使用 += 和 -= 来绑定或者解除绑定
    	/// 3.event 还限定了 delegate 只能在定义的类中被调用
    	/// </summary>
    	//定义委托
    	public delegate void Something (string name);
    
    	public class Student  {
    		public string name;
    		//事件 - 使用了事件之后就不能直接给委托赋值,必须使用 += 和 -= 来解除绑定
    
    		public event Something something;
     
    		public Student (string name){
    			this.name = name;
    		}
    
    		public void Do (){
    			something (name);
    		}
    	}
    
    	public class Teacher{
    		public void Hungry (){
    			Student s = new Student ("dzzhyk");
    			//现在通过s中的something方法来直接赋值
    			s.something += new Something (A);
    			//使用了 event 之后就不能在Student的外部调用something
    			//s.something ("nihao");
    			s.Do ();
    		}
    		public void A (string name){
    			Console.WriteLine ("Hello!" + name);
    		}
    	}
    	class MainClass
    	{
    		public static void Main (string[] args)
    		{
    			Teacher t = new Teacher ();
    			t.Hungry ();
    		}
    	}
    }
    

     

    展开全文
  • 深入浅出话事件(上)

    万次阅读 多人点赞 2006-06-19 11:04:00
    深入浅出话事件(上)小序 在上篇文章(《深入浅出话委托》)中,我们集中讨论了什么是委托以及委托的用法。有朋友问:什么时候用委托——说实话,使用某种编程要素是一种思想,更是一种习惯。举个极端点的例子:...

    深入浅出话事件(上)

    小序

             在上篇文章(《深入浅出话委托》)中,我们集中讨论了什么是委托以及委托的用法。有朋友问:什么时候用委托——说实话,使用某种编程要素是一种思想,更是一种习惯。举个极端点的例子:比如你问我“什么时候使用for循环”,我完全可以回答——根本用不着for循环,用ifgoto就完全能够搞定——我们大多数人使用for循环,是因为我们认同for循环的思想,并且养成了使用for循环的习惯。委托也是这样——没有委托的日子,程序员们一样在干活,只是有了委托机制后,大家干起来更方便、写出的代码质量更高——当你体验到它的方便、自然而然地使用它、养成一种习惯后,你就知道什么时候应该使用它了。OK,我们回到正题上来,委托最常用的一个领域是用来声明“事件”,或者说:委托是事件的基础。作为《深入浅出话委托》的姊妹篇,本文我们主要来讨论事件(Event)。

    正文

    一.什么是事件

             程序语言是对人类语言的抽象,因此,程序语言要素往往与人类语言中对应的词汇有着相近的含义。正是这种“相近”,让很多要素看上去很好懂,但如果不仔细理解,就会误入歧途。“事件”就是这类要素中的一个,让我们小心对待。

    现实世界中的事件

             先让我们看一看现实世界中的“事件”。

             现实世界中的“事件”(Event)是指“有一定社会意义或影响的大事情”。 提取一下句子的二级主干,我们可以得出:事件=有意义或影响的事情。因此,我们可以看出,判定是否为一个“事件”有两个先决条件:首先它要是一个“事情”,然后这个事情还要“有意义或影响”。

             接着,我们进一步分析“事情”这个概念。我们常说“一件事情发生了”,这个“发生”组成要素又无外乎时间、地点、参与人物(主体)、所涉及的客体——抽象一点,我们可以把这些要素称为“事情”的参数

             一件事情发生了,可能对某些客体(Client)产生影响,也可能没有任何影响。如果事情发生了、并对客体产生了影响,这时候,我们就应该拿出影响这一影响的办法来

    举个例子:大楼的火警响了(火警鸣响这一事件发生),它产生的影响是让楼内的所有人员都听到了警报声,楼内的人纷纷拿出自己响应这一影响的方法来——普通职员们飞奔出大楼,而消防人员却向相反的方向跑,冲向最危险的火场。我们把这种套路称为“事件响应机制”,用于响应事件所造成的影响而采取的行动简称为“事件响应方法”。特别注意:员工逃跑和消防员冲向火场都是对警号鸣响这一事件的响应方法,而非事件所产生的影响。

    对了,还有个小问题:火警响了,我们为什么会跑呢?呵呵,答案很简单——因为我们时刻关心着警报会不会响这个事件

             OK,非常感谢你能把上面的文字读完——初中语文老师的水平完全可以决定一个学生以后是不是能成为一名合格的程序员。

    .NET Framework 中事件的概念

             下面让我们再来看看C#中“事件”(Event)是什么,并且是如何与现实世界中的事件概念相对应。

    1.          MSDNevent关键字的解释:
    Events are used on classes and structs to notify objects of occurrences that may affect their state.
    事件被用在类和结构体上,用处是通知某些对象——这些对象的状态有可能被事件的发生所影响。

    2.          MSDNEvent的解释:
    An event is a way for a class to provide notifications when something of interest happens.
    事件,是当某些被关注的事情发生时类提供通知的一种途径。

    3.          C# Spec中对Event成员的解释:
    An event is a member that enables an object or class to provide notifications. Clients can attach executable code for events by supplying event handlers.
    事件是一种类成员,它使得对象或类能够提供通知。客户端(被通知的对象/类)可以为事件附加上一些可执行代码来响应事件,这些可执行代码称为“事件处理器”(Event Handlers)。

    4.          我自己的解释:
    Events is a kind of member of class and structs, and it is a way for class and structs who own the events to notify objects who cares these events and provides the event handlers when these events fire.

             事件是类和结构体的一种成员。当事件发生时,“事件”是一种拥有此事件的类/结构体通知关心(或者称为“订阅”)这些事件、并提供事件处理器的对象的一种途径。

     

     

    干说没啥意思,下面我还是给出相应的代码,带领大家体验一下什么是事件、事件是怎么声明的、事件如何被其它类“订阅”、订阅了事件的类又是如何响应(处理)事件的。

     

    我们就以大楼火警为例,给出下面的代码:

    //=============水之真谛============
    //
    //        http://blog.csdn.net/FantasiaX
    //
    //=========
    上善若水,润物无声==========
    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace EventSample
    {
        //
    委托是事件的基础,是通知的发送方与接收方双方共同遵守的"约定"
        delegate void FireAlarmDelegate();

        //
    大楼(类)
        class Building
        {
            //
    声明事件:事件以委托为基础
            public event FireAlarmDelegate FireAlarmRing;
           
            //
    大楼失火,引发火警鸣响事件
            public void OnFire()
            {
                this.FireAlarmRing();
            }
        }

        //
    员工(类)
        class Employee
        {
            //
    这是员工对火警事件的响应,即员工的Event handler。注意与委托的匹配。
            public void RunAway()
            {
                Console.WriteLine("Running awary...");
            }
        }

        //
    消防员(类)
        class Fireman
        {
            //
    这是消防员对火警事件的响应,即消防员的Event handler。注意与委托的匹配。
            public void RushIntoFire()
            {
                Console.WriteLine("Fighting with fire...");
            }
        }

        class Program
        {
            static void Main(string[] args)
            {
                Building sigma = new Building();
                Employee employee = new Employee();
                Fireman fireman = new Fireman();

                //
    事件的影响者"订阅"事件,开始关心这个事件发生没发生
                sigma.FireAlarmRing+=new FireAlarmDelegate(employee.RunAway);
                sigma.FireAlarmRing += new FireAlarmDelegate(fireman.RushIntoFire);

                //
    由你来放火!
                Console.WriteLine("Please input 'FIRE' to fire the building...");
                string str = Console.ReadLine();
                if (str.ToUpper()=="FIRE")
                {
                    sigma. OnFire();
                }
            }
        }
    }
         
    上面的代码中提到:事件是基于委托的,委托不但是声明事件的基础,同时也是通知收发双方必需共同遵守的一个“约定”。OK,让我们改进一下上面的例子,进一步发挥事件的威力。

          设想这样一个情况:大楼一共是7层,每层的防火做的也不错,只要不是火特别大那么就没必要让所有人都撤离——哪层着火,哪层员工撤离。还有就是一个火警的级别问题:我们把火的大小分为三级——

    C级(小火):打火机级,我左边的兄弟比较喜欢抽烟,一般他点烟的时候我不跑。

    B级(中火):比较大了,要求所在楼层的人员撤离。

    A级(大火):一般女友发脾气都是这个级别,要求全楼人撤离。

    OK,让我们看看代码:

    //=============水之真谛============
    //
    //        http://blog.csdn.net/FantasiaX
    //
    //=========
    上善若水,润物无声==========
    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace EventSample
    {
        //
    事件参数类:记载着火的楼层和级别
        class FireEventArgs
        {
            public int floor;
            public char fireLevel;
        }

        //
    委托是事件的基础,是通知的发送方与接收方共同遵守的"约定"
        delegate void FireAlarmDelegate(object sender, FireEventArgs e);

        //
    大楼(类)
        class Building
        {
            //
    声明事件:事件以委托为基础
            public event FireAlarmDelegate FireAlarmRing;

            //
    大楼失火,引发火警鸣响事件
            public void OnFire(int floor, char level)
            {
                FireEventArgs e = new FireEventArgs();
                e.floor = floor;
                e.fireLevel = level;
                this.FireAlarmRing(this, e);
            }
            public string buildingName;
        }

        //
    员工(类)
        class Employee
        {
            public string workingPlace;
            public int workingFloor;
            //
    这是员工对火警事件的响应,即员工的Event handler。注意与委托的匹配。
            public void RunAway(object sender, FireEventArgs e)
            {
                Building firePlace = (Building)sender;
                if (firePlace.buildingName == this.workingPlace && (e.fireLevel == 'A' || e.floor == this.workingFloor))
                {
                    Console.WriteLine("Running awary...");
                }
            }
        }

        //
    消防员(类)
        class Fireman
        {
            //
    这是消防员对火警事件的响应,即消防员的Event handler。注意与委托的匹配。
            public void RushIntoFire(object sender, FireEventArgs e)
            {
                Console.WriteLine("Fighting with fire...");
            }
        }

        class Program
        {
            static void Main(string[] args)
            {
                Building sigma = new Building();
                Employee employee = new Employee();
                Fireman fireman = new Fireman();

                sigma.buildingName = "Sigma";
                employee.workingPlace = "Sigma";
                employee.workingFloor = 1;

                //
    事件的影响者"订阅"事件,开始关心这个事件发生没发生
                sigma.FireAlarmRing += new FireAlarmDelegate(employee.RunAway);
                sigma.FireAlarmRing += new FireAlarmDelegate(fireman.RushIntoFire);

                //
    由你来放火!
                Console.WriteLine("Please input 'FIRE' to fire the building...");
                string str = Console.ReadLine();
                if (str.ToUpper() == "FIRE")
                {
                    sigma.OnFire(7, 'C');
                }
            }
        }
    }
           我们仔细分析一下上面的代码:

    1.        较之第一个例子,本例中多了一个class FireEventArgs 类,这个类是专门用于传递“着火”这件事的参数的——请回过头去看“现实世界中的事件”一段——我们关心的主要是着火的地点和火的级别,因为在这个类中我们有两个成员变量。

    2.        接下来的委托也有所改变,由无参变成了两个参数——object sender, FireEventArgs e ,大家可能会问:为什么你写两个参数,而不用3个或者4个?唔……传统习惯就是这样,这个传统的开端应该可以追溯到VCWin32时代吧——那时候,消息传递的参数就是一个lParam和一个wParam,分别承载着各种有用的信息——VB模仿它们,一个改名叫sender,一个改名叫e,然后C#又传承了VB,就有了你看到的样子。至于为什么第一个参数是object型,解释起来需要用到一些“多态”的知识,在这里我先不说了,我会在《深入浅出话多态》中以之为例。第二个参数使用了我们自己制造的类,这个类里带着两个有用的信息,上面也提到过了。

    3.        Building类的OnFire方法函数中,进行了参数的传递——你完全可以理解成:Building类将这些参数(一个是this,也就是自己,另一个是e,承载着重要信息)发送给了接收者,也就是发送给了关心/订阅了这一事件的类。在我们这个例子中,订阅了Building类事件的对象分别是employeefireman,他们会在事件发生的时候得到通知,并从传递给他们的事件参数中筛选自己关心的内容。这一筛选是由程序员完成的,在本例中,Employee对消息就做了筛选,而Fireman类不加筛选,见火就灭(我有点担心我左边的兄弟)。

    4.        注意:Building类有一个buildingName域,因为Building是事件的持有者,所以在事件激发的时候,它也是消息的发送者(sender),所以,这个buildingName域也会随着this被发送出去。如果你理解什么是多态,那么OK,你会明白为什么可以使用Building firePlace = (Building)sender;把这个buildingName读出来。

    5.        Employee类是本程序中最有意思的类。它不但提供了对Build类事件的影响,还会对事件进行智能筛选——只有当自己所工作的大厦警报鸣响,并且是自己所在楼层失火或火势足够大时才会撤离。请仔细分析public void RunAway(object sender, FireEventArgs e)方法。

    6.        Employee类不同,Fireman类对事件是不加筛选的——你想啦,灭火可是消防员的职责,不论哪里着火,他们都会勇往直前!

    7.        进入主程序,代码相当清晰——的确是这样,基本类库的代码总是比较复杂(在本例中,基本类库是指BuildingEmployeeFireman这几个类)。一般情况下,基本类库与主程序的开发者不是一个人,基本类库的源代码一般也不向主程序的开发者开放,而是以DLLAssembly)文件的形式发放,所以实际开发中整个程序看起来是非常清晰的。

    8.                    sigma.FireAlarmRing += new FireAlarmDelegate(employee.RunAway);
                sigma.FireAlarmRing += new FireAlarmDelegate(fireman.RushIntoFire);
    通过这两句你能看出什么来?呵呵,因为事件是基于委托的,所以事件也是多播的!如果不明白什么是多播委托,请参见《深入浅出话委托》。

    9.        因为员工在1F工作,所以7层的C级火不会导致其撤离——只有消防员会响应。

     

     

    TO BE CONTINUE

     

     

    法律声明:本文章受到知识产权法保护,任何单位或个人若需要转载此文,必需保证文章的完整性(未经作者许可的任何删节或改动将视为侵权行为)。若您需要转载,请务必注明文章出处为CSDN以保障网站的权益;请务必注明文章作者为刘铁猛,并向bladey@tom.com发送邮件,标明文章位置及用途。转载时请将此法律声明一并转载,谢谢!

     

     

    展开全文
  • 委托和事件的区别(讲的很详细)

    万次阅读 多人点赞 2008-10-25 23:58:00
    原文地址:http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx 委托 和 事件...它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里
  • 【TencentOS】事件

    2019-09-20 18:35:35
    3)事件 概述 事件提供了一种任务间实现同步和信息传递的机制。一般来说,一个事件中包含了一个旗标,这个旗标的每一位表示一个“事件”。 一个任务可以等待一个或者多个“事件”的发生,其他任务在一定的业务条件下...
  • [JS]事件

    2020-11-23 11:03:13
    事件 描述 onload onload 事件会在页面或图像加载完成后立即发生。 onload 通常用于 <body> 元素,在页面完全载入后(包括图片、css文件等等。)执行脚本代码。 onunload ...
  • js阻止事件冒泡

    万次阅读 2019-06-04 15:21:39
    js阻止事件冒泡 冒泡事件简介 当我们点击一个控件的时候,如果包括这个控件的父控件也有click事件,则会继续执行。 方法一:event.stopPropagation( ); 例如: <div> <p>段落文本内容 <input type=...
  • C#事件

    千次阅读 2018-03-29 23:36:53
    C#事件的用法与意义C#事件与委托十分相似,其实事件包含了一个私有委托,所以事件就像是专门用于某种特殊用途的简单委托。事件使用的方法图:正如上图所示,发布者类Incrementer里面的事件CountedADozen就像一个装...
  • 委托 委托太常见了,能灵活运用可以使你在编程中游刃有余。 简单说它就是一个能把方法当参数传递的对象,而且还知道怎么调用这个方法,同时也是粒度更小的“接口”(约束了指向方法的签名) 委托的简单使用 ...
  • C#事件(event)解析

    千次阅读 2013-11-27 16:37:36
    事件(event)  事件类似于异常,因为它们都是由对象引发(抛出),我们可以提供代码来处理事件。单它们也有区别,最重要的区别是并没有与try...catch 类似的结构来处理事件,而必须订阅(subscribe)它们。订阅一...
  • c#事件 传值

    2019-02-26 16:56:10
    c#事件传值特别简单只要了解事件的含义。 假设场景: 在比赛过程中,当裁判员枪声响起,发生了一个事件,裁判员通知该事件发生,参加比赛的运动员仔细听枪声是否发生。运动员是该事件的订阅者,没有参赛的人不会...
  • C#事件概念

    万次阅读 2009-12-09 15:16:00
    原则:1、C#事件本质就是对消息的封装,用作对象之间的通信;发送方叫事件发送器,接收方叫事件接收器;2、发送器不知道接收器的任何情况,但接收器有一个事件处理程序来处理这个事件(当事件发生时);那么发送器...
  • C#事件监听

    2012-06-18 11:41:28
    这两天头脑发热,突然想学C#,用C#作一个网络通信服务包,遇到了种种问题,下面是一个c++中不太常见的处理方式“事件监听”搞了半天才明白,跟c++的继承非常相似。实现功能如下: 定义一个用户委托事件 public ...
  • c#事件机制

    千次阅读 2018-10-02 17:01:50
    c#有一个很重要的高级语言特性,叫做事件,有很多人说事件就是委托,其实不然,事件包含委托,但绝对不是委托,因为事件只能在类中声明,而委托可以在函数也就是方法中声明,另外,事件的方法也少于委托,那么什么是...
  • 事件C#中另一高级概念,使用方法和委托相关。奥运会参加百米的田径运动员听到枪声,比赛立即进行。其中枪声是事件,而运动员比赛就是这个事件发生后的动作。不参加该项比赛的人对枪声没有反应。 <br />...
  • C#事件的用法

    2019-02-06 00:04:33
    //事件提供者,提供事件为其成员NUM的值改变。事件为静态事件NumChange class EventExp { static private int num; //public EventExp exp; public delegate void NumChangeEventHandler(object sender, N...
  • c# 事件 EventHandler

    千次阅读 2014-10-21 21:27:23
    3 /// 用户在单击win窗口中的如按钮,复选框等,就会引发事件,我们要写代码去处理这些事件。实现 处理事件事件处理程序 4 /// 在.Net里,有委托实现事件,具有事件的对象为:发布者。订阅事件(处理事件)的为...
  • C#事件回调

    千次阅读 2015-01-10 22:13:47
    自己学习过程中的一点笔记: using System; using System.Collections.Generic; using System.Text; namespace TestApp { class Program { public static void Main(string[] args) ...
  • C# 事件

    千次阅读 2015-04-17 09:45:22
    本篇文章我们来讨论C#中的事件。委托是事件的基础,了解委托请点击C#委托 。 我们先来看下面这个类public class Person { public string Name { get; set; } public int Age { get; set; } public void ZhuangBi...
  • C#事件的发送方和接收方

    千次阅读 2012-10-28 22:32:37
    C#事件的发送方和接收方(订阅方) windows的应用程序也是基于消息的,Windows使用预定义消息与应用程序通讯。 .NET Framework将Windows消息封装在事件中,可以把事件作为对象之间的通讯介质。 事件发送...
  • C# 事件案例 (事件触发多方法)

    千次阅读 2019-02-15 11:06:28
    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; ...namespace Examples ... public delegate void ...//声明事件所需的委托(代理) cla...
  • c# 事件传参

    2017-08-03 17:00:00
    public class SeatChoosenEventArgs : EventArgs { public 呼叫中心工号核对表Entity SeatChoosen; } public partial class UCSeatIcon : UserControl {  private 呼叫中心工号核对表Entity _entity;...
  • C#事件为空

    千次阅读 2010-09-11 13:17:00
    事件定义之后,在调用的时候提示为空是怎么回事?
  • C#事件-经典小例子

    2010-11-22 00:09:00
    public class EatEventArgs : EventArgs ...{ public String restrauntName;... /// 这个委托用来说明处理吃饭事件的方法的方法头(模式) /// public delegate void EatEventHandler(obje
  • C#事件与委托

    千次阅读 2015-07-19 00:43:03
    C#中Event和委托
  • C# 事件的继承

    千次阅读 2007-07-03 18:09:00
    有下面一段代码,目的是实现事件的继承: 基类: public class BaseBusiness { //声明事件委托 public delegate void ProgressEventHandler(int progress, string msg); //声明事件 public event ...
  • C#事件的调用

    千次阅读 2018-06-26 22:53:03
    前言说实话,这东西我在做这个东西之前只是单纯的用C#给出的事件,如Form_Load(),然后在事件中写方法,这玩意都是自己生成的,从没关心过这个事件是怎么调用的以及其背后的机制。所以,现在先浅谈我对这个东西浅显...
  • C#事件-事件本身就是一种多播委托

    千次阅读 2010-11-22 00:13:00
    C#中的事件就是委托的一个变量。它和属性、方法一样,都是类的成员。只不过事件是指向一个方法,当事件被触发时,就会执行对象的相关方法。 事件的这种对方法的引用并不是写死在代码里面的,而是可以...
  • C#事件的实现

    千次阅读 2012-12-19 11:25:11
    事件C#中一个重要的内容,MSDN上有一个自定义事件的演示示例。我看了半天有点晕,所以新建了一个winform工程添加了一个按钮,然后找出调用的程序,一对比做了一个类似的示例,就明白了。看代码有时候比看文档来得...

空空如也

1 2 3 4 5 ... 20
收藏数 2,726,094
精华内容 1,090,437
关键字:

事件