DOM 事件

207 阅读1分钟

1 .DOM事件模型

 DOM事件模型是W3C制定的标准模型,既一次事件的发生包含三个过程:事件捕获阶段、事件目标阶段、事件冒泡阶段

2.事件捕获

事件的触发响应会从最外层目标一层层地向内到最内层

3.事件冒泡

事件的触发响应会从最底层目标一层层地向外到最外层

<style>
        #parent {
            position: relative;
            border: 1px solid;
            height: 300px;
            width: 300px;
            background: yellow;
        }

        #child {
            position: absolute;
            border: 1px solid;
            height: 100px;
            width: 100px;
            background: red;
            top: 300px;
            left: 200px;
            display: none;
        }
    </style>
    <body>
    <div id="parent">
        我是父元素
        <div id="child">
            我是子元素
        </div>
    </div>
    <script>
        let parent = document.getElementById('parent')
        let child = document.getElementById('child')
        parent.onclick = (e) => {
            console.log('显示啦')
            child.style.display = 'block'
        }
        window.onclick = (e) => {
            console.log('隐藏啦')
            child.style.display = 'none'
        }
    </script>
</body>

点击父元素,子元素未显示,因为事件冒泡,点击父元素会触发window,导致子元素被隐藏。

4.阻止冒泡

stopBubble函数:

function stopBubble(e) {
            //如果提供了事件对象,则这是一个非IE浏览器
            if (e && e.stopPropagation)
                //因此它支持W3C的stopPropagation()方法
                e.stopPropagation();
            else
                //否则,我们需要使用IE的方式来取消事件冒泡
                window.event.cancelBubble = true;
        }

上面例子在点击父元素时调用stopBubble(e),子元素正常显示

5.阻止默认行为

function stopDefault(e){
    if(e && e.preventDefault){
        e.preventDefault();
    }else{
        window.event.returnValue = false;
    }
}

6.事件委托

  • 利用冒泡的原理,将子元素事件加到 父元素 或 祖先元素上,触发执行效果
  • 适用于可能会新增子元素并且需要对子元素绑定事件的场景
  • 事件代理实际上是事件冒泡的一种应用

例1:

<ul id="list">
    <li>red</li>
    <li>yellow</li>
    <li>blue</li>
</ul>

点击页面中的li元素,输出li中的颜色,不用事件委托:

(function(){
    var list = document.getElementById('list');
    var colors = list.getElementsByTagName('li');
    for(var i=0;i<colors.length;i++){
        colors[i].addEventListener('click',showColor,false);
    };
    function showColor(e){
        var x = e.target;
        alert("The color is " + x.innerHTML);
    };
})();

利用事件委托:

(function(){
    var list = document.getElementById('list');
    list.addEventListener('click',showColor,false);
    function showColor(e){
        var x = e.target;
        if(x.nodeName.toLowerCase() === 'li'){
            alert('The color is ' + x.innerHTML);
        }
    }
})();

利用事件委托大量减少内存占用,减少事件注册。

例2:

<body>
 <ul id="thl">
   <li>001</li>
   <li>002</li>
   <li>003</li>
</ul>
<button onclick="fun()">touch</button>

<script>
    var thl= document.getElementById('thl');
    var aLi = thl.getElementsByTagName('li');
    for (var i = 0; i < aLi.length; i++) {
        aLi[i].onclick = fn;
    }
    
    function fn (){
       console.log(this.innerHTML);
    }

    function fun(){
   var node=document.createElement("li");
   var textnode=document.createTextNode("maomaoliang");
   node.appendChild(textnode);    document.getElementById("thl").appendChild(node);
    }
</script>
</body>

每新增元素要手动添加事件

利用事件委托:

<script>
    var thl= document.getElementById('thl');
    thl.onclick = function(e) {
        e = e || event;
        //兼容处理
        var target = e.target || e.srcElement;
        //找到li元素
        if (target.nodeName.toLowerCase() == 'li') {
              console.log(target.innerHTML);
         }
    };

    function fun(){
        var node=document.createElement("li");
        var textnode=document.createTextNode("maomaoliang");
        node.appendChild(textnode);
        document.getElementById("thl").appendChild(node);
    }
</script>

利用事件委托实现了新增元素实现动态绑定事件