JavaScript 进阶
1、事件流
- 事件流描述的是页面上各个元素接收事件的顺序,
- 为了描述事件的传播顺序分为两个阶段 :捕获阶段、冒泡阶段
2、DOM事件
- DOM分级别为 DOM0级、DOM1级 、DOM2级 、DOM3级
2.1 DOM0级事件绑定
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .box1{ 300px; height: 300px; background: red; } .box2{ 200px; height: 200px; background: blue; } .box3{ 100px; height: 100px; background: orange; } </style> </head> <body> <div class="box1"> <div class="box2"> <div class="box3"> </div> </div> </div> <script src="js/jquery-1.12.3.min.js"></script> <script> // //DOM 0级 只监听冒泡阶段 // $('div').get(0).onclick=function(){ // alert('box1'); // }; // $('div').get(1).onclick=function(){ // alert('box2'); // }; // $('div').get(2).onclick=function(){ // alert('box3'); // }; // document.body.onclick = function(){ // alert('body'); // }; // document.onclick = function(){ // alert('document'); // }; // window.onclick = function(){ // alert('window'); // }; // DOM0级事件不允许给元素绑定相同的事件 后面会把前面的覆盖 $('div').get(0).onclick=function(){ console.log("haha"); } $('div').get(0).onclick=function(){ console.log("xixi "); } </script> </body> </html>
总结:
- DOM0级只能监听冒泡阶段
- DOM0级事件不允许给元素绑定相同的事件 后面会把前面的覆盖
2.2 DOM1级就是DOM
2.3 DOM2级事件绑定
- DOM2级事件监听使用一个方法是: addEventListener(); add添加 ,Event 事件,Listener 监听
参数:
有三个参数:什么事件、函数、是否监听捕获阶段
- 第1个参数:事件名不用写on, click、mouseover 、mouseout
- 第2个参数:函数可以是匿名函数,也可以是有名函数
- 第3个参数:布尔值,true表示监听捕获、false表示监听冒泡阶段
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .box1{ 300px; height: 300px; background: red; } .box2{ 200px; height: 200px; background: blue; } .box3{ 100px; height: 100px; background: orange; } </style> </head> <body> <div class="box1"> <div class="box2"> <div class="box3"></div> </div> </div> <script src="js/jquery-1.12.3.min.js"></script> <script> // $('div').get(0).addEventListener('click',function(){ // console.log("box1-捕获"); // },true); // $('div').get(1).addEventListener('click',function(){ // console.log('box2-捕获'); // },true); // $('div').get(2).addEventListener('click',function(){ // console.log('box3-捕获'); // },true); // $('div').get(0).addEventListener('click',function(){ // console.log('box1-冒泡'); // }); // $('div').get(1).addEventListener('click',function(){ // console.log('box2-冒泡'); // }); // $('div').get(2).addEventListener('click',function(){ // console.log('box3-冒泡'); // }); //DOM2级事件允许给同一元素绑定相同的事件,执行顺序按照代码顺序 $('div').get(0).addEventListener('click',function(){ console.log("haha"); }); $('div').get(0).addEventListener('click',function(){ console.log("xixi"); }); </script> </body> </html>
3、低版本IE的事件绑定
- 格式:oDiv.attachEvent(“onclick”,函数);
参数:
- 第一个参数,必须写on,和addEventListener()不一样;
- 第二个参数,就是事件处理函数
- 没有第三个参数,只能监听冒泡。所以和on***写法一样
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .box{ 200px; height: 200px; background-color: skyblue; } </style> </head> <body> <div class="box" id='box'></div> <script> var box = document.getElementById('box'); // 低版本IE不支持 // box.addEventListener('click', function(){ // this.style.background = 'red'; // alert('box'); // }, false); /* // 只能监听冒泡阶段 box.attachEvent('onclick', function(){ // alert(this); // IE中this指的是window对象 // this.style.background = 'red'; // 错误 低IE不识别 // alert('box'); changeColor.call(box); }); function changeColor(){ this.style.backgroundColor = "red"; } */ // 允许给同一元素绑定多个相同事件 执行顺序与代码顺序相反 box.attachEvent('onclick',function(){ alert('1'); }); box.attachEvent('onclick',function(){ alert('2'); }); box.attachEvent('onclick',function(){ alert('3'); }); </script> </body> </html>
4、事件处理
4.1通用事件对象属性和方法
- event.type 返回事件的类型,没有on, 比如”click”
- event.target 返回你点击的最小的那个元素,即使这个元素身上没有监听,也是返回它
- event.currentTarget 返回自己,this一定和event.currentTarget是一个元素,都是自己
- event.bubbles 返回一个布尔值,表示这个事件是否冒泡
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> div{ 200px; height: 200px; background: blue; } </style> </head> <body> <div> <span>span</span> </div> <script> var box = document.getElementsByTagName('div')[0]; // box.onclick = function(event){ // console.log(event); //输出mouseEvent // console.log(event.type); //输出click // console.log(event.target); // console.log(event.currentTarget);//返回自己 // console.log(event.bubbles); //输出true // } var span = document.getElementsByTagName('span')[0]; span.onclick = function(enent){ // console.log(event); console.log(event.type); console.log(event.target); console.log(event.currentTarget); console.log(event.bubbles); } </script> </body> </html>
4.2、其他
stopPropagation() 停止传播事件流
- event.stopPropagation();
preventDefault() 阻止默认事件
- event.preventDefault();
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> body{ height: 2000px; } div{ 200px; height: 200px; background-color: skyblue; } </style> </head> <body> <div></div> <script> document.getElementsByTagName('div')[0].onmousewheel = function(event){ console.log('在div上鼠标滚动的默认事件被禁止了'); event.preventDefault(); } </script> </body> </html>
4.3 clientX、clientY、screenX、screenY
全线兼容,表示事件触发这一瞬间的鼠标位置。
- event.clientX clientX表示鼠标的位置,距离浏览器窗口左边边的距离
- event.clientY clientY表示鼠标的位置,距离浏览器窗口上边边的距离
- event.screenX screenX表示鼠标的位置,距离屏幕左边边的距离
- event.screenY screenY表示鼠标的位置,距离屏幕上边边的距离
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> body{ height: 2000px; } div{ 200px; height: 200px; background-color: skyblue; } </style> </head> <body> <div></div> <script> document.body.onclick = function(event){ console.log('clientX--' + event.clientX); console.log('clientY--' + event.clientY); console.log('screenX--' + event.screenX); console.log('screenY--' + event.screenY); } </script> </body> </html>
5、object 类型
5.1对象的创建
两种方法:
- 第一种字面量
- 第二种是new Object() (注Object O是大写)
方法一:字面量
{ }就是对象的界定符,就是对象的字面量
格式:{
k : v,
k : v,
k : v,
k : v
}
下面的特殊情况,这个k必须加引号:
k是特殊字符
k是数字
k是有空格
k是关键字、保留字
特殊形式的k,必须要加上引号,检索属性的时候,必须用方括号
json和字面量的区别:
JSON要求所有的k必须加引号,而对象字面量不需要加引号,当然加引号也不错
JSON 格式:
{
"k" : v,
"k" : v,
"k" : v,
"k" : v
}
第二种方法 :new Object()
var obj = new Object(); //这是一个空对象,里面没有任何属性
对象的属性值:
- 对象属性值,可以是任何东西。比如数字、字符串、布尔值、正则表达式、对象、数组、函数……
- 特别的,当对象的属性的值是一个函数的时候,我们称这个函数是对象的方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script> //字面量 // var obj = { // name:'zs', // age:18, // gender:'male', // } // console.log(typeof obj); // console.log(obj); // console.log(obj.name); /* 下面的特殊情况,这个k必须加引号: k是特殊字符 k是数字 k是有空格 k是关键字、保留字 */ // var obj = { // name:'zs', // 'class':10, // '234':'haha', // 'haha xixi':'oo', // } // console.log(obj.name); // console.log(obj['class']); // console.log(obj['234']); // console.log(obj['haha xixi']) // //创建出来的是一个空对象 // var obj = new Object(); // console.log(typeof obj); // console.log(obj); // //添加属性 // obj.name='zs'; // obj.age = 18; // console.log(typeof obj); // console.log(obj); var obj = { name:'zs', age:18, gender:'male', sayHello:function(){ console.log(this.name); }, haha:[1,2,3] } console.log(obj.haha); obj.sayHello(); </script> </body> </html>
5.2 对象的方法
当一个对象的属性的值,是一个函数,那么这个函数我们就称为对象的“方法”
调用函数的方式有哪些? 这些调用方式中this指什么?
- 直接用()运算符来调用函数,那么函数里面的this指的是window对象
- 函数如果绑定给了某个HTML元素的事件上,那么函数里面的this就是这个HTML对象
- 用定时器调用函数,函数内部的this就是window对象
- 用对象打点(方法)来调用函数,函数里面的this指的是这个对象
- 用apply、call,可以人工设置this是谁,百变。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div>div</div> <script> function fun(){ console.log(this); } // fun(); // 直接执行fun this指的是window // document.getElementsByTagName('div')[0].onclick=fun; //把fun绑定给元素 this指的是这个html元素 // var obj ={ // name:'zs', // haha:fun // } // obj.haha(); //用对象打点(方法)来调用函数,函数里面的this指的是这个对象 var obj = { name:'haha' } // fun(obj); //指window fun.call(obj);// {name: "haha"} 用apply、call,可以人工设置this是谁了 </script> </body> </html>
6、构造函数
JavaScript规定,一个函数可以用new关键字来调用。那么此时将按顺序发生四件事情:
- (1)隐秘的创建一个新的空对象
- (2)将这个函数里面的this绑定到刚才创建隐秘新对象上
- (3)执行函数体里面的语句
- (4)返回这个新的对象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script> // var zs ={ // name:'zs', // age:18, // gender:'male', // sayHello:function(){ // console.log(this.name + '---' +this.age); // } // } // var ls ={ // name:'ls', // age:18, // gender:'male', // sayHello:function(){ // console.log(this.name + '---' +this.age); // } // } // console.log(zs.name); // console.log(ls.name); // zs.sayHello(); // ls.sayHello(); //使用函数 // function People(){ // this.name='zs'; // this.age=18; // this.gender='male'; // this.sayHello=function(){ // console.log(this.name + '---' +this.age); // } // } // function People(){ // this.name='ls'; // this.age=19; // this.gender='female'; // this.sayHello=function(){ // console.log(this.name + '---' +this.age); // } // } // var zs = new People(); // console.log(zs); // var ls = new People(); // console.log(ls); // //执行结果都是People {name: "ls", age: 19, gender: "female", sayHello: ƒ} 结果很不完美 //使用new构造函数 function People(name,age,gender){ this.name=name; this.age=age; this.gender=gender; this.sayHello=function(){ console.log(this.name +'---'+this.age); } } var zs = new People('zs',18,'male'); var ls = new People('ls',10,'female'); console.log(zs); console.log(ls); //结果分别是 //People {name: "zs", age: 18, gender: "male", sayHello: ƒ} //People {name: "ls", age: 10, gender: "female", sayHello: ƒ} </script> </body> </html>