dom事件模型分为脚本模型,内联模型和动态绑定三种。javascript
<html>
<body>
<!--行内绑定:脚本模型-->
<div onclick="javascrpt:alert('eventType1')" id="eventType1">脚本模型</div>
<!--内联模型: 屡次声明,只能绑定一次,后声明,后生效-->
<div onclick="sayType" id="eventType2">内联模型</div>
<!--动态绑定:能够绑定屡次,均可生效-->
<div id="eventType3">动态绑定</div>
</body>
<script> function sayType(){ alert('eventType2-1') } // 会覆盖以前的事件声明 document.getElementById('eventType2').onclick = function(){ alert('eventType2-2') } var eventType3Dom = document.getElementById('eventType3') eventType3Dom.onclick = function(){ alert('eventType3-1') } // 生效 eventType3Dom.addEventListener('click',function(){ alert('eventType3-2') }) // 生效 eventType3Dom.addEventListener('click',function(){ alert('eventType3-2') }) </script>
</html>
复制代码
DOM结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所通过的结点都会收到该事件,这个传播过程可称为DOM事件流。DOM同时支持两种事件模型:捕获型事件和冒泡型事件。html
"DOM2事件流"规定的事件流包括三个阶段:事件捕获阶段,处于目标阶段,事件冒泡阶段。java
document对象首先接收到事件,而后事件沿着DOM树依次向下,一直传播到事件的实际目标。浏览器
事件捕获的用意在于在事件到达预约目标以前就捕获它。给addEventListener
第三个参数传入true
便可监听捕获事件。app
<html>
<body>
<div id="div">div</div>
</body>
<script> document.getElementById('div').addEventListener('click',function(){ alert('div') },true) document.addEventListener('click',function(){ alert('html') },true) document.body.addEventListener('click',function(){ alert('body') },true) </script>
</html>
复制代码
依次打印html body div
dom
事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,而后逐级向上传播到较为不具体的节点。函数
<html>
<body>
<div id="div">div</div>
</body>
<script> document.getElementById('div').addEventListener('click',function(){ alert('div') },true) document.addEventListener('click',function(){ alert('html') },true) document.body.addEventListener('click',function(){ alert('body') },true) </script>
</html>
复制代码
依次打印div body html
性能
function stopBubble(e) {
//若是提供了事件对象,则这是一个非IE浏览器
if ( e && e.stopPropagation ) {
//所以它支持W3C的stopPropagation()方法
e.stopPropagation();
} else {
//不然,咱们须要使用IE的方式来取消事件冒泡
window.event.cancelBubble = true;
}
}
复制代码
function stopDefault( e ) {
//阻止默认浏览器动做(W3C)
if ( e && e.preventDefault ) {
e.preventDefault();
//IE中阻止函数器默认动做的方式
} else {
window.event.returnValue = false;
}
return false;
}
复制代码
事件委托就是利用事件冒泡,只指定一个事件处理程序,就能够管理某一类型的全部事件。优化
<ul id="parent">
<li class="child">one</li>
<li class="child">two</li>
<li class="child">three</li>
</ul>
<script> //父元素 var dom= document.getElementById('parent'); //父元素绑定事件,代理子元素的点击事件 dom.onclick= function(event) { var event= event || window.event; var curTarget= event.target || event.srcElement; if (curTarget.tagName.toLowerCase() == 'li') { //事件处理 } } </script>
复制代码
局限性:ui
规定在一个单位时间内,只能触发一次函数。若是这个单位时间内触发屡次函数,只有一次生效。
function throttle(fn,delay){
var flag = true;
var _this = this;
return function(){
if (flag === false) {
return;
}
flag = false;
var args = arguments;
setTimeout(function(){
fn.apply(_this, args);
flag = true;
},delay || 500);
}
}
// onsize事件
window.onresize = throttle(function (e) console.log(123); }, 500) 复制代码
在事件被触发n秒后再执行回调,若是在这n秒内又被触发,则从新计时。
<button id="button">连续点击</button>
<script> function debounce (fn, delay){ var timer = null; var _this = this; return function(){ var args = arguments; clearTimeout(timer); timer = setTimeout(function(){ fn.apply(_this, args); },delay || 500); } } // 500ms只执行一次 document.getElementById('button').addEventListener('click',debounce(function(){ console.log(123) })) </script>
复制代码