JavaScript Event
JavaScript Event API:http://www.w3school.com.cn/jsref/dom_obj_event.asp
什么是事件驱动模型?
由事件的发生来触发程序的执行
都有哪些事件?
onclick 单击
ondblclick 双击
onmouseover 鼠标划入
onmouseout 鼠标划出
onfocus 获得焦点
onblur 失去焦点
onload 加载完成
onerror
ontimeout
onkeydown 键盘被按下
onkeypress 键盘按下并松开 , 不适用于组合键 如:ctrl 、alt
onkeyup 键盘松开
onscroll 窗口滚动
onresize 改变大小
onmousemove 鼠标的移动
onchange 内容被改变并失去焦点
Event对象是干嘛的?
有了Event,可以处理任何跟鼠标或键盘相关的信息
比如: 计算鼠标的位置,计算用户按下了哪个键?
怎么得到Event对象?
xxx.onclick = function(evt){
//use evt ...........
}
xxx.onclick = function(){
argument[0]
}
在IE中event 是由window.event获取的
兼容
function(e){
var e = e || event;
}
button属性代表什么?
代表了事件发生时,鼠标哪个键被按下
button==0 左键
button==1 滚轮
button==2 右键
clientX和clientY
鼠标在 浏览器的可视区域 的坐标(即浏览器窗口)
计算鼠标的页面绝对位置
var e = e || event;
var x = e.clientX + document.body.scrollLeft||document.documentElement.scrollLeft;
var y = e.clientY + document.body.scrollTop||document.documentElement.scrollTop; //Google|火狐
此外也可用 e.pageX和e.pageY (由Google浏览器提出较晚) ,不兼容IE8及以下
onload = function(){ document.onmousemove = function(e){ var e = e || window.event; var x = e.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft); var y = e.clientY + (document.body.scrollTop || document.documentElement.scrollTop); document.title="X: "+x+" Y:"+y; } }
offsetX和offsetY
鼠标在 当前事件触发的元素上的坐标
和键盘相关的keyCode以及组合键
keyCode 键盘的ascii码
兼容写法 which
keypress和 keydown的 区别
在google中组合键: Unicode(ctrl+enter)=10
在keypress中,对于设备控制键或组合键,例如capsLock、alt、ctrl 不会触发该事件
在keydown中,会对所有键都会触发事件,并有对应的虚拟码
在keypress中,对于alt和ctrl这样的组合键,需要通过
ctrlKey altKey 的值来判断
事件流是什么东西?
事件是可以流动的,它在触发时,默认情况下,会将事件向父元素进行传播,导致外层也被依次触发,直到页面的最顶层元素。 事件函数的执行顺序按照事件传播的顺序进行。
我们管这种现象叫做: 事件冒泡
当然,事件流能从子到父传播(冒泡)也能从父到子进行传播
什么叫冒泡
好处在哪? (事件委托机制)
把元素触发事件时要执行的动作委托给父元素来执行,应用场景:
1、需要添加事件的子元素太多 2、子元素数量不固定
注: 通过event.target属性,我们可以找到事件触发的原始对象。
坏处在哪?
事件冒泡给父元素,会导致一些不该触发的事件被触发了
怎么阻止事件传播?
event.stopPropagation() //常规浏览器,是一个方法
event.cancelBubble = true; // IE中设置,是一个boolean值默认为false
兼容性:
如何阻止右键菜单
document.oncontextmenu = function(e){
e = e || event;
e.preventDefault ? e.preventDefault() : e.returnValue = false; // 常规浏览器 || IE
}
浏览器的默认行为有哪些? 能阻止吗?
右键弹出菜单
超链接的页面跳转
按钮(button,type不一定是submit)在表单中的自动提交
e.preventDefault ? e.preventDefault() : e.returnValue = false;
拖拽原理
ele.onmousedown = function(){ document.onmousemove = function(){ //.......... } } document.onmouseup = function(){ document.onmousemove = null; }
事件捕获又是什么东西?
与事件冒泡的执行顺序相反的事件特性
从最顶层父元素依次向子元素
另外一种绑定事件的方法?
addEventListener(eventtype, func, isCapture) //IE8及以下无这个方法
参数1 : 事件的类型,注意 不加 on
参数2 : 事件需要绑定的函数
参数3 : 是否支持捕获,默认为false,即冒泡
//结果只有small03
//会弹出01 02 03 ,三个都会生效
可以给同一个元素绑定多个事件函数!!,一般多人开发的时候选用的就是以addEventListener
方式添加事件,避免覆盖别人的事件
参数三的使用:
// window document small01 big
多个事件的执行顺序和事件绑定的顺序一致
删除操作如下:
// window document
small01 big (先捕获再冒泡)
先捕获(网景对抗IE)再冒泡(IE)
small.attachEvent("onclick",function(){}) //IE8及以下
//兼容IE8及以下,无第三个参数,虽然也能重复添加同一事件,但执行顺序与添加顺序是相反的
捕获的过程(定义函数如:onclick)不会向下传播
兼容封装1://对象,事件名,方法,是否捕获 ,缺点每次使用都要判断
兼容封装2:只在加载时做一次判断(函数自运行),这也叫作:函数的柯里化
鼠标跟随示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> div{height:10px;width:10px;position:absolute;background:#000;} </style> </head> <body id="_body"> <div style="left: 341px; top: 172px;"></div> <div style="top: 172px; left: 341px;"></div> <div style="top: 69px; left: 272px;"></div> </body> <script> var _div=Array.from(document.getElementsByTagName('div'));// ES6中伪数组转为数组 document.onmousemove=function(e){ var e = e || event; var _last=_div.pop(); _last.style.top = e.clientY+"px"; _last.style.left = e.clientX+"px"; _div.unshift(_last); } </script> </html>
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>DOM操作</title> </head> <style> </style> <script src="js/common.js"></script> <body> <div id="big" style="position:absolute; width:400px; height:400px; background: #cdf"> <div id="small" style="position:absolute; left:500px; top:300px; width:200px; height:200px; background: blue"></div> </div> <script> window.onclick = function(){ alert("window"); } big.onclick = function() { alert("big"); } document.documentElement.onclick = function() { alert("html"); } document.body.onclick = function() { alert("body"); } small.onclick = function() { alert("small"); } </script> </body> </html>
(1、允许负债,2、当你的钱数为0时,从队伍中消失)
以下实现条件2
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> div{height:20px;width:40px;float:left;background:#000;color:#fff;line-height:20px;margin:10px;text-align:center;} </style> <script> onload=function(){ (function _init(){ //初始化 var frag = document.createDocumentFragment(); for(var i = 0;i <1000;i++ ){ //初始为有1000人 var tmp = document.createElement('div'); tmp.innerText="200"; //初始时每人200块钱 tmp.style.background="rgb("+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+")"; frag.appendChild(tmp); } document.body.appendChild(frag); })(); (function _play(){ var t = setInterval(function(){//定时器,每隔一秒运行一次 var div_list = Array.from(document.body.children); if(div_list.length<=2) clearInterval(t);//当数组人数小于等于2时停止定时器 div_list.forEach(function(item,index,arr){ //遍历数组 if(parseInt(arr[index].innerText)-1<0){//轮到当前这人,分钱后=0则踢出 arr[index].remove(); console.log("数组原来长度:"+div_list.length); div_list.splice(index,1); console.log("数组长度:"+div_list.length); }else{ arr[index].innerText = parseInt(arr[index].innerText)-1;// 否则钱数减一 } var index_tmp=0; while(1){ //将钱随机分给某个人(不能是本人) var index_tmp = parseInt(Math.random()*div_list.length); if(index_tmp!=index)break; } arr[index_tmp].innerText = parseInt(arr[index_tmp].innerText)+1; //获得一块 }); },1000); })(); } </script> </head> <body> </body> </html>
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> <style type="text/css"> div { width: 100px; height: 100px; background: #CCCCCC; position: absolute; left: 0px; top: 0px; } </style> <script type="text/javascript"> window.onload = function() { function Drag(obj) { this.obj = obj; this.trail = new Array(); onmousedown = function(e) { e = e || event; trail = new Array(0); trail.push({ x: obj.style.left, y: obj.style.top }); var offsetMouse = { X: e.offsetX, Y: e.offsetY } document.onmousemove = function(e) { e = e || event; obj.style.left = Math.min(window.innerWidth - obj.offsetWidth, Math.max(0, e.clientX - offsetMouse.X)) + "px"; obj.style.top = Math.min(window.innerHeight - obj.offsetHeight, Math.max(0, e.clientY - offsetMouse.Y)) + 'px'; trail.push({ x: obj.style.left, y: obj.style.top }); } }, onmouseup = function() { document.onmousemove = ""; this.fllowTrail(); }, fllowTrail = function() { //回到原点 var t = setInterval(function() { if(trail.length == 0) { clearInterval(t); return; } var item = trail.pop(); obj.style.left = item.x; obj.style.top = item.y; }, 50); } } var _div = Array.prototype.slice.call(document.body.children)[0]; var drag = new Drag(_div); console.log(drag.trail); } </script> </head> <body> <div> </div> </body> </html>
手动触发事件,例:触发window.onresize事件
// 原生 if (window.fireEvent) { // IE window.fireEvent('resize'); } else { let e = document.createEvent("Event"); e.initEvent("resize", true, true); window.dispatchEvent(e); } // jquery触发 $(window).trigger('resize');