JavaScript事件

事件基础

  JavaScript 事件是由访问 Web 页面的用户引起的一系列操作。
  当用户执行某些操作的时候,再去执行一系列代码。或者用来获取事件的详细信息,如鼠标位置、键盘按键等。

事件处理函数

  javaScript可以处理的事件类型为:鼠标事件、键盘事件、HTML事件
  所有的事件处理函数都会都有两个部分组成,on + 事件名称,函数体

1、鼠标事件

onclick      用户单击鼠标按钮或按下回车键时触发
ondblclick   用户双击主鼠标按钮时触发

onmousedown  用户按下鼠标还未弹起时触发
onmouseup    用户释放鼠标按钮时触发
// onmousedown和onmouseup可看做是单击鼠标事件的分解动作

onmouseover  鼠标移到某个元素上方时触发
onmouseout   鼠标移出某个元素上方时触发
onmousemove  鼠标指针在元素上移动时触发

onmouseenter  onmouseleave
也是鼠标移入移出事件,但不支持事件冒泡

2、HTML事件

onload       页面或者资源完全加载后在 window 上面触发,
	或框架集加载完毕后在框架集上触发。

onselect     用户选择文本框(input 或 textarea)中的一个或多个字符触发
onchange     文本框(input 或 textarea)内容改变且失去焦点后触发

onfocus      页面或者元素获得焦点时在 window 及相关元素上面触发	
onblur       页面或元素失去焦点时在 window 及相关元素上触发

onsubmit     用户点击提交按钮在<form>元素上触发
onreset      用户点击重置按钮在<form>元素上触发

onresize     窗口或框架的大小变化时在 window 或框架上触发
onscroll     用户滚动带滚动条的元素时触发

3、键盘事件

onkeydown    用户按下键盘上任意键触发,如果按住不放,会重复触发
onkeypress   用户按下键盘上的字符键触发,如果按住不放,会重复触发
onkeyup      用户释放键盘上的键触发

组合键ctrlkey、altkey、shiftkey
altKey属性,bool类型,表示发生事件的时候alt键是否被按下
ctrlKey属性,bool类型,表示发生事件的时候ctrl键是否被按下
shiftKey属性,bool类型,表示发生事件的时候shift键是否被按下

keyCode/which兼容  获取用户按下键盘的哪个键

贪吃蛇小案例:通过键盘上下左右键控制div的移动

<div id="outer">
	<div id="box"></div>
</div>
<script type="text/javascript">
	var oBox = document.getElementById("box");
	document.onkeydown = function(e){
		var evt = e || window.event;
		switch(evt.keyCode){
			case 37:  // 左移
				oBox.style.left = oBox.offsetLeft-20+"px";
				break;
			case 38:  // 上移
				oBox.style.top = oBox.offsetTop-20+"px";
				break;
			case 39:  // 右移
				oBox.style.left = oBox.offsetLeft+20+"px";
				break;
			case 40:  // 下移
				oBox.style.top = oBox.offsetTop+20+"px";
				break;
		}
	}
</script>

事件对象

当触发某个事件时,会产生一个事件对象,这个对象包含着所有与事件有关的信息。
包括导致事件的元素、事件的类型、以及其它与特定事件相关的信息。

通过事件绑定的执行函数是可以得到一个隐藏参数的 。
说明,浏览器会自动分配一个参数,这个参数其实就是 event 对象。

兼容性代码获取事件对象
oBox.onclick = function(e){
	var evt = e || window.event;
}

// 距离可视区域的左边距距离,上边距距离
console.log(evt.clientX,evt.clientY);
				
// 距离页面的左边距距离,上边距距离
console.log(evt.pageX,evt.pageY);
				
// 距离事件源的左边距距离,上边距距离
console.log(evt.offsetX,evt.offsetY);
		
// 距离电脑显示屏幕的左边距距离,上边距距离
console.log(evt.screenX,evt.screenY);

事件冒泡

事件流 事件的传播顺序:捕获 事件源 冒泡
事件源 直接触发某个事件的DOM对象
冒泡 事件由最特定的目标到最不特定的目标的一个传播过程

<div id="outer">
	<div id="inner"></div>
</div>
<script type="text/javascript">
	var outer = document.getElementById("outer");
	var inner = document.getElementById("inner");
	document.onclick = function(e){
		var evt = e || event;
		// 得到事件源
		console.log(evt.target || evt.srcElement);

		//兼容性的写法
		if(evt.stopPropagation){
			//针对于现代浏览器的
			evt.stopPropagation();
		}else{
			//最初是针对于IE
			evt.cancelBubble = true;
		}		
	}
</script>

事件默认行为及阻止方式

  浏览器的默认行为:JavaScript事件本身所具有的属性,例如a标签的跳转,Submit按钮的提交,右键菜单,文本框的输入等。
  阻止默认行为的方式

event.preventDefault();    //现代浏览器 不兼容IE低版本
event.returnValue = false; //针对IE,但现在很多浏览器也支持
return false;              //兼容性最好的,但return之后的代码都将不会再执行

  自定义右键菜单
oncontextmenu

document.oncontextmenu = function(e){
	var evt = e || event;
	var x = evt.clientX;
	var y = evt.clientY;
	oUl.style.display = "block";
	oUl.style.left = x + "px";
	oUl.style.top = y + "px";
}

DOM2级事件处理程序

区别:
1、DOM2级事件处理程序可以给同一DOM对象添加多个相同的事件处理函数
2、可以把事件获取方式由冒泡改为捕获

添加事件监听器:addEventListener(事件名,处理函数,布尔值)
移除事件监听器:removeEventListener(事件名,处理函数)
注意:事件名不带on,处理函数为函数指针,布尔值代表冒泡或捕获

如:element.addEventListener(“click”,foo,false);

IE下的事件监听器:
attachEvent(事件名,处理函数)
detachEvent(事件名,处理函数)
注意:事件名带on

封装事件监听函数
1、我们要给哪一个DOM对象,添加哪个类型,执行什么代码
2、浏览器兼容

function addEvent(domobj, type, fn) {
	if(domobj.addEventListener) {
		domobj.addEventListener(type, fn);
	} else {
		domobj.attachEvent("on" + type, fn);
	}
}

function removeEvent(domobj, type, fn) {
	if(domobj.removeEventListener) {
		domobj.removeEventListener(type, fn);
	} else {
		domobj.detachEvent("on" + type, fn);
	}
}

事件委托机制

  利用事件冒泡的原理,把本应添加给某元素上的事件委托给他的父级(外层)。
主要目的:给新增的元素添加相同的事件。
好处:减少事件添加的次数,减少DOM操作。提高性能。

var oUl = document.querySelectorAll("ul")[0];
oUl.onclick = function(e){
	var evt = e || event;
	//console.log(evt.target || evt.srcElement);事件源,可得到是哪个li被点击
	
	var _target = evt.target || evt.srcElement;
	//console.log(_target.nodeName);
	//toUpperCase() 字符串转大写    toLowerCase()字符串转小写
				
	if(_target.nodeName.toUpperCase()=="LI"){
		console.log("aa");
	}			
				
}

综合案例 九宫格拖拽交换位置

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			body{margin: 0;padding: 0;}
			#wrap{
				position: relative;
			}
			#wrap>div{position: absolute;
			width: 100px;height: 100px;border-radius: 10px;
			text-align: center;line-height: 100px;
			font-size: 30px;color: #000000;
			user-select : none;}
		</style>
	</head>
	<body>
		<div id="wrap"></div>
		<script type="text/javascript">
		var oWrap = document.getElementById("wrap");
		// 创建结构,三行三列
		var mt = ml = 10;
		for (var i = 0; i < 3; i++) {
			for (var j = 0; j < 3; j++) {
				var oDiv = document.createElement("div");
				oWrap.appendChild(oDiv);
				oDiv.style.left = j * (oDiv.offsetWidth + ml) + "px";
				oDiv.style.top = i * (oDiv.offsetHeight + mt) + "px";
				// 设置随机颜色
				oDiv.style.background = "rgb(" + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + "," +
					Math.floor(Math.random() * 256) + ")";
			}
		}
		// 向单元格中添加字符
		var arr = ["A", "B", "C", "D", "E", "F", "G", "H", "I"];
		var aItems = oWrap.children;
		for (var i = 0; i < aItems.length; i++) {
			aItems[i].innerText = arr[i];
		}

		// 拖拽
		for (var i = 0; i < aItems.length; i++) {
			aItems[i].onmousedown = function(e) {
				var evt = e || event;
				var x = evt.offsetX;
				var y = evt.offsetY;
				var dragItem = this;
				var cloneNode = dragItem.cloneNode();
				cloneNode.style.border = "1px solid #cecece";

				// 交换位置
				// DOM结构顺序上的位置交换
				oWrap.replaceChild(cloneNode, dragItem);

				oWrap.appendChild(dragItem);
				dragItem.style.zIndex = 1;
				document.onmousemove = function(e) {
					var evt = e || event;
					var _left = evt.clientX - x;
					var _top = evt.clientY - y;

					// 去改变拖拽对象的样式,获取这个对象时,既不能用this,也不能用aItem[i]
					// 不能用this的原因,this在这里指向document
					// 不能用aItem[i],循环结束后,i值发生了变化
					dragItem.style.left = _left + "px";
					dragItem.style.top = _top + "px";
					return false;
				}
				document.onmouseup = function() {
					var disArr = []; //保存拖拽对象和单元格之间的距离
					var newArr = [];
					// 交换位置
					for (var j = 0; j < aItems.length - 1; j++) {
						var disX = dragItem.offsetLeft - aItems[j].offsetLeft;
						var disY = dragItem.offsetTop - aItems[j].offsetTop;
						var dis = Math.sqrt(Math.pow(disX, 2) + Math.pow(disY, 2));
						disArr.push(dis);
						newArr.push(dis);
					}
					// console.log(disArr);
					// 找数组中的最小值及索引

					disArr.sort(function(a, b) {
						return a - b;
					})
					var minVal = disArr[0];
					var minIndex = newArr.indexOf(minVal);

					// 交换位置
					dragItem.style.left = aItems[minIndex].style.left;
					dragItem.style.top = aItems[minIndex].style.top;

					aItems[minIndex].style.left = cloneNode.style.left;
					aItems[minIndex].style.top = cloneNode.style.top;

					oWrap.removeChild(cloneNode);


					document.onmousemove = null;
					document.onmouseup = null;
				}
				return false;
			}
		}
	</script>
	</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值