dom事件
事件监听
DOM允许我们书写JavaScript代码以让 HTML元素对事件作出反应
什么是事件
用户与网页的交互动作
当用户点击元素时
当鼠标移动到元素上时
当文本框的内容被改变时
当键盘在文本框中被按下时
当网页已加载完毕时........
什么是监听
“监听”,顾名思义,就是让计算机随时能够发现这个事件发生了,从而执行程序员预先编写的一些程序
DOMO级事件
最简单的给元素设置事件监听的方法就是设置它们的 onxxx 属性,像这样:
oBox.onclick = function(){
//点击盒子,将执行这里的语句
}
举例
<style>
#box{
width: 100px;
height: 100px;
background-color: #333;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
let oBox = document.getElementById("box");
oBox.onclick = function(){
alert("您好,我是点击函数");
};
</script>
常见的鼠标事件监听
鼠标事件 | |
---|---|
onclick | 鼠标单击 |
ondblclick | 鼠标双击 |
oncontextmenu | 鼠标右击 ( 通常需要在触发函数中添加 ev.preventDefault()来阻止浏览器默认行为 ) |
onmouseenter(常用) | 鼠标移入 ( 只触发一次 ) |
onmouseleave(常用) | 鼠标移出 |
onmouseover(不常用) | 鼠标移入( 进入触发,进入 子元素 继续触发 ) |
onmouseout(不常用) | 鼠标移出 ( 移出时触发,遇到子元素也触发 ) |
onmousedown | 鼠标按下时 |
onmouseup | 鼠标松开时 |
onmousemove | 鼠标在区域内移动时 |
onwheel | 滚轮在区域内滚动时 |
举例
<style>
#box {
width: 100px;
height: 100px;
background-color: #333;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
let oBox = document.getElementById("box");
oBox.onclick = function () {
console.log("我是onclick");
};
oBox.ondblclick = function () {
console.log("我是ondblclick");
};
oBox.onmousedown = function () {
console.log("我是onmousedown");
};
oBox.onmouseup = function () {
console.log("我是onmouseup");
};
//触发一个click事件会依次先后触发: mousedown ==> mouseup ==> click
oBox.onmouseenter = function () {
console.log("我是onmouseenter");
};
oBox.onmouseleave = function () {
console.log("我是onmouseleave");
};
oBox.onmouseover = function () {
console.log("我是onmouseover");
};
oBox.onmouseout = function () {
console.log("我是onmouseout");
};
oBox.onmousemove = function () {
console.log("我是onmousemove");
};
</script>
常见的键盘事件监听
举例
姓名
<input type="text" id="name-field">
<script>
let nameField = document.getElementById("name-field");
//顺序为:keydown -> keypress ->keyup
nameField.onkeydown = function(){
console.log("我是onkeydown");
}
nameField.onkeypress = function(){
console.log("我是onkeypress");
}
nameField.onkeyup = function(){
console.log("我是onkeyup");
}
</script>
常见的表单事件监听
<body>
<form action="#" id="myform">
<p>
姓名:
<input type="text" id="name-field" />
</p>
<p>
年龄
<input type="text" id="age-field" />
</p>
<input type="submit">
<input type="reset">
</form>
<script>
let myForm = document.getElementById("myform");
let nameField = document.getElementById("name-field");
let ageField = document.getElementById("age-field");
nameField.onchange = function () {
console.log("你已经修改完姓名了");
};
nameField.oninput = function () {
console.log("你正在修改姓名");
};
ageField.onfocus = function () {
console.log("年龄框已经得到焦点");
};
ageField.onblur = function () {
console.log("年龄框已经失去焦点");
};
myForm.onsubmit = function(){
console.log("表单正在提交");
}
myForm.onreset = function(){
console.log("表单正在重置");
}
</script>
</body>
常见的页面事件监听
文档的加载
浏览器在加载一个页面时,是按照自上向下的顺序加载的,读取到一行就运行一行。
如果将script标签写到页面的上边,在代码执行时,页面还没有加载,页面没有加载DOM对象也没有加载,会导致无法获取到DOM对象。
onload 事件:
onload 事件会在整个页面加载完成之后才触发。为 window 绑定一个onload事件,该事件对应的响应函数将会在页面加载完成之后执行,这样可以确保我们的代码执行时所有的DOM对象已经加载完毕了。
<script type="text/javascript">
// 【方式一:先加载,后执行】这段 js 代码是写在 <head> 标签里的,所以建议放在 window.onload 里面。
window.onload = function() {
// 获取id为btn的按钮
let btn = document.getElementById("btn");
// 为按钮绑定点击事件
btn.onclick = function() {
alert("hello");
};
};
</script>
</head>
<body>
<button id="btn">点我一下</button>
<script type="text/javascript">
// 【方式二:后加载,后执行】这段 js 代码是写在 <body> 标签里的,代码的位置是处在页面的下方。这么做,也可以确保:在页面加载完毕后,再执行 js 代码。
// 获取id为btn的按钮
let btn = document.getElementById("btn");
// 为按钮绑定点击事件
btn.onclick = function() {
alert("hello");
};
//上方代码中,方式一和方式二均可以确保:在页面加载完毕后,再执行 js 代码。
</script>
</body>
事件传播
思考一个问题
研究:当盒子嵌套时事件监听的执行顺序
<style>
div {
display: flex;
margin: auto;
}
#box1 {
width: 200px;
height: 200px;
border: 1px solid black;
}
#box2 {
width: 150px;
height: 150px;
border: 1px solid black;
}
#box3 {
width: 100px;
height: 100px;
border: 1px solid black;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
<script>
let oBox1 = document.getElementById("box1");
let oBox2 = document.getElementById("box2");
let oBox3 = document.getElementById("box3");
oBox1.onclick = function () {
console.log("我是box1的onclick");
};
oBox2.onclick = function () {
console.log("我是box2的onclick");
};
oBox3.onclick = function () {
console.log("我是box3的onclick");
};
//冒泡只会触发同等类型的事件
oBox2.onclick = function(){
console.log("我是box2的onclick");
}
oBox3.onmouseenter = function(){
console.log("我是box3的onmouseenter");
}
//即使打乱顺序 也是由Box3到Box1传递 我们感觉事件传递是由内往外
</script>
实际上
事件的传播是 先从外到内 然后再从内到外
onxxx这样的写法只能监听冒泡阶段
DOM2级事件
高级事件处理方式, 一个事件可以绑定多个监听函数
DOM 2级时添加了一种新的绑定事件的方式:
addEventListener
oBox.addEventListener("click", function () {
alert("这是dom2级绑定方式", false)
})
//参数1:事件名的字符串(注意,没有on)
//参数2:回调函数:当事件触发时,该函数会被执行
//参数3:true表示捕获阶段触发,false表示冒泡阶段触发(默认)。如果不写,则默认为false。【重要】
<style>
div {
display: flex;
margin: auto;
}
#box1 {
width: 200px;
height: 200px;
border: 1px solid black;
}
#box2 {
width: 150px;
height: 150px;
border: 1px solid black;
}
#box3 {
width: 100px;
height: 100px;
border: 1px solid black;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
<script>
let oBox1 = document.getElementById("box1");
let oBox2 = document.getElementById("box2");
let oBox3 = document.getElementById("box3");
oBox1.addEventListener("click", function () {
console.log("我是box1的捕获阶段");
},true);
oBox2.addEventListener("click", function () {
console.log("我是box2的捕获阶段");
},true);
oBox3.addEventListener("click", function () {
console.log("我是box3的捕获阶段");
},true);
oBox1.addEventListener("click", function () {
console.log("我是box1的冒泡阶段");
},false);
oBox2.addEventListener("click", function () {
console.log("我是box2的冒泡阶段");
},false);
oBox3.addEventListener("click", function () {
console.log("我是box3的冒泡阶段");
},false);
//先捕获再冒泡
//最内层的元素不区分捕获还是冒泡 受顺序影响
</script>
</body>
最内部元素不再区分捕获和冒泡阶段,会先执行写在前面的监听,然后执行后写的监听
事件解绑
语法
element.removeEventListener(event, function, useCapture)
举例
<input type="button" id="btn" value="按钮">
let btn = document.getElementById("btn");
btn.addEventListener("click" , function(){
alert("事件绑定");
},false)
btn.removeEventListener("click" , function(){
alert("事件绑定")
},false)//此时不能解绑
//此时可以解绑
function clickme(){
alert("事件绑定")
}
btn.addEventListener("click" , clickme);
btn.removeEventListener("click" , clickme);
注意事项
如果给元素设置相同的两个或多个同名事件,则DOM0级写法后面写的会覆盖先写的;
而DOM2级会按顺序执行
oBox3.onclick = function(){
console.log("A");
}
oBox3.onclick = function(){
console.log("B");
}
oBox3.addEventListener("click" , function(){
console.log("C");
})
oBox3.addEventListener("click" , function(){
console.log("D");
})
//弹出BCD
事件对象event
什么是事件对象
事件处理函数提供一个形式参数,它是一个对象,封装了本次事件的细节
这个参数通常用单词event或字母e来表示
oBox.onclick = function(e){
//对象e就是这次事件的"事件对象"
}
获取 event 对象(兼容)
所有浏览器都支持event对象,但支持的方式不同
(1)普通浏览器的写法是 event
。
(2)ie 678 的写法是 window.event
。此时,事件对象 event 是作为window对象的属性保存的。
于是,我们可以采取一种兼容性的写法。如下:
event = event || window.event; // 兼容性写法
举例
<script>
document.onclick = function(event){
event = event || window.event;
console.log(event);
console.log(event.type);
}
</script>
鼠标位置
举例
<style>
*{margin: 0; padding: 0;}
body{
height: 3000px;
}
#box{
width: 200px;
height: 200px;
background-color: #333;
padding: 50px;
margin: 100px;
}
#info{
font-size: 30px;
}
</style>
</head>
<body>
<div id="box">
<!-- offsetX注意内部的盒子 计算最内层盒子指针到边界的距离-->
<div style="width: 100px; height: 100px; background-color: green;"></div>
</div>
<div id="info"></div>
<script>
let oBox = document.getElementById("box");
let oInfo = document.getElementById("info");
oBox.onmousemove = function(e){
oInfo.innerHTML = `offsetX值: ${e.offsetX} offsetY值: ${e.offsetY}<br>
clientX值: ${e.clientX} clientY值: ${e.clientY}<br>
pageX值: ${e.pageX} pageY值: ${e.pageY} `
}
</script>
</body>
e.charCode和e.keyCode属性
e.charCode属性通常用于onkeypress事件中,表示用户`输入的字符的**“字符码**”
e.keyCode属性通常用于onkeydown事件和onkeyup中,表示用户按下的按键的“键码"
<body>
<input type="text" id="field1">
<h1 id="info1"></h1>
<input type="text" id="field2">
<h1 id="info2"></h1>
<script>
let oField1 = document.getElementById("field1");
let oField2 = document.getElementById("field2");
let oInfo1 = document.getElementById("info1");
let oInfo2 = document.getElementById("info2");
oField1.onkeypress = function(e){
oInfo1.innerText = `您输入的字符的字符码是 ${e.charCode}`;
}
oField2.onkeydown = function(e){
oInfo2.innerText = `您按下的按键的键码是 ${e.keyCode}`;
}
</script>
</body>
小案例
制作一个特效:按方向键可以控制页面上的盒子移动
<style>
#box{
position: relative;
top: 200px;
left: 200px;
width: 50px;
height: 50px;
background-color: orange;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
let oBox = document.getElementById("box");
//全局变量t , l 分贝表示盒子的top和let属性值
let t = 200;
let l = 200;
//监听document对象的键盘按下事件监听 表示当用户在整个网页上按下按键的时候
/*37 左
38 上
39 右
40 下
*/
document.onkeydown = function(e){
switch (e.keyCode) {
case 37:
l -= 3;
break;
case 38:
t -= 3;
break;
case 39:
l += 3;
break;
case 40:
t += 3;
break;
}
//更改样式
oBox.style.left = l + "px";
oBox.style.top = t + "px";
};
</script>
e.preventDefault(方法
e.preventDefault()方法用来阻止事件产生的“默认动作”
—些特殊的业务需求,需要阻止事件的“默认动作”
举例
<a href="https://www.baidu.com" id="a">我是a</a>
let a = document.getElementById("a");
a.addEventListener("click" , function(e){
e.preventDefault();
alert("11")
})
小案例1
制作一个文本框,只能让用户在其中输入小写字母和数字,其他字符输入没有效果
<body>
<p>
<input type="text" id="field" />
</p>
<script>
let oField = document.getElementById("field");
oField.onkeypress = function(e){
//根据用户输入的字符的字符码(e.charCode)
//数字0~9 字符 码48~57
//小写字母a~z 字符码是97~122
if(!(e.charCode >= 48 && e.charCode <= 57 || e.charCode >= 97 && e.charCode <= 122)){ //阻止浏览器的默认行为
e.preventDefault();
}
console.log(e.charCode);
};
</script>
</body>
小案例2
制作鼠标滚轮事件:当鼠标在盒子中向下滚动时,数字加1,反之,数字减1.
鼠标滚轮事件是onmousewheel,它的事件对象e提供deltaY属性表示鼠标滚动方向,向下滚动时返回正值,向上滚动时返回负值
<style>
#box{
width: 200px;
height: 200px;
background-color: #333;
}
body{
height: 3000px;
}
</style>
</head>
<body>
<div id="box"></div>
<h1 id="info">0</h1>
<script>
let oBox = document.getElementById("box");
let oInfo = document.getElementById("info");
//全局变量就是info中显示的数字
let a = 0;
oBox.onmousewheel = function(e){
if(e.deltaY > 0){
a++;
}else{
a--;
}
oInfo.innerText = a;
//阻止默认事件 用户在盒子里面滚动鼠标滚轮的时候,此时不会引发页面的滚动条的滚动
e.preventDefault();
}
</script>
e. stopPropagation()方法
e.stopPropagation()方法用来阻止事件继续传播
在一些场合,非常有必要切断事件继续传播,否则会造成页面特效显示出bug
用法
<style>
#box {
width: 100px;
height: 100px;
background-color: #333;
}
</style>
</head>
<body>
<div id="box">
<input type="button" value="按钮" id="btn" />
</div>
<script>
let oBox = document.getElementById("box");
let oBtn = document.getElementById("btn");
oBox.onclick = function () {
console.log("我是盒子");
};
oBtn.onclick = function (e) {
//阻止事件传播
e.stopPropagation();
console.log("我是按钮");
};
oBox.addEventListener("click" , function(e){
//阻止事件传播
e.stopPropagation();
console.log("我是盒子");
},true)
oBtn.addEventListener("click" , function(e){
console.log("我是按钮");
},true)
</script>
小案例
<style>
#content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 200px;
height: 100px;
background-color: #333;
text-align: center;
line-height: 100px;
transition: 0.5s;
transform: scale(0);
}
#content.show {
transform: scale(1);
}
</style>
</head>
<body>
<input type="button" value="点我试试" id="tips" />
<div id="content">弹窗内容</div>
<script>
let oButton = document.getElementById("tips"),
oCotent = document.getElementById("content");
// 点击按钮的时候 弹出层显示
oButton.onclick = function (e) {
// 阻止事件继续传播到document上
e.stopPropagation();
oCotent.classList.add("show");
};
// 点击页面的任何部分的时候 弹出层关闭
document.onclick = function () {
oCotent.classList.remove("show");
};
// 点击弹出层内部的时候 不能关闭弹出层的 应该阻止事件继续传播
oCotent.onclick = function (e) {
//阻止事件继续传播到docuemnt身上
e.stopPropagation();
};
</script>
</body>
事件委托
(原理就是事件冒泡)
批量添加事件监听
题目:页面上有一个无序列表
<ul>
,它内部共有20个<li>
元素,请批量给它们添加点击事件监听,实现效果:点击哪个
<li>
元素,哪个<li>
元素就变红
<body>
<ul id="list">
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
</ul>
<script>
let oList = document.getElementById("list");
let aLi = oList.getElementsByTagName("li");
// 书写循环语句 批量给元素添加事件监听
for(let i = 0; i < aLi.length; i++){
aLi[i].onclick = function(){
this.style.color = "red";
}
}
</script>
批量添加事件监听的性能问题
每一个事件监听注册都会消耗一定的系统内存,而批量添加事件会导致监听数量太多,内存消耗会非常大
实际上,每个
<li>
的事件处理函数都是不同的函数,这些函数本身也会占用内存
再看一个例子
新增元素动态绑定事件
题目:页面上有一个无序列表
<ul>
,它内部没有<li>
元素,请制作一个按钮,点击这个按钮就能增加一个
<li>
元素。并且要求每个增加的<li>
元素也要有点击事件监听,实现效果点击哪个<li>
元素,哪个
<li>
元素就变红
<body>
<input type="button" value="点击添加列表项" / id="btn">
<ul id="list"></ul>
<script>
let oBtn = document.getElementById("btn");
let oList = document.getElementById("list");
// 按钮的点击事件
oBtn.onclick = function () {
// 创建一个新的li列表项 孤儿节点
let oLi = document.createElement("li");
// 写内容
oLi.innerText = "列表项";
// 上树
oList.appendChild(oLi);
// 给新创建的li节点添加事件
oLi.onclick = function () {
this.style.color = "red";
};
};
</script>
</body>
动态绑定事件的问题
新增元素必须分别添加事件监听,不能自动获得事件监听
大量事件监听、大量事件处理函数都会产生大量消耗内存
事件委托
利用事件冒泡机制,将后代元素事件委托给祖先元素
<ul id="list"> <!--监听onclick事件-->
<li>列表项</li>
<li>列表项</li> <!--不管点击任何一个li元素,事件就会通过事件冒泡传到祖先元素-->
<li>列表项</li>
<li>列表项</li>
</ul>
e.target和e.currentTarget属性
事件委托通常需要结合使用e.target属性
解决之前的批量监听和动态绑定
<body>
<input type="button" id="btn" value="点我生成新的列表项">
<ul id="list">
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
</ul>
<script>
let oList = document.getElementById("list");
oList.onclick = function (e) {
//e.target表示用户真正点击的那个元素 点击谁谁就是target 事件源
e.target.style.color = "red";
console.log(e.target);
console.log(e.currentTarget);
//e.currentTarget 事件绑定在谁身上 就是指向谁 相当于this
};
let oBtn = document.getElementById("btn");
oBtn.onclick = function(){
// 创建新的li元素
let oLi = document.createElement("li");
// 写内容
oLi.innerText = "列表项";
// 上树
oList.appendChild(oLi);
}
</script>
事件委托的使用场景
当有大量类似元素需要批量添加事件监听时,使用事件委托可以减少内存开销
当有动态元素节点上树时,使用事件委托可以让新上树的元素具有事件监听
使用事件委托时需要注意的事项
onmouseenter和onmouseover都表示“鼠标进入”,它们有什么区别呢?
onmouseenter不冒泡,onmouseover冒泡。
使用事件委托时要注意:不能委托不冒泡的事件给祖先元素
<body>
<input type="button" id="btn" value="点我生成新的列表项">
<ul id="list">
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
<li>列表项</li>
</ul>
<script>
let oList = document.getElementById("list");
// onmouseenter这个属性天生就是不冒泡的 , 相当于你事件处理函数附加了哪个Dom节点
//就是哪个Dom节点自己触发的事件 没有冒泡的过程
oList.onmouseenter = function (e) {
e.target.style.color = "red";
};
let oBtn = document.getElementById("btn");
oBtn.onclick = function(){
let oLi = document.createElement("li");
oLi.innerText = "列表项";
oList.appendChild(oLi);
}
</script>
最内层元素不能再有额外的内层元素了,比如:
<ul id="list">
<li><span>ABCD</span>列表项</li>
<li><span>ABCD</span>列表项</li>
<li><span>ABCD</span>列表项</li>
<li><span>ABCD</span>列表项</li>
</ul>
<script>
let oList = document.getElementById("list");
//点击span只要span变色
oList.onclick = function (e) {
e.target.style.color = "red";
};
</script>
以下事件不冒泡
blur、focus、load、unload、onmouseenter、onmouseleave。意思是,事件不会往父元素那里传递。
我们检查一个元素是否会冒泡,可以通过事件的以下参数:
event.bubbles
//如果返回值为true,说明该事件会冒泡;反之则相反。
举例:
box1.onclick = function (event) {
event = event || window.event;
console.log(event.bubbles); //打印结果:true。说明 onclick 事件是可以冒泡的
}
event对象跨浏览器兼容性写法
let eventUtil = {
addHandler: function (element, type, handler) {
//绑定事件
// chrome、firefox、 IE9等addEventListener
// IE8及IE8以下的浏览器attachEvent
if (element.addEventListener) {
element.addEventListener(type, handler, false)
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler)
} else {
element["on" + type] = handler;
}
},
getTarget: function (event) {
return event.target || event.srcElement;
},
preventDefault: function (event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
stopPropagation: function (event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
},
removeHander: function (element, type, handler) {
//移除事件
//chrome、firefox、 IE9等removeEventListener
//E8及IE8以下的浏览器detachEvent
if (element.addeventListener) {
element.removeEventListener(type, handler, false)
} else if (element.attachEvent) {
element.detachEvent("on" + type, handler)
} else {
element["on" + type] = null;
}
}
}
事件汇总
标事件 | |
---|---|
onclick | 鼠标单击 |
ondblclick | 鼠标双击 |
oncontextmenu | 鼠标右击 ( 通常需要在触发函数中添加 ev.preventDefault()来阻止浏览器默认行为 ) |
onmouseenter(常用) | 鼠标移入 ( 只触发一次 ) |
onmouseleave(常用) | 鼠标移出 |
onmouseover(不常用) | 鼠标移入( 进入触发,进入 子元素 继续触发 ) |
onmouseout(不常用) | 鼠标移出 ( 移出时触发,遇到子元素也触发 ) |
onmousedown | 鼠标按下时 |
onmouseup | 鼠标松开时 |
onmousemove | 鼠标在区域内移动时 |
onwheel | 滚轮在区域内滚动时 |
键盘事件 | |
---|---|
onkeydown | 键盘按下时 |
onkeyup | 键盘弹起时 |
onkeypress | 键盘按下并弹起后触发,但系统按钮无法识别( 箭头键/功能键等 ) |
oninput | 当input框内输入时触发(有兼容问题,但是好用) |
表单元素事件 | |
---|---|
<input> .onchange | 内容改变后且焦点离开后触发 |
<input> .onfocus | 获得焦点时触发 |
<input> .onblur | 失去焦点时触发 |
<input> .onselect | 当select下拉框选择后触发 |
<form> .onsubmit | 当表单提交时 |
<form> .onreset | 当表单重置时 |
系统事件 | |
---|---|
onload | 页面加载完成后 |
onerror | 页面加载出错后 |
onresize | 浏览器窗口大小改变时 |
onscroll | 页面滚动条滚动时 |
eventUtil.addHandler(myBtn, "mousedown", function (event) {
console.log("mousedown");
console.log(event.button) //区分浏览器
// event.button == 0 鼠标左键
//event.button == 1 鼠标中键
//event.button == 2 鼠标右键
resize 事件
当浏览器窗口被调整到一个新的高度或宽度时,就会触发resize事件。
eventUtil.addHandler(window, "resize", function(event){
alert("Resized");
});
scroll事件
body{
height:2000px;
}
eventUtil.addHandler(window, "scroll", function (event) {
alert("scrolled")
});
mouseenter
光标从元素外部首次移动到元素范围之内时触发,这个事件不冒泡,而且在鼠标移动到后代元素上也不会触发
var div = document.getElementById("div");
eventUtil.addHandler(div, "mouseenter", function(event){
console.log("mouseenter")
})
//只能进入目标元素时候才去触发
mouseleave
鼠标光标移动到元素范围之外时触发。这个事件不冒泡,而且在鼠标移动到后代元素上也不会触发
eventUtil.addHandler(div, "mouseleave", function (event) {
console.log("mouseleave ")
})
//只能离开目标元素时候才去触发
mouseover
在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边界之内时触发
eventUtil.addHandler(div, "mouseover", function(event){
console.log("mouseover")
})
//进入目标元素或者其子元素的时候执行
mouseout
在鼠标指针位于一个元素上方,然后用户将其移动到另一个元素时触发
eventUtil.addHandler(div, "mouseout", function(event){
console.log("mouseout")
})
//离开目标元素或者其子元素的时候执行
mousemove
当鼠标指针在元素内部移动时重复地触发
EventUtil.addHandler(myBtn, "mousemove", function(event){
console.log("mousemove")
})
focusin
同focus一样 但是它支持冒泡
eventUtil.addHandler(input, "focusin", function(event){
console.log("元素获取焦点的时候触发,支持事件浏览器是IE5.5+,Safari5.1+,chrome等");
});
focuout
同blur一样 支持冒泡
EventUtil.addHandler(input, "focuout", function(event){
console.log("元素失去焦点的时候触发,支持事件浏览器是IE5.5+,Safari5.1+,chrome等");
});
元素增删事件
<input type="text" id="Input">
<ul id="myList">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
<script>
let Input = document.getElementById("Input");
let li = document.getElementsByTagName("li");
let myList = document.getElementById('myList');
eventUtil.addHandler(document, "DOMNodeRemoved", function (event) {
console.log(1111);
})
document.body.removeChild(myInput);
// document中任意元素被删除就会触发
// myList任意元素被删除都会触发
eventUtil.addHandler(myList , "DOMNodeRemoved" , function(event){
console.log(1111);
})
myList.removeChild(li[1])
</script>
//DOM结构中发生任何变化都会触发
eventUtil.addHandler(document, "DOMSubtreeModified", function(event) {
console.log(111111);
})
document.body.removeChild(Input)
// 从文档中移除之前被触发
eventUtil.addHandler(myInput, "DOMNodeRemovedFromDocument", function (event) {
console.log(111111);
})
document.body.removeChild(Input);
//document中任意元素被添加就会触发
let item = document.createElement("li");
eventUtil.addHandler(document, "DOMNodeInserted", function(event) {
console.log(111111);
})
document.body.append(item);
eventUtil.addHandler(myList, "DOMNodeInserted", function (event) {
console.log(111111);
})
myList.append(item);
//在DOM树结构之后就会触发
eventUtil.addHandler(document, "DOMContentLoaded", function (event) {
console.log("DOMContentLoaded速度一定快于load事件");
})
//readstatechange 支持IE、firfox、opera,提供文档或者元素加载过程,但是很难预料与load事件一起使用时候
//1、document.readState == uninitialized 尚未初始化
//2、loading 对象正在加载数据
//3、interactive 可以操作对象,单还没有完全加载
//4、对象已经加载完毕
eventUtil.addHandler(document, "readstatechange", function (event) {
console.log(111111);
//情绪化,限制IEfox.很难预料
})
//hashchange事件 只能给window添加 , #后面的值变化
eventUtil.addHandler(window, "hashchange", function (event) {
console.log(event.oldURL + "这是新地址" + event.newURL);
})
let div = document.getElementById("myDiv");
eventUtil.addHandler(div, "click", function (event) {
var keys = new Array();
if (event.shiftKey) {
keys.push("shift");
}
if (event.ctrlKey) {
keys.push("ctrl");
}
if (event.altKey) {
keys.push("alt");
}
if (event.metaKey) {
keys.push("meta");
}
console.log("keys:" + keys.join(","));
});
//监测点击时候是不是按下了这些键位