标签:mod 事件模型 阶段 使用 字符串 容器 cal suv nodename
事件处理程序就是响应某个时间的函数,DOM事件分为3个级别:DOM 0级事件处理,DOM2级事件处理,DOM3级事件处理
el.onclick=function(){}
var btn = document.getElementById(‘btn‘);
btn.onclick = function(){
alert(this.innerHTML);
}
当希望为同一个元素/标签绑定多个同类型事件的时候(如给上面这个btn元素绑定三个点击事件),是不被允许的。DOM0级事件绑定,给元素的事件行为绑定方法,这些方法都是在当前元素事件行为的冒泡阶段(或者目标阶段)执行的
el.addEventlistener(event-name,callback,useCapture)
event-name:事件名称,可以是标准的DOM事件
callback:回调函数,当事件触发时,函数会被注入一个参数为当前的事件对象event
userCapture:默认是false,代表事件句柄在冒泡阶段执行
var btn = document.getElement(‘btn‘);
btn.addEventListener("click",test,false);
function test(e){
e = e || window.event
alert(e.target|| e.srcElement.innerHTML);
btn.removeListener("click",test)
}
IE9以下的IE浏览器不支持addEventListener()和removeListener(),使用attachEven()与detachEvent()代替,因为IE9以下不支持事件捕获的,所以也没有第三个参数,第一个事件名称前要加on。
DOM事件模型分为捕获和冒泡。一个事件发生后,会在子元素和父元素之间传播。这种传播分为三个阶段。
捕获是从上到下,事件先从window对象,然后再到document(对象),然后是html标签(通过document.documentElement获取html标签),然后是body标签(通过document.body获取body标签),然后按照普通的html结构一层一层往下传,最后到达目标元素
而事件冒泡的流程刚好是事件捕获的逆过程。
由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理子元素的事件。这种方法叫做事件对的代理
如何实现
//给父层元素绑定事件
document.getElementId(‘list‘).addEventListener(‘click‘,function(e){
//兼容性处理
var event =e||window.event
var target =event.target ||event.srcElemnt;
//判断是否匹配目标元素
if(target.nodeName.toLocaleLowerCase === ‘li‘){
console.log(‘this content is:‘,target.innerHTML)
}
})
event.preventDefault()
如果调用这个方法,默认事件行为将不再触发。什么是默认事件呢?例如表单一点击提交按钮(suvmit)跳转页面,a标签默认页面跳转或是锚点定位等。
<a id="test" href="http://www.cnblogs.com">链接</a>
<script>
var test=document.getElementById(‘test‘);
test.onclick =function(e){
e =e ||window.event;
e.preventDefault();
}
</script>
实现输入框最多只能输入六个字符
<input type="text" id="tempInp">
<script>
var tempInp = document.getElementById(‘tempInp‘)
tempInp.onkeydown =function(ev){
ev=ev||window.event;
let val =this.value.trim();//trim去除字符串首位空格
let len =val.length
if(len>=6){
this.value =val.substr(0,6);
//阻止默认行为去除特殊按键
let code =ev.which ||ev.keyCode;
if(!/^(46|8|37|38|39|40)$/.test(code)){
ev.preventDefault();
}
}
}
</script>
event.stopPropagation()
& stop.stopImmediatePropagation()
event.stopPropagation()
方法阻止事件冒泡到父元素,阻止任何父事件处理程序被执行。
stop.stopImmediatePropagation()
既能阻止事件向父元素冒泡,也能阻止元素同事件类型的其他监听器被触发。而stopPropagtion
只能实现前者的效果。
<button id="btn">click me</button>
<script>
var btn =document.querySelector(‘#btn‘);
btn.addEventListener(‘click‘,function(event){
console.log(‘btn click 1‘);
event.stopImmediatePropagation();
});
btn.addEventListener(‘click‘,function(){
console.log(‘btn click 2‘)
})
document.body.addEventListener(‘click‘,function(){
console.log(‘body click‘)
})
//btn click 1
</script>
使用stop.stopImmediatePropagation()
后。点击按钮时,不仅仅body绑定事件不会触发,与此同按钮的另一个点击事件也不会触发。
event.target
& event,currentTarget
event.target
指向引起触发事件的元素,而event.currenttTarget
则是事件绑定的元素,也就是说event.currentTarget
始终是监听事件者,而event.target
是事件的真正发出者
<div id="a">
<div id="b">
<div id="c">
<div id="d">
</div>
</div>
</div>
</div>
<script>
document.getElementId(‘a‘).addEventListener(‘click‘,function(e){
console.log(‘target:’+e.target.id+‘¤tTarget:‘+e.currentTarget.id)
})
document.getElementId(‘b‘).addEventListener(‘click‘,function(e){
console.log(‘target:’+e.target.id+‘¤tTarget:‘+e.currentTarget.id)
})
document.getElementId(‘c‘).addEventListener(‘click‘,function(e){
console.log(‘target:’+e.target.id+‘¤tTarget:‘+e.currentTarget.id)
})
document.getElementId(‘d‘).addEventListener(‘click‘,function(e){
console.log(‘target:’+e.target.id+‘¤tTarget:‘+e.currentTarget.id)
})
</script>
当点击最里层的元素d的时候会依次输出
target:d¤tTarget:d
target:d¤tTarget:c
target:d¤tTarget:b
target:d¤tTarget:a
var eve =new event(‘custome‘);
ev.addEventListener(‘custome‘,function(){
console.log(‘custome‘)
})
ev.dispatchEvent(eve);
var objA ={};
objA.name =‘a‘;
objA.sayname =function(){
console.log(‘my name is‘+this.name);
}
objA.sayName();
console.log(objA.__proto__ === Object.prototype);//true
console.log(objA instanceof Object) //true
var B = function(name){
this.name =name;
this.sayname = function(){
console.log(‘my name is‘+this.name)
}
}
var objB =new B(‘b‘);
Object.create()
方法创建一个新对象,使用现有的对象来提供新创建对象的__proro__
const person = {
isHuman:false,
printIntroduction:function(){
console.log(`my name is ${this.name}. Am I human ${this.isHuman}`);
}
};
const me = Object.create(person);
me.name = "Matthew";
me.isHuman =true;
me.printIntroduction();
Object.create(proto,[propertiesObject])
proto
必填参数,是新对象的原型对象,如上面代码里新对象me
的__proto__
指向person
。注意,如果这个参数是null
,那新对象就彻彻底底是个空对象,没有继承Object.prototype
上的任何方法和属性,如hasOwnProperty()
,toString()
等var a = Object.create(null);
console.log(a);
console.log(a.__proto__);
console.log(a.__proto__ === Object.prototype);//false
console.log(a instanceof Object);false
propertiesObject
是可选参数,指定要添加到新对象上的可枚举的属性(即其自定义的属性和方法,可用hasOwnProperty()获取的,而不是原型对象上的)的描述符及相应的属性名称。var bb = Object.create(null,{
a:{
value:2,
writable:true,
configurable:true
}
});
console.log(bb);
console.log(bb.__proto__);
console.log(bb.__proto__===Object.prototype);
console.log(bb instanceof Object);
//-----------------------------------------------------------------------
var cc =Object.create({b:1},{
a:{
value:3,
writable:true,
configurable:true
}
});
console.log(cc);
console.log(cc.hasOwnProperty(‘a‘),cc.hasOwnProperty(‘b‘));
console.log(cc.__proto__);
console.log(cc.__proto__ === Object.prototype);
console.log(cc instanceof Object)
Object.create()
创建的对象原型指向传入的对象。跟字面量和new
关键字创建有区别
自己实现一个Object.create()
Object.mycreate = function(proto,properties){
function F(){};
F.prototype = proto;
if(properties){
Object.defineProperties(F,properties);
}
return new F();
}
var hh = Object.myCreate({a:11},{mm:{value:10}})
console.log(hh);
new
关键字创建的对象是Object
的实例,原型指向Object.prototype
,继承内置对象Object
Object.create(arg,pro)
创建的对象的原型取决于arg
,arg
为null
,新对象是空对象,没有原型,不继承任何对象;arg
为指定对象,新对象的原型指向对象,继承指定对象instanceof可以检测某个对象是不是另一个对象的实例:
var Person = function(){}
var student =new Person();
console.log(student instanceof Person);//true
instanceof可以检测父类型
function Person(){};
function Student(){};
var p =new Person();
Student.prototype = p; //继承原型
var s =new Student();
console.log(s instanceof Student);//true
console.log(s instanceof Person); //true
查看对象B的原型指向是否在对象A的原型链上。如果在,则返回true,如果不在返回false
实例对象属性查找属性顺序是:实例对象内部---->构造函数原型链----->实例对象父对象的原型链
var obj ={};
obj.__proto__ = F.prototype;
F.call(obj);
执行new操作符,构造函数会经历以下三个步骤:
//在ES5中没有类的概念,开发者通过原型的方法,实现了类似于类的结构
function Person(name){
this.name =name;
}
Person.prototype.sayName =function(){
console.log(`my name is ${this.name}`)
}
var p = new Person(‘haha‘);
console.log(p.sayName)//haha
//ES6中提供了class方法,实现类
class Person(name){
constructor(name){
this.name =name;
}
//定义一个方法并且赋值给构造函数的原型
sayName(){
return this.name
}
}
let p =new Person(‘haha‘);
console.log(sayName);
function Parent1(){
this.name =‘Parent1‘
}
Parent1.prototype.say = function(){
console.log(‘hello‘)
}
function Child1(){
Parent1.call(this)
this.type =‘child1‘
}
console.log(new Child1());
缺点:借助构造函数继承,不能继承父类的prototype原型上的方法
function Parent2(){
this.name =‘Parent2‘
}
Parent2.prototype.say =function(){
console.log(‘h1‘)
}
function Child2(){
this.type =‘child2‘
}
Child2.prototype =new Parent2();
console.log(new Child2());
c1 =new Child2();
c2 =new Child2();
缺点:因为原型链中的对象都是公用的,导致子类改变继承父类中的属性和方法,父类下的所有子类继承的属性和方法都会改变
function Parent3(){
this.name =‘parent3‘;
this.play =[1,2,3]
}
function Child3(){
Parent3.call(this);
this.type =‘child3‘
}
Child3.prototype =new Parent3();
var c3 =new Child3();
var c4 =new Child4();
c3.play.push(4);
console.log(c3.play,c4.play)
缺点:父类创建执行了两次,浪费了内存空间,子类的prototype指向不再是子类自己,而是指向父类
function Parent5(){
this.name =‘parent5‘;
this.play =[1,2,3]
}
function Child5(){
Parent3.call(this);
this.type =‘child5‘
}
Child5.prototype =Object.create(parent.prototype)
Child5.prototype.constructor = Child5
//ES6
class Parent{
constructor(name){
this.name =name;
}
static.sayHello(){
console.log(‘hello‘)
}
sayName(){
console.log(‘my name is‘ +this.name)
return this.name
}
}
class Child extends Parent{
constructor(name,age){
super(name);
this.age =age;
}
sayAge(){
console.log(‘my age is‘ +this.age);
return this.age
}
}
let parent = new Parent(‘Parent‘);
let child = new Child(‘Child‘, 18);
console.log(‘parent: ‘, parent); // parent: Parent?{name: "Parent"}
Parent.sayHello(); // hello
parent.sayName(); // my name is Parent
console.log(‘child: ‘, child); // child: Child?{name: "Child", age: 18}
Child.sayHello(); // hello
child.sayName(); // my name is Child
child.sayAge(); // my age is 18
标签:mod 事件模型 阶段 使用 字符串 容器 cal suv nodename
原文地址:https://www.cnblogs.com/lrgupup/p/12900227.html