12、事件(下)

1、阻止右键菜单

        <style>
			#div1{
				width: 500px;
				height: 500px;
				background-color: red;
			}
			#menu{
				width: 100px;
				height: 100px;
				background-color: gray;
				position: absolute;
				display: none
			}
		</style>
		<script>

自定义右键菜单
1、阻止默认右键菜单
2、自定义右键菜单
<1>mousedown button == 2
<2>按下右键
右键菜单显示,并且移动到点击的位置
<3>按下鼠标上除右键的其他键,菜单隐藏

            window.onload = function(){

				//固定写法
				document.oncontextmenu = function(){
					return false;
				}

				var oDiv1 = document.getElementById("div1");
				var oMenu = document.getElementById("menu");

				oDiv1.onmousedown = function(event){
					var e = event || window.event;
					if(e.button == 2){
						//<1>menu显示
						oMenu.style.display = "block";
						//<2>将menu移动到鼠标点击的位置
						oMenu.style.left = e.clientX + "px";
						oMenu.style.top = e.clientY + "px";
					}else{
						oMenu.style.display = "none";
					}
				}
			}
		</script>
		
	<body>
		<div id = "div1">
			<div id = "menu">
				<ul>
					<li>选项1</li>
					<li>选项2</li>
					<li>选项3</li>
				</ul>
			</div>
		</div>
	</body>

2、阻止默认行为

            window.onload = function(){
				var oA = document.getElementById("a1");

绑定点击事件,函数中返回值为false;
window.confirm
点击确定返回true,点击取消返回false

oA.onclick = function(){
					// return false;
					var res = window.confirm("你确定要跳转吗?");
					if(res){
						return true;
					}else{
						return false;
					}
				}
			}
		</script>
	</head>
	<body>

点击a,自动进行跳转,叫做浏览器的默认行为。

        <a id = "a1" href="https://www.baidu.com">百度</a>
	</body>

3、拖拽

        <style>
			#div1{
				width: 100px;
				height: 100px;
				background-color: red;
				position: absolute;
				left: 200px;
				top: 100px
			}
		</style>
		<script>

1、mousedown
记录,被拖拽物体和,鼠标按下的相对位置,
这个相对位置,在被拖动的过程中也保持。

2、同时按下并且拖拽的时候,才能拖拽着走
mousedown mousemove
3、鼠标抬起,停止拖拽
mouseup

            window.onload = function(){
				var oDiv = document.getElementById("div1");

				drag(oDiv);
			}

			function drag(node){
				//暂存相对位置
				var offsetX = 0;
				var offsetY = 0; 
				node.onmousedown = function(event){
					//1、开始拖拽
					var e = event || window.event;

					offsetX = e.clientX - node.offsetLeft;
					offsetY = e.clientY - node.offsetTop;
					
					//2、mousemove 改变被拖拽物体的位置
					document.onmousemove = function(event){
						var e = event || window.event;
						node.style.left = e.clientX - offsetX + "px";
						node.style.top = e.clientY - offsetY + "px";

					}
					//3、当鼠标抬起,取消拖拽
					document.onmouseup = function(){
						document.onmousemove = null;
					}
				}
			}
		</script>
	</head>
	<body>
		<div id = "div1"></div>
	</body>

4、事件委托

<script>

委托:
母亲  委托方
你    代理方

事件委托:
li标签委托ul执行onclick事件。
委托方 li 收益
代理方 ul 执行

【注】li委托ul去执行onclick操作

            window.onload = function(){
				var oUl = document.getElementById("ul1");
				var aLis = oUl.getElementsByTagName("li");

背下去:
1、找到当前要添加事件的父级或者祖父节点
2、将事件绑定在父一级的标签
3、找出触发该事件的对象,进行判断

                oUl.onclick = function(event){
					var e = event || window.event;
					var target = e.target || e.srcElement;

					//这里转成全小写更准确
					if(target.nodeName.toLowerCase() == "li"){
						//判断是我们的委托方
						target.style.backgroundColor = "red";
					}
				}

1、浪费资源 解决
2、后添加的li标签,没有拥有这个onclick

                var oBtn = document.getElementById("btn1");

				var count = 5;
				oBtn.onclick = function(){
					//添加li
					var node = document.createElement("li");
					node.innerHTML = 111111111 * count++;
					oUl.appendChild(node);
				}

			}
		</script>
	</head>
	<body>
		<ul id = "ul1">
			<li>111111111</li>
			<!-- onclick -->

			<li>222222222</li>
			<!-- onclick -->

			<li>333333333</li>
			<!-- onclick -->

			<li>444444444</li>
			<!-- onclick -->
			<div>div</div>
			<span>span</span>
		</ul>
		<button id = "btn1">增加</button>
	</body>

5、事件监听器

事件监听器:
removeEventListener()
addEventListener()

removeEventListener
格式:node.removeEventListener(事件类型, 要删除的函数的名字)

addEventListener
格式:node.addEventListener(事件类型, 函数, false)
参数:第一个参数 要绑定的事件类型
第二个参数 要绑定的函数
第三个参数 false 默认值 事件冒泡 从里向外
        true 事件捕获 从外向里

            window.onload = function(){
				var oDiv = document.getElementById("div1");

				//传统的事件绑定
				/*oDiv.onclick = function(){
					alert(123);
				}*/

				/*oDiv.addEventListener("click", function(){
					alert(123);
				}, false);*/


				var aBtns = document.getElementsByTagName("button");
				//增加
				aBtns[0].onclick = function(){
					// aBtns[1].onclick = show;

					aBtns[1].addEventListener("click", show, false);
				}


				//删除
				aBtns[2].onclick = function(){
					// aBtns[1].onclick = null;
					aBtns[1].removeEventListener("click", show);

				}

				function show(){
					alert(123);
				}

			}
		</script>
	</head>
	<body>
		<!-- <div id = "div1">div</div> -->

		<button>增加点击事件</button>
		<button>按钮</button>
		<button>删除点击事件</button>
	</body>

6、传统事件问题

传统事件绑定的问题:

1、会覆盖,后添加的事件会把前面添加的事件覆盖掉。
            // alert(window.onload); //null

			window.onload = function(){
				alert(1);
			}
			/*
				【注】当window.onload绑定事件以后,数据类型会变成function。
			*/
			// alert(typeof window.onload);

			if(typeof window.onload == "function"){
				//已经添加过一次
				var save = window.onload;
				// alert(save);
			}

			//100行代码
			window.onload = function(){
				//如果save里面有函数,说明添加过
				if(save){
					save();
				}
				alert(2);
			}


			function addEvent(obj, eventType, funcName){
				if(typeof obj["on" + eventType] == "function"){
					var save = obj["on" + eventType];
				}
				obj["on" + eventType] = function(){
					if(save){
						save();
					}
					funcName();
				}
			}
        addEvent(window, "load", function(){
				alert(1);
			})
			addEvent(window, "load", function(){
				alert(2);
			})
			addEvent(window, "load", function(){
				alert(3);
			})


			//添加事件
			function addEvent(obj, eventType, funcName){
				if(typeof obj["on" + eventType] == "function"){
					var save = obj["on" + eventType];
				}
				obj["on" + eventType] = function(){
					if(save){
						save();
					}
					funcName();
				}
			}
2、this指向有问题,混乱。
        <style>
			.red{
				width: 100px;
				height: 100px;
				background-color: red;
			}
			.blue{
				width: 100px;
				height: 100px;
				background-color: blue
			}
		</style>
		<script>
			/*
				传统事件绑定的问题:
				1、会覆盖,后添加的事件会把前面添加的事件覆盖掉。
				2、this指向有问题,混乱。
			*/
			window.onload = function(){
				var oDiv = document.getElementById("div1");

				addEvent(oDiv, "click", toBlue);
				/*oDiv.onclick = toBlue;

				oDiv.onclick = function(){
					alert(123);
				}*/

				function toRed(){
					this.className = "red";
					addEvent(this, "click", toBlue);
				}

				function toBlue(){
					this.className = "blue";
					addEvent(this, "click", toRed);
				}
			}

			//添加事件
			function addEvent(obj, eventType, funcName){
				if(typeof obj["on" + eventType] == "function"){
					var save = obj["on" + eventType];
				}
				obj["on" + eventType] = function(){
					if(save){
						save();
					}
					funcName.call(obj);
				}
			}
        <script>
			var show = function(){
				alert(this);
			}

			show(); //windows

			var xiaoming = {
				name: "小明",
				xxx: show
			}

			// xiaoming.xxx();

			window.onload = function(){
				document.onclick = show;
			}
		</script>
强制改掉某一函数中的this

函数名.call(参数)
参数:函数内部,this的指向
功能:强制将函数内部的this改掉
【注】如果this传参用掉第一个参数,那么后续所有的参数向后移动一位。

        function show(num1, num2){
				alert(this);
				alert(num1 + ", " + num2);
			}

			show.call("xxxx", 10, 20);

			show.call("hello world", 10, 20);
3、too much recursion 过多的递归
        <style>
			.red{
				width: 100px;
				height: 100px;
				background-color: red;
			}
			.blue{
				width: 100px;
				height: 100px;
				background-color: blue
			}
		</style>
		<script>
			传统事件绑定的问题:
			1、会覆盖,后添加的事件会把前面添加的事件覆盖掉。
			2、this指向有问题,混乱。
			3、too much recursion 过多的递归
            window.onload = function(){
				var oDiv = document.getElementById("div1");

				var i = 0;

				addEvent(oDiv, "click", toBlue);
				/*addEvent(oDiv, "click", function(){
					alert(123);
				})*/
				
				function toRed(){
					this.className = "red";
					addEvent(this, "click", toBlue);
					document.title = i++;
				}

				function toBlue(){
					this.className = "blue";
					addEvent(this, "click", toRed);
					document.title = i++;
				}
			}

			//添加事件
			function addEvent(obj, eventType, funcName){
				if(typeof obj["on" + eventType] == "function"){
					var save = obj["on" + eventType];
				}
				obj["on" + eventType] = function(){
					if(save){
						save();
					}
					funcName.call(obj);
				}
			}
		</script>
	</head>
	<body>
		<div id = "div1" class = "red"></div>
	</body>
4、添加的函数,不能去重
        <style>
			.red{
				width: 100px;
				height: 100px;
				background-color: red;
			}
			.blue{
				width: 100px;
				height: 100px;
				background-color: blue
			}
		</style>
		<script>

传统事件绑定的问题:
1、会覆盖,后添加的事件会把前面添加的事件覆盖掉。
2、this指向有问题,混乱。
3、too much recursion 过多的递归
4、添加的函数,不能去重

function init(){
				alert(123);
			}

			addEvent(window, "load", init);
			addEvent(window, "load", init);
			addEvent(window, "load", init);

			//添加事件
			function addEvent(obj, eventType, funcName){
				if(typeof obj["on" + eventType] == "function"){
					var save = obj["on" + eventType];
				}
				obj["on" + eventType] = function(){
					if(save){
						save();
					}
					funcName.call(obj);
				}
			}
		</script>
	</head>
	<body>
		<div id = "div1" class = "red"></div>
	</body>

7、传统事件绑定

一、
1、会覆盖
2、this混乱
3、容易造成递归
4、不会去重

			事件监听器
			addEventListener
			removeEventListener

		window.addEventListener("load", function(){
			alert(123);
		}, false);

		window.addEventListener("load", function(){
			alert(456);
		}, false);

二、

        <style>
			.red{
				width: 100px;
				height: 100px;
				background-color: red
			}
			.blue{
				width: 100px;
				height: 100px;
				background-color: blue;
			}
		</style>
		<script>

1、会覆盖
2、this混乱
3、容易造成递归
4、不会去重

			事件监听器
			addEventListener
			removeEventListener
		

		window.onload = function(){
			var oDiv = document.getElementById("div1");

			oDiv.addEventListener("click", toBlue, false);

			function toBlue(){
				this.className = "blue";
				oDiv.removeEventListener("click", toBlue);
				oDiv.addEventListener("click", toRed, false);
			}
			function toRed(){
				this.className = "red";
				oDiv.removeEventListener("click", toRed);
				oDiv.addEventListener("click", toBlue, false);
			}
		}
	</script>
</head>
<body>
	<div id = "div1" class = "red">
		
	</div>
</body>

三、去重

1、会覆盖
2、this混乱
3、容易造成递归
4、不会去重

事件监听器 IE8及IE8以下不兼容
addEventListener
removeEventListener

            function init(){    
				alert(123); 
			}   
事件监听器可以去重,只输出一个。      
			window.addEventListener("load", init, false);
			window.addEventListener("load", init, false);
			window.addEventListener("load", init, false);
			window.addEventListener("load", init, false);
			window.addEventListener("load", init, false);
			window.addEventListener("load", init, false);

四、事件绑定兼容

        <script>
			addEvent(window, "load", function(){
				alert(123);
			})
			addEvent(window, "load", function(){
				alert(456);
			})

			function addEvent(obj, eventType, func){
				if(obj.addEventListener){
					obj.addEventListener(eventType, func, false);//IE不兼容
				}else{
					obj.attachEvent("on" + eventType, func);//IE
				}
			}

			function removeEvent(obj, eventType, func){
				if(obj.removeEventListener){
					obj.removeEventListener(eventType, func);//IE不兼容
				}else{
					obj.detachEvent("on" + eventType, func);//IE
				}
			}
		</script>

五、阻止默认行为(兼容)

        <script>
			window.onload = function(){
				var oA = document.getElementById("a1");
				oA.onclick = function(event){

					var e = event || window.event;

					alert(123);

1、阻止默认行为return false只能放在函数最后
2、如果想阻止默认行为以后,还想做一些别的操作,是不可能的。

                    // return false;

					// e.preventDefault(); //IE不兼容
					preDef(e);

					alert(456);
				}
			}

阻止默认行为跨浏览器兼容,超链接

            function preDef(event){
				if(event.preventDefault){
					event.preventDefault();//IE不兼容
				}else{
					event.returnValue = false;//IE
				}
			}
		</script>
	</head>
	<body>
		<!-- a标签的默认行为 -->
		<a id = "a1" href="https://www.baidu.com">百度</a>
	</body>

练习测试

1、微博(事件委托)

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Document</title>
		<style>
			*{
				margin: 0px;
				padding: 0px
			}
			#div1{
				width: 300px;
				height: 200px;
				background-color: gray;
				border: 1px solid black;
				display: none;
				position: absolute;
				left: 50px;
				top: 50px;
			}
			#title{
				width: 300px;
				height: 40px;
				background-color: blue;
				position: relative;
			}
			#text1{
				width: 298px;
				height: 158px;
			}
			#title button{
				height: 40px;
				line-height: 40px;
				font-size: 18px;
				background-color: orange;
				color: white
			}
			#close{
				position: absolute;
				right: 0px;
				width: 40px
			}
			#div2{
				width: 500px;
				height: 600px;
				border: 1px solid black;
				margin: 50px auto;
				text-align: center;
			}
			#div2 div{
				border-bottom: 1px dashed black;
				position: relative;
			}
			#div2 div button{
				position: absolute;
				right: 15px;
				height: 20px;
			}
		</style>
		<script src = "../js/tool.js"></script>
		<script>
			window.onload = function(){
				$("#issue").onclick = function(){
					//发布,显示输入框
					$("#div1").style.display = "block";
				}

				//关闭按钮,点击关闭,让输入框隐藏掉
				$("#close").onclick = function(){
					$("#div1").style.display = "none";
				}

				//发送消息
				$("#msg").onclick = msgFunc;


				//让输入框可以被拖拽
				drag($("#div1"));

				//点击ctrl+回车执行发送消息
				window.onkeydown = function(event){
					var e = event || window.event;
					if(e.keyCode == 13 && e.ctrlKey){
						msgFunc();
					}
				}




				function msgFunc(){
					//1、拿到输入框的value
					if($("#text1").value == ""){
						alert("输入不能为空");
					}else{
						//2、创建节点,将节点插入div2
						var newDiv = document.createElement("div");
						newDiv.innerHTML = $("#text1").value;
						//清空输入框的内容
						$("#text1").value = "";
						var newButton = document.createElement("button");
						newButton.innerHTML = "X";
						//将button插入到div中
						newDiv.appendChild(newButton);
						$("#div2").appendChild(newDiv);
					}
				}

				/*
					1、找到要添加事件的父节点或者祖父节点
					2、给找到父节点或者祖父节点,添加事件
					3、找到触发该事件的对象,进行判断
				*/
				$("#div2").onclick = function(event){
					var e = event || window.event;
					var target = e.target || e.srcElement;
					if(target.nodeName.toLowerCase() == "button"){
						$("#div2").removeChild(target.parentNode);
					}
				}

			}
		</script>
	</head>
	<body>
		<button id = "issue">发布</button>
		<div id = "div1">
			<div id = "title">
				<button id = "msg">发送消息</button>
				<button id = "close">X</button>
			</div>
			<textarea id="text1" cols="30" rows="10"></textarea>
		</div>
		<div id = "div2">
			<!-- <div>aasdadadadadada
				<button>X</button>
			</div>
			<div>aasdadadadadada
				<button>X</button>
			</div>
			<div>aasdadadadadada
				<button>X</button>
			</div> -->
		</div>
	</body>
</html>

2、跟随鼠标一串效果

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Document</title>
		<style>
			#div1 div{
				width: 10px;
				height: 10px;
				background-color: red;
				position: absolute;
			}
		</style>
		<script>
			window.onload = function(){
				var oDiv = document.getElementById("div1");
				var aDivs = oDiv.getElementsByTagName("div");

				document.onmousemove = function(event){
					var e = event || window.event;

					for(var i = aDivs.length - 1; i > 0; i--){
						aDivs[i].style.left = aDivs[i - 1].offsetLeft + "px";
						aDivs[i].style.top = aDivs[i - 1].offsetTop + "px";
					}
					//0的位置等于鼠标的位置
					aDivs[0].style.left = e.clientX + "px";
					aDivs[0].style.top = e.clientY + "px";
				}

			}
		</script>
	</head>
	<body>
		<div id = "div1">
			<div></div>
			<div></div>
			<div></div>
			<div></div>
			<div></div>
			<div></div>
			<div></div>
			<div></div>
			<div></div>
			<div></div>
		</div>
	</body>
</html>
posted @ 2018-07-06 20:58  飞刀还问情  阅读(165)  评论(0编辑  收藏  举报