Dom_事件流(二)
- 事件流的感念
- 从外向内:捕获流
- 网景公司的工程师认为,事件流应该是捕获流
- 从内向外:冒泡流
- 微软的id就是默认使用的是冒泡流
- w3c
- 事件流
- 三个阶段
- 捕获阶段
- 处于目标阶段
- 冒泡阶段
- 目前的所有的浏览器(ie9+, 其他的高级游览器)都支持dom事件流
- 将来的事件触发,要么在冒泡阶段,要么在捕获。只能选择一个
- 默认都是在冒泡阶段触发事件
- 可以更改触发的阶段,但是一般不建议去更改,因为冒泡阶段的兼容性更好
事件
- 事情分为三个要素:
- 事件源
- 事件发生所在位置大的元素
- 事件对象
- 事件发生的信息: 坐标, 事件类型..会封装到一个对象中,
- 这个对象就是事件对象
- 游览器负责创建和封装数据进去,我们只需哟使用就可以。
- 事件处理程序(监听器)
- 当事件发生的时候,执行的代码
- 函数
- 事件发生的时候处理逻辑,全部封装这个函数中
- 事件源
- HTML事件处理程序
- 给事件源注册事件处理程序的方式不一样:
HTML事件处理程序
-
使用方式比较少
-
内容和行为不分离
-
不便于的后期的维护
<button onclick="alert('abc'); alert('abc')">abc</button> <button onclick="show()">进化</button> <script> function show(){ alert("abc") } </script>
DOM0事件处理程序 //兼容性最好
- 注册事件的时候,总是用on开头,后面跟上各种事
- btn.onclick
- btn.ondblclick
- btn.onmouseover
- 去掉dom0事件
- btn.onclick = null(undefined)
- 缺点:
-
同一个类型的事件,只能有一个事件处理程序
var btn = document.querySelector("button"); var btn2 = document.querySelector(".but"); btn.onclick = function (){ alert("abc") } btn2.onclick = function (){ btn.onclick = null; }
-
DOM2事件处理程序
-
给一个元素同时为一个事件添加多个事件处理或程序
-
可以选择触发的阶段
-
不到万不得已,不要使用捕获阶段触发
<button id="btn">一个按钮</button></div> <script> var btn = document.querySelector("#btn"); // 给元素添加监听器(事件处理程序) // 参数1:事件的类型 参数2:事件处理程序 参数3: 是否在捕获阶段触发事件 btn.addEventListener("click", function (){ console.log("button..."); }, true); document.body.firstElementChild.addEventListener("click", function (){ console.log("div....") }, true); document.body.addEventListener("click", function (){ console.log("body...") }, false); //div..button...body..
-
添加多个事件,顺序是按照源码的顺序来执行
-
也可以删除事件处理程序
-
删除的时候要和注册的时候是同一个事件处理程序(函数)
<div> <button id="btn">一个按钮</button> </div> <script> var btn = document.querySelector("#btn"); var foo = function (){ console.log("button1..."); } btn.addEventListener("click", foo); btn.addEventListener("click", function (){ console.log("button2...") }, true); // 删除这个事件处理程序 btn.removeEventListener("click", foo);
-
- ui事件
onload
// 页面加载完成之后触发
window.onload = function (){
console.log("页面加载完成")
var div = document.querySelector("div");
console.log(div); //可以访问到div
}
</script>
</head>
<body>
<div></div>
<script>
var div = document.querySelector("div");
console.log(div);
<div></div>
<img src="_" alt="">
<script>
var img = document.querySelector("img");
img.onload = function (){
console.log("图片加载完成");
}
console.log("abc") //abc 图片加载完成
-
resize事件
<script> window.onresize = function (){ //console.log("窗口的尺寸发生了变化"); var w = window.innerWidth || document.documentElement.clientWidth; var h = window.innerHeight || document.documentElement.clientHeight; console.log(w, h); } </script>
-
scroll事件
window.onscroll = function (){ console.log("你在滚动...."); // console.log(window.scrollTop, window.scrollLeft); 拿不到值 console.log(document.documentElement.scrollTop || document.body.scrollTop); } div { width: 200px; height: 300px; border: 1px solid #000; overflow: auto; } var div = document.querySelector("div"); /*setTimeout(function move(){ var start = div.scrollTop; div.scrollTop += 2; if (start == div.scrollTop) return; setTimeout(move, 20); }, 0)*/ var id = setInterval(function (){ var start = div.scrollTop; div.scrollTop += 2; console.log("aaaa") if (start == div.scrollTop){ clearInterval(id); // 停止interval只能这样停 } }, 20)
-
焦点事件
获取焦点 //onfocus
失去焦点 //onblur
-
这两个都是不冒泡
.ok { color :green; } .wrong { color: #ff0000; } </style> </head> <body> 用户名: <input type="text" autofocus><span></span> <br> <input type="text"><span></span> <script> input.onblur = function () { var userName = this.value; if(/^[a-z]\w{2,15}$/gi.test(userName)){ this.nextElementSibling.innerHTML = "✔️验证通过"; this.nextElementSibling.className = "ok"; }else { this.nextElementSibling.innerHTML = "麻烦改格式"; this.nextElementSibling.className = "wrong"; this.focus(); } }
-
onfocusin
-
onfocuout //这两个冒泡
用户名:<input type="text"> <script> var input = document.querySelector("input"); input.addEventListener("focusin", function (){ console.log("focusin...") }); document.body.addEventListener("focusin", function (){ console.log("focusin.........") })
- 鼠标事件
dblclick
- 双击事件
mouseover和mouseout //这个是冒泡的
- mouseover : 鼠标进入了某个区域
- mouseout : 鼠标从某个区域出来
不冒泡的版本:mouseenter/mouseleave
mousemove //鼠标移动的时候的触发
- 事件对象
- type: click
- target : 事件发生区域的最内部那个元素(处于目标阶段的那个元素)
- currentTarget : 事件注册在谁身上,就表示那个元素
- 和事件中this指向相同的元素
- stopPropagation(): 停止事件的进一步传播
- preventDefault():阻止事件的默认行为
- bubbles: 一个只读,查看这个事件是否冒泡
- cancelable: 事件的默认行为是否可以取消
- a标签点击之后会自动跳转到指定的地址,这就是默认行为
- eventPhase: 表示这个事件是在什么阶段触发的:
- 捕获阶段
- 处于目标
- 冒泡
- stopImmdiatePropagation()
- 即使同一个元素的其他事件也收不到了
-
id产品
<style> *{ margin: 0; padding: 0; } .product_nav{ list-style: none; width: 200px; height: 200px; background-color: pink; margin: 100px; position: relative; } .product_nav li{ width: 200px; height: 50px; background-color: gray; } .product_nav li h3{ width: 200px; text-align: center; line-height: 50px; } .product_nav li div{ position: absolute; left: 200px; top: 0; width: 400px; height: 600px; background-color: #c3c4c3; display: none; } </style> </head> <body> <ul class="product_nav"> <li> <h3>家用电器</h3> <div>家用电器详情</div> </li> <li> <h3>数码产品</h3> <div>数码产品详情</div> </li> <li> <h3>厨房用品</h3> <div>厨房用品详情</div> </li> <li> <h3>男女服装</h3> <div>男女服装详情</div> </li> </ul> <script> var h3s = document.querySelectorAll(".product_nav li"); for(var i = 0; i < h3s.length; i++){ h3s[i].onmouseenter = function (){ this.style.backgroundColor = "white"; this.lastElementChild.style.display = "block"; } h3s[i].onmouseleave = function (){ this.style.backgroundColor = "gray"; this.lastElementChild.style.display = "none"; } }
网友评论