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>