专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

第61节 模拟和自定义事件Event-Web前端开发之-JavaScript-王唯

ins518 2024-09-29 18:35:36 技术文章 188 ℃ 0 评论

本内容是《Web前端开发之Javascript视频》的课件,请配合大师哥《Javascript》视频课程学习。

模拟事件:

事件经常由用户操作或通过其他浏览器功能来触发,也可以使用javascript在任意时刻来触发特定的事件,该事件就如同浏览器创建的事件一样,也就是通过Javascript来模拟触发事件;

DOM2级规定了模拟特定事件的方式,标准浏览器都支持这种方式,IE拥有自己模拟事件的方式;

DOM中的事件模拟:

可以在doucment对象上使用createEvent(type)方法创建event对象,该方法接受一个表示要创建的事件类型的type字符串参数;

// 创建事件
var event = document.createEvent("Event");
console.log(event);  // Event
// 定义名为build的事件
event.initEvent("build", true, true);
// 注册事件处理程序
ele.addEventListener("build", function(e){
    console.log(e);
},false);
// 触发
ele.dispatchEvent(event);

type参数,只能传递事件模块中定义的值,在DOM2级中,所有这些字符串都使用英文复数的形式,而在DOM3级中都变成了单数;该字符串可以是以下字符串之一:

Event:通用Event类;

  • UIEvents:一般化的UI事件,鼠标事件和键盘事件都继承自UI事件,DOM3级是UIEvent;
  • MouseEvents:一般化的鼠标事件,DOM3级是MouseEvent;
  • KeyboardEvent:
  • MutationEvents:一般化的DOM变化事件,DOM3级是MutationEvent;
  • HTMLEvents:一般化的HTML事件,没有对应的DOM3级事件,因为在DOM3级事件中,把HTML事件分散到其他类别中了;
  • TextEvents:DOM3级为TextEvent;
  • CustomEvent:自定义事件;
var event = document.createEvent("MouseEvents");

事件模块还有其他,如:SVGEvents、MessageEvent、ProgressEvent、AnimationEvent、TransitionEvent等;

DOM2级事件并没有专门规定键盘事件,在DOM3级事件中给出键盘事件的规定;实际上,当前还没有浏览器支持DOM3级的键盘事件;但在现有方法的基础上,可以通过几种方式来模拟键盘事件;

创建了event对象后,还需要使用与事件有关的信息对其进行初始化;每种类型的event对象都有一个特殊的方法,为它传入适当的数据就可以初始化该event对象,但不同类型的这个方法的名字也不相同,具体要取决于createEvent()中使用的参数;

Event模块的event对象,可以使用Event.initEvent()方法进行初始化;语法:event.initEvent(type, bubbles, cancelable);参数:type:定义了事件名称;bubbles:一个 Boolean 值,是否冒泡;cancelable:一个 Boolean 值,是否可以被取消;如:

event.initEvent("click",true,true);

事件模块及其初始化方法:

  • UIEvents:event.initUIEvent;
  • MouseEvents:initMouseEvent;
  • MutationEvents:initMutationEvent;
  • HTMLEvents:event.initEvent;
  • TextEvent:event.initTextEvent;
  • KeyboardEvent:event.initKeyboardEvent;
  • CustomEvent:event.initCustomEvent;

这些初始化方法中的参数都不一样,由其事件类型决定的,如:

var event = document.createEvent("MouseEvents");
event.initMouseEvent("click",true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);

模拟事件最后一步就是使用dispatchEvent()方法触发事件,需要传入表示要触发事件的event对象;所有支持事件的DOM节点都支持该方法;

var btn = document.getElementById("btn");
btn.addEventListener("click", function(event){
    console.log("click");
});
btn.dispatchEvent(event);

触发事件后,该事件就可以像普通的事件一样,也可以冒泡,并且也能正常的引发相应的事件处理程序的执行;

dispatchEvent()方法返回一个boolean值,当该事件是可取消的(cancelable为true)并且至少一个该事件的事件处理程序调用了preventDefault(),则返回值为false;否则返回true;

如果dispatchEvent()方法在调用之前,事件没有被经过初始化,就会抛出一个 UNSPECIFIED_EVENT_TYPE_ERR 异常,或者如果事件类型是null或事件处理程序是一个空字符串就会抛出未捕获的异常;

var result = btn.dispatchEvent(event);
// true,当事件处理程序中执行event.preventDefault(),返回false
console.log(result);  // true

模拟鼠标事件:

方法就可以创建并返回一个模拟鼠标事件对象,该对象有一个名为initMouseEvent()方法,用于指定与该鼠标事件有关的信息;该方法接受15个参数,分别与鼠标事件中每个典型的属性一一对应,参数如下:

  • type (字符串):表示要触发的事件类型(例如:click);
  • bubbles (布尔值):表示事件是否应该冒泡;为精确地模拟鼠标事件,应该设为true
  • cancelable (布尔值):表示事件是事可以取消;为精确,应该设为true;
  • view (AbstractView):与事件关联的视图,这个参数几乎总是要设置为doucment.defaultView;
  • detail (整数):与事件有关的详细信息,这个值一般只是事件处理程序使用,但通常都设置为0;
  • screenX (整数):事件相对于屏幕的X坐标;
  • screenY (整数):事件相对于屏幕的Y坐标;
  • clientX (整数):事件相对于视口的X坐标;
  • clientY (整数):事件相对于视口的Y坐标;
  • ctrlKey (布尔值):是否按下了Ctrl键,默认为false;
  • altKey (布尔值):是否按下了Alt键,默认为false;
  • shiftKey (布尔值):是否按下了Shift键,默认为false;
  • metakey (布尔值):是否按下了Meta键,默认为false;
  • button (整数):按下了哪个鼠标键,默认为0;
  • relatedTarget (对象):表示与事件相关的对象,这个参数只在模拟mouseover与mouseout时使用;

其中,前四个参数对正确的触发事件至关重要,剩下的所有参数只有在事件处理程序中才会用到;

当把event对象传给dispatchEvent()方法时,这个对象的target属性会自动设置;

var btn = document.getElementById("btn");
EventUtil.addHandler(btn, "click", function(event){
    console.log("我被单击了");
});
// 创建事件对象
var event = document.createEvent("MouseEvents");
// 初始化事件对象
event.initMouseEvent("click", true, true, document.defaultView, 0,0,0,0,0,false,false,false,false,0,null);
btn.dispatchEvent(event);

在兼容的DOM的浏览器中,还可以通过相同的方式模拟其他鼠标事件,比如:dblclick;

模拟键盘事件:

DOM3级规定,调用createEvent()并传入“keyboardEvent”就可以创建一个键盘事件;返回的事件对象会包含一个initKeyboardEvent()方法,这个方法接受下列参数:

  • type (字符串):表示要触发的事件类型;
  • bubbles (布尔值):表示事件是否应该冒泡;
  • cancelable (布尔值):表示事件是事可以取消;
  • view (AbstractView):与事件关联的视图。这个参数几乎总是要设置为doucment.defaultView;
  • key(字符串):表示按下的键的键码;
  • location(整数):表示按下了哪里的键:0表示默认的主键盘、1表示左、2表示右、3表示数字键盘、4表示移动设备(即虚拟键盘)、5表示手柄;
  • ctrlKey:
  • altKey:
  • shiftKey:
  • metaKey:
  • repeat(整数):在行中按了这个键多少次;

由于DOM3级不提倡使用keypress事件,因此只能利用这种技术来模拟keydown和keyup事件,如:

var txt = document.getElementById("txt");
EventUtil.addHandler(txt, "keydown", function(event){
    console.log("keydown被自动触发");
});
var event;
if(document.implementation.hasFeature("KeyboradEvent","3.0")){
    event  = document.createEvent("KeyboardEvent");
    event.initKeyboardEvent("keydown", false,false, document.defaultView,"a",2,false,false,true,true,8);
    txt.dispatchEvent(event);
}

但这个参数顺序在IE中是不正常的,但其可以使用通用的事件;

首先创建一个通用的事件,然后调用initEvent()方法对其初始化,也就是向事件对象中添加键盘事件特有的信息(也可以不添加),如:

var event = document.createEvent("Events");
event.initEvent("keypress", true, true);
event.ctrlKey = false;
event.altKey = false;
event.metaKey = false;
event.shiftKey = false;
event.keyCode = 65;
event.charCode = 65;
txt.dispatchEvent(event);

在此,必须使用通用事件,而不能使用UI事件,因为UI事件不允许向event对象中再添加新属性;

像这样模拟事件虽然会触发键盘事件,但却不会向文本框中写入文本,这是由于无法精确模拟键盘事件所造成的;

模拟变动事件:

可以使用createEvent(”MutationEvents”)创建一个包含initMutationEvent()方法的变动事件对象,该方法接受的参数为:type、bubbles、cancelable、relatedNode、preValue、newValue、attrName和attrChange;

var event = document.createEvent("MutationEvents");
event.initMutationEvent("DOMNodeInserted",true,false,someNode,"","","",0);
target.dispatchEvent(event);

其他变动事件也按以上格式创建,只需要改动参数即可;

模拟HTML事件:

通过createEvent(”HTMLEvents”),再使用这个对象的initEvent()方法来初始化它即可;

var event = document.createEvent("HTMLEvents");
event.initEvent("focus", true, false);
target.dispatchEvent(event);

自定义DOM事件:

DOM3级还定义了“自定义事件”,此类事件不是DOM原生触发的,它的目的是让开发人员创建自己的事件;

要创建自定义事件,可以调用createEvent(“CustomEvent”)方法,返回的对象有一个名为initCustomEvent()的方法,其接收4个参数:

  • type (字符串):表示要触发的事件类型,如“keydown”;
  • bubbles (布尔值):表示事件是否应该冒泡;
  • cancelable (布尔值):表示事件是事可以取消;
  • detail(对象):任意值,保存在event对象的detail属性中;

可以像分派其他事件一样在DOM中分派创建的自定义事件对象,如:

var oDiv = document.getElementById("mydiv");
EventUtil.addHandler(oDiv, "myevent", function(event){
    console.log("div:" + event.detail);
});
EventUtil.addHandler(document, "myevent", function(event){
    console.log("document:" + event.detail);
});
if(document.implementation.hasFeature("CustomEvent","3.0")){
    event = document.createEvent("CustomEvent");
    event.initCustomEvent("myevent", true, false, "Web前端开发");
    oDiv.dispatchEvent(event);
}

IE中的事件模拟:

IE8及以下是不是支持DOM模拟事件的,它有专用的一套API,其与DOM思路相似:先创建event对象,然后为其指定相应的信息,然后再使用该对象来触发事件;

调用document.createEventObject()方法可以在IE中创建event对象,该方法不接受参数,会返回一个通用的event对象;然后,手工为这个对象添加所有必要的信息;最后,在目标上调用fireEvent()方法,该方法接受两个数:事件处理程序的名称和event对象;在调用fireEvent()方法时,会自动为event对象添加srcElement和type属性;其他属性则都是必须手工添加的;模拟任何IE支持的事件都采用相同的模式;

var btn = document.getElementById("btn");
EventUtil.addHandler(btn, "click", function(event){
    console.log("我被单击了");
});
// 创建事件对象
var event = document.createEventObject();
// 初始化事件对象
event.screenX = 0;
event.screenY = 0;
event.clientX = 0;
event.clientY = 0;
event.ctrlKey = false;
event.altKey = false;
event.shiftKey = false;
event.button = 0;
btn.fireEvent("onclick", event);

为事件对象添加的属性可以随意,不会有任何限制,即使添加的属性IE不支持也可以,添加的属性对事件没有影响,因为只有事件处理才会用到它们;

采用相同的模式也可以模拟触发keypress事件;

var txt = document.getElementById("txt");
EventUtil.addHandler(txt, "keypress", function(event){
    console.log("我是文本域");
});
var event = document.createEventObject();
event.altKey = false;
event.ctrlKey = false;
event.shiftKey = false;
event.keyCode = 65;
txt.fireEvent("onkeypress", event);

与DOM一样,不会在文本框中输出任何字符;

由于鼠标事件、键盘事件以及其他事件的event对象并没有什么不同,所以可以使用通用对象来触发任何类型的事件;

自定义事件:

document.createEvent()已经不推荐使用了,建议使用各种事件类型的构造函数来创建事件;

Event类:

表示在 DOM 中出现的事件,其是其他类型事件的基类,包含适用于所有事件的属性和方法;
构造函数:Event(),创建并返回一个 Event 对象;语法:event = new Event(typeArg, eventInit);参数:typeArg,字符串,表示所创建事件的名称;
eventInit可选,是EventInit 类型的字典对象,其接受以下字段:

  • "bubbles",可选,Boolean类型,默认值为 false,表示该事件是否冒泡;
  • "cancelable",可选,Boolean类型,默认值为 false, 表示该事件能否被取消;
  • "composed",可选,Boolean类型,默认值为 false,指示事件是否会在Shadow DOM根节点之外触发侦听器;
var event = new Event("click",{bubbles:false, cancelable: false,});
console.log(event);

该typeArg事件类型,即可以是内置的事件,也可以是自定义的事件;

Element.dispatchEvent(event):

事件创建后,需要使用dispatchEvent()手动触发;

var event = new Event("click",{bubbles:false, cancelable: false,});
console.log(event);
var btn = document.getElementById("btn");
btn.addEventListener("click", function(event){
    console.log(event);
})
btn.dispatchEvent(event);
// 或者
var event = new Event("gohome", {"bubbles":true, "cancelable": false, "composed":false});
function goHomeHandler(event){
    console.log(event);
}
document.addEventListener("gohome", goHomeHandler,false);
document.dispatchEvent(event);

注:使用事件event.isTrusted属性可以区分是用户触发还是脚本触发的;

另外,自定义事件应该使用addEventListener,因为 on<event> 仅用于内建事件中;
IE不支持使用构造器创建事件,只能使用document.createEvent()方法代替;如:

var event = document.createEvent("Event");
event.initEvent("build", true, true);
console.log(event);

如:

var afterClick = new Event("afterclick");
var btn = document.getElementById("btn");
btn.addEventListener("afterclick", function(event){
    console.log("单击事件后执行的逻辑");
},false);
btn.addEventListener("click", function(event){
    console.log("被点击了");
    this.dispatchEvent(afterClick);
},false);
event.preventDefault():

许多内置事件是有默认行为的,但对于自定义的事件,是没有默认的行为;但当调用该方法时,dispatchEvent()方法就会返回false;所以该方法用在自定义事件中,是为了实现一些特殊的目的,例如,通过调用该方法,事件处理程序可以发出一个信号,根据这个信号,以便决定以下应该如何进行,如:

btn.addEventListener("click", function(event){
    event.preventDefault();
},false);
var result = btn.dispatchEvent(event);
console.log(result);

示例:

<pre id="rabbit">
    |\   /|
     \|_|/
     /. .\
    =\_Y_/=
     {>o<}
</pre>
<button id="btn">隐藏</button>
<script>
var btn = document.getElementById("btn");
var rabbit = document.getElementById("rabbit");
function hideHandler(){
    var event = new Event("hide", {
        cancelable: true
    });
    if(!rabbit.dispatchEvent(event)){
        alert("这个事件被阻止了");
    }else{
        rabbit.hidden = true;
    }
}
btn.addEventListener("click", hideHandler,false);
rabbit.addEventListener("hide", function(event){
    if(confirm("需要阻止事件吗?"))
        event.preventDefault();
});
</script>

常见Event的子类:

  • CustomEvent:自定义事件类;
  • DeviceOrientationEvent:旋转移动设备事件类;(比如,获取事件的旋转的x、y和Z轴的角度等)
  • DragEvent:拖放事件类,其同时继承Event和MouseEvent类;
  • ErrorEvent:错误事件类;
  • FocusEvent:表示与焦点相关的事件类,继承自UIEvent类;
  • KeyboardEvent:键盘事件类
  • MouseEvent:鼠标事件类,继承自UIEvent类;
  • MutationEvent:变动事件类;
  • TouchEvent:触摸事件类,继承自UIEvent类;
  • UIEvent;用户界面事件类,继承自Event类;
  • WheelEvent:鼠标滚轮或类似输入设备事件类;

不同的事件类型,其标准属性是不一样的,例如鼠标事件的clientX和clientY,如:

var event = new MouseEvent("click", {
    bubbles: true,
    cancelable: true,
    clientX: 100,
    clientY: 100,
});
var btn = document.getElementById("btn");
btn.addEventListener("click", function(event){
    console.log(event.clientX + ":" + event.clientY); // 100 100
},false);
btn.dispatchEvent(event);

但是如果使用Event构造器(把MouseEvent换成Event),由于clientX和clientY属性不是它的标准属性,所以直接被忽略;

创建CustomEvent事件:
例如把上例中的new Event换成new CustomEvent,结果是一样的;但CustomEvent对象拥有detail属性,可以使用它来传递一些信息,该属性可以是任何类型的数据,如:

<form>
    <input type="text" id="txt" />
</form>
<script>
var form = document.querySelector("form");
var txt = document.querySelector("#txt");
// 创建一个新事件,允许冒泡,并提供要传递给“detail”属性的任何数据
var eventAwesom = new CustomEvent("awesome", {
    bubbles: true,
    detail: {
        text: function(){
            // console.log(event); // 可以直接使用event
            return event.target.value;
        }
    }
});
// form元素侦听自定义的“awesome”事件,然后控制传递的text()方法的输出
form.addEventListener("awesome", function(event){
    console.log(event.detail.text());
},false);
// 当用户键入时,触发target中awesome事件
txt.addEventListener("input", function(event){
    event.target.dispatchEvent(eventAwesom);
},false);
</script>

甚至可以在dispatchEvent()方法中直接实例化一个Event对象,如:

txt.addEventListener("input", function(event){
    event.target.dispatchEvent(new CustomEvent("awesome",{bubbles:true, detail:{text:function(){return event.target.value;}}}));
},false);

创建MouseEvent事件,语法:event = new MouseEvent(typeArg, mouseEventInit);参数typeArg为事件名称,可选参数mouseEventInit为初始化MouseEvent的字典对象,与上面的initMouseEvent()方法作用相同,如:

var event = new MouseEvent("click", {
    "bubbles": false,
    "cancelable": false,
    "view": document.defaultView
});
var btn = document.getElementById("btn");
btn.addEventListener("click", function(event){
    console.log(event);  // bubbles为false,cancelable为false
},false);
btn.dispatchEvent(event);

创建KeyboardEvent事件,语法:event = new KeyboardEvent(typeArg, KeyboardEventInit),参数typeArg为事件名称,KeyboardEventInit为一个字典对象,有以下几种值:

  • "key",可选,默认为"",对应KeyboardEvent.key的值;
  • "code",可选,默认为"",对应KeyboardEvent.code的值;
  • "location", 可选,默认为 0, unsigned long类型, 设置 KeyboardEvent.location 的值。
  • "ctrlKey", 可选,默认为 false, Boolean 类型, 设置 KeyboardEvent.ctrlKey 的值。
  • "shiftKey", 可选,默认为 false, Boolean 类型, 设置KeyboardEvent.shiftKey 的值。
  • "altKey", 可选,默认为 false, Boolean 类型, 设置 KeyboardEvent.altKey 的值。
  • "metaKey", 可选,默认为 false, Boolean 类型, 设置 KeyboardEvent.metaKey 的值。
  • "repeat", 可选,默认为 false, Boolean 类型, 设置 KeyboardEvent.repeat 的值。
  • "isComposing", 可选,默认为 false, Boolean 类型, 设置 KeyboardEvent.isComposing 的值。
  • "charCode", 可选,默认为 0, unsigned long 类型, 设置 KeyboardEvent.charCode (已废弃) 的值。
  • "keyCode", 可选,默认为 0, unsigned long 类型, 设置KeyboardEvent.keyCode (已废弃) 的值。
  • "which", 可选,默认为 0, unsigned long 类型, 设置KeyboardEvent.which (已废弃) 的值

KeyboardEventInit 字典也可以接受来自 UIEventInit 和 EventInit 的字典字段值;如:

var event = new KeyboardEvent("keydown");
txt.dispatchEvent(event);

设置KeyboardEventInit参数:

var event = new KeyboardEvent("keydown",{
    key:"",
    code:"",
    location:0,
    ctrlKey:false,
    shiftKey:false,
    altKey:false,
    metaKey:false,
    repeat:false,
    isComposing:false,
    charCode:0,
    keyCode:0,
    which:0
});
txt.dispatchEvent(event);

自定义事件的实现原理:

事件本质上是一种消息,事件模式是一种叫做观察者的设计模式,这是一种创建松散耦合代码的技术;

观察者模式有两类对象组成:主体和观察者;主体负责发布事件,同时观察者通过订阅这些事件来观察该主体;该模式的一个关键概念是主体并不知道观察者的任何事情,也就是说它可以独自存在并正常运作即使观察者不存在;从另一方面说,观察者知道主体并能注册事件的回调函数(事件处理程序);涉及DOM上时,DOM元素便是主体,你的事件处理代码便是观察者;

最原始的自定义事件,如:

var obj = {};
obj["click"] = function(){
    console.log("最简单的事件");
};
obj["click"]();

自定义事件本质上就是调用一个函数;对于内置事件来说,事件名通常事先就由API定义了;

最简单的自定义事件,如:

// 添加自定义事件
function addEvent(obj, type, handler){
    obj[type] = handler;
}
// 移除自定义事件
function removeEvent(obj, type){
    delete obj[type];
}
// 触发/派发自定义事件
function dispatchEvent(obj, type){
    obj[type]();
}
var obj = {};
function handler(){
    console.log("简单的自定义事件");
}
addEvent(obj, "myclick", handler);
dispatchEvent(obj, "myclick");

简单的事件类:

function MyEvent(){
    this.handler;
}
MyEvent.prototype = {
    constructor: MyEvent,
    addEvent: function(type,handler){
        this[type] = this.handler = handler;
    },
    removeEvent: function(type){
        this.handler = null;
        this[type] = null;
    },
    dispatchEvent: function(type){
        // this.handler();
        if(this[type]) // 或者
            this[type]();
    }
};
var myevent = new MyEvent();
myevent.addEvent("myclick",function(){
    console.log("自定义事件类");
});
myevent.dispatchEvent("myclick");
myevent.removeEvent("myclick");
myevent.dispatchEvent("myclick");

事件对象是可以注册多个事件的,如:

function MyEvent(){
    this.handlers = {};
}
MyEvent.prototype = {
    constructor: MyEvent,
    addEvent: function(type,handler){
        if(typeof type === "string" && typeof handler === "function"){
            // 如果不存在type,就新建一个
            if(typeof this.handlers[type] == "undefined")
                this.handlers[type] = [];
            this.handlers[type].push(handler);
        }
    },
    removeEvent: function(type, handler){
        var handlers = this.handlers[type];
        if(typeof type === "string" && handlers instanceof Array){
            if(typeof handler === "function"){
                // 清除type对应的handler方法
                for(var i=0, len=handlers.length; i<len; i++){
                    if(handlers[i] === handler)
                        break;
                }
                handlers.splice(i,1);
            }
        }
        handlers = null;
    },
    dispatchEvent: function(type){
        var handlers = this.handlers[type];
        if(handlers instanceof Array){
            for(var i=0, len = handlers.length; i<len; i++){
                if(typeof handlers[i] === "function")
                    handlers[i]();
            }
        }
        handlers = null;
    }
};
var handler = function(){
    console.log("自定义事件类");
}
var myevent = new MyEvent();
myevent.addEvent("myclick", handler);
myevent.dispatchEvent("myclick");
myevent.removeEvent("myclick", handler);
myevent.dispatchEvent("myclick");

也可以改造dispatchEvent()方法,传递一个类似event对象,如:

// ...
    dispatchEvent: function(event){
        var handlers = this.handlers[event.type];
        if(handlers instanceof Array){
            for(var i=0, len = handlers.length; i<len; i++){
                if(typeof handlers[i] === "function")
                    handlers[i](event);
            }
        }
        handlers = null;
    }

应用:

var handler = function(event){
    console.log("自定义事件类");
    console.log(event.detail);
}
var event = {
    type: "myclick",
    detail : {}
}
var myevent = new MyEvent();
myevent.addEvent("myclick", handler);
myevent.dispatchEvent(event);
myevent.removeEvent("myclick", handler);
myevent.dispatchEvent(event);

应用:

function Student(name){
    this.myEvent = new MyEvent();
    this.name = name;
}
Student.prototype = {
    constructor: Student,
    setName: function(name){
        var event = {
            type: "changeName",
            newName: name,
            oldName: this.name
        };
        this.myEvent.dispatchEvent(event);
        this.name = name;
    }
}
// 创建学生对象
var student = new Student("wangwei");
// 事件处理程序
function changeNameHandler(event){
    console.log("事件类型:" + event.type + ",oldName:" + event.oldName + ",newName:" + event.newName);
}
// 注册事件changeName
student.myEvent.addEvent("changeName", changeNameHandler);
// 设置name,将会触发事件changeName
student.setName("Jing Jing");

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表