网站首页 > 技术文章 正文
本内容是《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");
猜你喜欢
- 2025-06-09 为什么数字孪生开发选择UE5?高保真视觉与物理模拟的完美结合
- 2025-06-09 恒玄科技:公司为智能手表提供主控芯片和低功耗模拟前端
- 2025-06-09 晶华微:带ADC的多芯锂电池充放电管理模拟前端芯片有望在第三或第四季度推出
- 2025-06-09 「招标」瀚诺半导体模拟前端芯片IP核(二次)国内公开招标
- 2025-06-09 ADI推出带24位转换器内核的高度集成模拟前端
- 2024-09-29 如何使用React的useEffect Hook来模拟componentDidMount和。。。
- 2024-09-29 模拟实现JS的apply&call方法 js模拟post
- 2024-09-29 暖芯迦推出超低功耗六合一生理信号模拟前端芯片——九感BAF003
- 2024-09-29 高速adc模拟前端无源路仿真 adc前端电路设计详解
- 2024-09-29 恩智浦N-AFE模拟前端产品在工业自动化中的应用
你 发表评论:
欢迎- 502℃几个Oracle空值处理函数 oracle处理null值的函数
- 500℃Oracle分析函数之Lag和Lead()使用
- 496℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 491℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 482℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 474℃【数据统计分析】详解Oracle分组函数之CUBE
- 457℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 455℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端富文本编辑器 (47)
- 前端路由 (61)
- 前端数组 (73)
- 前端定时器 (47)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)