美文网首页
2023-03-17_DOMDAY04-Dom0和Dom2以及事

2023-03-17_DOMDAY04-Dom0和Dom2以及事

作者: 远方的路_ | 来源:发表于2023-03-16 21:29 被阅读0次

1. DOM0事件绑定和解绑

  • DOM0高级浏览器中同一个对象 绑定同一个事件 那么会覆盖
  • DOM0事件解绑 本质上就是把事件回调函数和事件对象的事件属性断开指向
    box.onclick= null

2. Dom2事件绑定和解绑

前提:DOM2事件添加和解绑高低浏览器使用的方法是不同的

  • 高级浏览器

    • 添加事件监听1
      (1)添加事件监听类型
      (2)回调函数
box.addEventListener('click',function(){
    console.log('老马去红浪漫');
});
  • DOM2高级浏览器 同一个对象绑定同一个事件的执行顺序是从上到下依次执行的
  • 添加事件监听方法2 (函数定义在外边以便变量来调用 )
function fn(){
    console.log('马斯托洛夫斯基');
}
box.addEventListener('click',fn);

function fn1(){
    console.log('马坚强');
}
box.addEventListener('click',fn1);
  • Dom2事件的解绑
    • DOM2事件解绑的时候,参数必须和绑定的时候一模一样
    • 如果DOM2事件要解绑,那么就不能在方法内部去定义回调函数,必须添加的时候在外部定义有名函数
btn.onclick = function(){
    box.removeEventListener('click',function(){
        console.log('布鲁斯马!');
    });
}  //解绑不了,因为回调函数和绑定的虽然看着一样,但是不是同一个函数
function fn(){
    console.log('杰森斯坦马');
}
box.addEventListener('click',fn);                           
btn.onclick = function(){
    box.removeEventListener('click',fn);
}
  • 低级浏览器

    • 添加事件监听1
//低级浏览器
//添加事件监听
box.attachEvent('onclick',function(){
    console.log('哈哈');
})              
  • 如果添加多个事件,那么也会依次执行,只不过执行顺序和高级浏览器相反
  • 添加事件监听2
function fn1(){
    console.log('嘿嘿');
}
box.attachEvent('onclick',fn1);
  • 解绑方式
function fn1(){
    console.log('嘿嘿');
}
box.attachEvent('onclick',fn1);
btn.onclick = function(){
        box.detachEvent('onclick',fn1);
}
DOM0和DOM2.jpg

3. 事件流

3.1 DOM0事件的事件流(默认冒泡)

  • Dom0事件的事件流都是冒泡,没有捕获
  • 整体事件流会由最里层---子元素---父元素---body---html---document---window
  • DOM0事件取消冒泡的三种方法(高级浏览器)
    • 方法1
      event.cancelBubble = true;
    • 方法2
      event.stopPropagation();
    • 方法3
      event.stopImmediatePropagation();
  • DOM0事件低级浏览器中取消冒泡方法
    • 只有这个方法可以取消冒泡 event.cancelBubble = true;
      低级浏览器的event对象中没有stopPropagation
      低级浏览器的event对象中没有stopImmediatePropagation
    • event高级浏览器可以直接使用
            低级浏览器中的事件对象是window.event
            兼容性写法: event = event || window.event;

3.2 DOM2事件的事件流(默认冒泡)

  • DOM2高级浏览器
    • DOM2整体事件流会由最里层---子元素---父元素---body---html---document---window
    • DOM2事件取消冒泡的三种方法(高级浏览器)
      • 方法1
        event.cancelBubble = true;
      • 方法2
        event.stopPropagation();
      • 方法3
        event.stopImmediatePropagation();
    • DOM2事件-捕获事件流接收第三个参数true
    • 捕获整体事件流会由最外层---window---document----html---body---父元素---子元素
    • 取消捕获事件以上三种方法均可 一般使用的是event.stopImmediatePropagation();
  • DOM2低级浏览器
    • DOM2整体事件流会由最里层---子元素---父元素---body---html---document---window
    • DOM2的低级浏览器 可以直接使用event对象
      取消冒泡只有一种 event.cancelBubble = true;

总结:DOM0事件及低级浏览器的DOM2事件(没有第三个参数)都是只有冒泡,以后用的最多的也是冒泡,捕获几乎不用,高级浏览器的DOM2事件可以根据第三个参数选择是捕获还是冒泡,一般都不写,默认是冒泡


4. 事件委派

4.1 什么是事件委派

  • 事件委派过程当中依赖了事件冒泡
  • 事件冒泡的好处就是可以进行事件委派(事件委托,事件代理);
  • 把子元素的事件监听添加给父(祖先)元素,把子元素发生的事件委托给父元素进行处理

4.2 事件委派用法

  • 使用事件委派的情况有且仅有2种
    • 1:当新添加的对象 想要具备老的对象的方法的时候, 此时就想事件委派;不用事件委派,老对象身上会有想要的行为,而新添加的没有

    • 2:当对象很多 并且每一个对象都绑定了相同的事件对象的时候

      因为内存浪费的问题 所以要使用事件委派

  • 事件委派的作用:可以大大降低内存的占用,并且可以提高效率。

总结 :
  事件委派其实是借用事件冒泡去做的,因为事件冒泡导致内部所有的元素发生事件都会冒泡到祖先身上,我们不在子元素身上去添加事件监听和处理,而是在共同的祖先身上去添加,让祖先去处理子元素发生的事件;祖先去处理其实就是通过事件对象当中的target 去获取到真正发生事件的子元素;对子元素进行处理
  可以通过事件对象的target属性来找到你真实操作的那个标签
  通过target的nodeName就知道我移入的是哪个标签(大写标签 eg: UL/LI/SPAN)

  • 案例练习 --- 新添加对象具备老对象属性
<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="UTF-8" />
        <title>事件委派-为什么要学习事件委派</title>
    </head>
    <body>
        <ul>
            <li>红酒搓</li>
            <li>牛奶搓</li>
            <li>醋搓</li>
            <li>辣椒搓</li>
        </ul>

        <button>添加</button>

        <script>
            var btn = document.querySelector('button');
            var ul = document.querySelector('ul');

            // 点击按钮之后给ul添加li
            btn.onclick = function(){
                var li = document.createElement('li');
                li.innerHTML = '搓搓搓';

                ul.append(li);
            }
            ul.onmouseover = function(event){
                if(event.target.nodeName == 'LI'){
                    event.target.style.backgroundColor = 'skyblue';
                }
            }
            ul.onmouseout = function(event){
                if(event.target.nodeName == 'LI'){
                    event.target.style.backgroundColor = '';
                }
            }
            // 高亮
            // 注意 今天我们使用的移入移出 是onmouseover onmousepout
            // var li_list =document.querySelectorAll('li');
            // console.log(li_list.length);

            // for(var i = 0; i < li_list.length; i++){
            //     li_list[i].onmouseover = function(){
            //         this.style.backgroundColor = 'yellowgreen';
            //     }

            //     li_list[i].onmouseout = function(){
            //         this.style.backgroundColor = '';
            //     }
            // }
        </script>
    </body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="UTF-8" />
        <title>事件委派-移入的标签的内部还有标签</title>
    </head>
    <body>
        <ul>
            <li>麻婆豆腐</li>
            <li>青椒皮蛋</li>
            <li>蒜苗回锅肉</li>
            <li>
                <span>香菜牛肉</span>
            </li>
        </ul>
        <script>
            var ul = document.querySelector('ul');

            ul.onmouseover = function(event){
                if(event.target.nodeName == 'LI'){
                    event.target.style.backgroundColor = 'skyblue';
                }else if(event.target.parentElement.nodeName == 'LI'){
                    event.target.parentElement.style.backgroundColor = 'skyblue';
                }
            }

            ul.onmouseout = function(event){
                if(event.target.nodeName == 'LI'){
                    event.target.style.backgroundColor = '';
                }else if(event.target.parentElement.nodeName == 'LI'){
                    event.target.parentElement.style.backgroundColor = '';
                }
            }
        </script>
    </body>
</html>

5. 两对移入移出区别

  • onmouseover/onmouseout 如果涉及到事件切换或者冒泡必须使用双o

    如果是一个父子元素模型,对父元素添加移入和移出,当鼠标移入父元素里面的子元素的时候,事件会移出然后再移入。也就是说事件元素会有切换;事件委派的时候,必须使用这一对,大部分的时候我们使用的事件流都是冒泡,冒泡一定会涉及到事件的切换,所以我们常用双o事件;

  • onmouseenter/onmouseleave

    如果是一个父子元素模型,对父元素添加移入和移出,当鼠标移入父元素里面的子元素的时候,
    事件并没有移出然后再移入。也就是说事件元素没有切换;

  • 企业级开发中大部分使用的是onmouseenter/onmouseleave 因为不会发生事件切换 不会影响动态效果

    使用双o在部分浏览器下会发生卡顿现象。如果使用冒泡必须使用双o

  • 案例练习 --- 表格的增删改查
<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="UTF-8" />
        <title>13_作业</title>
        <style>
            .container {
                width: 800px;
                height: 500px;
                border: 1px solid #000;
                margin: 50px auto;
                padding: 15px;
            }
            table {
                table-layout: fixed;
                text-align: center;
                table-layout: fixed;
                border-collapse: collapse;
                width: 600px;
                margin: 30px auto;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <!-- <form action="#"> -->
                <label> 姓名: <input type="text" id="name"/> </label>
                <label> 年龄: <input type="text" id="age"/> </label>
                <label> 性别: <input type="text" id="gender"/> </label>
                <button id="btn">添加</button>
            <!-- </form> -->
            <table border="1">
                <tr>
                    <th>姓名</th>
                    <th>年龄</th>
                    <th>性别</th>
                    <th>操作</th>
                </tr>
                <tr>
                    <td>马大</td>
                    <td>18</td>
                    <td>男</td>
                    <td>
                        <a href="#">删除</a>
                    </td>
                </tr>
                <tr>
                    <td>马二</td>
                    <td>16</td>
                    <td>男</td>
                    <td>
                        <a href="#">删除</a>
                    </td>
                </tr>
            </table>
        </div>
        <script>
            var addBtn = document.querySelector('#btn')
            var tableTbody = document.querySelector('table tbody')
            
    addBtn.addEventListener('click', function() {
                // (1) 获取文本框中的内容
                var input = document.querySelectorAll('input')
                // name
                var nameVal = input[0].value
                // age
                var ageVal = input[1].value
                // gender
                var genderVal = input[2].value
                
                var tr = document.createElement('tr')

                var td_name = document.createElement('td')
                td_name.innerHTML = nameVal
                tr.append(td_name)

                var td_age = document.createElement('td')
                td_age.innerHTML = ageVal
                tr.append(td_age)

                var td_gender = document.createElement('td')
                td_gender.innerHTML = genderVal
                tr.append(td_gender)

                // 有bug  超链接没有小手  因为没有href
                // var a = document.createElement('a');
                // // a.href = '#';
                // a.innerHTML = '删除';

                // var td = document.createElement('td');
                // td.append(a);

                // tr.append(td);
                var td_del = document.createElement('td')
                td_del.innerHTML = '<a href="#">删除</a>'
                tr.append(td_del)
                
                tableTbody.append(tr)

            })
            // 老对象可以实现 新增对象不生效 无法删除 需要事件委派
            // var a_list = document.querySelectorAll('a');
            // for(var i = 0; i < a_list.length; i++){
            //     a_list[i].onclick = function(){
            //         this.parentElement.parentElement.remove();
            //     }
            // }

            tableTbody.onclick = function(event) {
                if (event.target.nodeName == 'A') {
                    var flag = confirm('你确定要删除嘛?')
                    if (flag) {
                        event.target.parentElement.parentElement.remove()
                    }
                }
                
            }
        </script>
    </body>
</html>

相关文章

  • DOM事件流以及DOM2

    事件流 事件流描述的是从页面中接受事件的顺序。目前有三种事件流模型: 1. IE的事件冒泡: 事件开始时由最具体的...

  • 2018-12-27

    第12章 DOM2和DOM3 DOM1级主要定义的是HTML和XML文档的底层结构。DOM2和DOM3则在这个结构...

  • JavaScript 高级程序设计(第12章 DOM2和DOM3

    第12章 DOM2和DOM3 DOM2 级核心(DOM Level 2 Core):在 1 级核心基础上构建,为节...

  • 十八

    DOM2和DOM3DOM1级主要定义的是HTML和XML文档的低层结构。DOM2和DOM3级则在这个结构的基础上引...

  • addEventListener与attachEvent区别

    DOM2级事件处理程序 DOM2级事件定义了两个方法用于处理指定和删除事件处理程序的操作: addEventLis...

  • 事件处理程序

    HTML事件处理程序 HTML程序和JS无法分离 DOM0级事件处理程序 DOM2级事件处理程序 DOM2级事件定...

  • 事件

    DOM0 事件和DOM2级在事件监听使用方式上有什么区别? DOM0级事件处理方式:通过javascript制定事...

  • 进阶9 事件

    DOM0 事件和DOM2级在事件监听使用方式上有什么区别? DOM0级事件处理方式:通过javascript制定事...

  • 事件

    题目1: DOM0 事件和DOM2级在事件监听使用方式上有什么区别? DOM2级事件特点:1)存在两个方法,用于处...

  • 事件

    1. DOM0 事件和DOM2级在事件监听使用方式上有什么区别? DOM2级事件特点: 存在两个方法,用于处理制定...

网友评论

      本文标题:2023-03-17_DOMDAY04-Dom0和Dom2以及事

      本文链接:https://www.haomeiwen.com/subject/hvudrdtx.html