DOM之事件代理(二)

目录

1.事件代理

2.一些额外的技术


1.事件代理

网页设计中的一种设计思想,利用事件对象中引用的目标对象这个技术来实现的

无论事件触发时,是不是目标对象的监听器,在监听器内部的事件对象event中都可以访问这个事件的目标对象(通过envet.target 得到触发事件的目标),利用这个特点去绑定事件给父级元素,来代理子集元素的业务,这种设计就是事件代理。

特点是:给父级元素绑定一个点击事件,通过event.target来判断是哪个子元素被点击了,以此判断点击的子元素和非点击的子元素。

<body>
    <style>
        .box1{
            background-color: darkgray;
        }
        .box2{
            width: 120px;
            height: 40px;
            background-color: firebrick;
            margin: 10px;
        }
    </style>
    <div class="box1">
        <div class="box2">hello1</div>
        <div class="box2">hello2</div>
        <div class="box2">hello3</div>
        <div class="box2">hello4</div>
    </div>
    <script>
        //业务,点击谁就打印谁的内容
        var box2s = document.querySelectorAll('.box2');
        box2s.forEach(el=>{
            el.addEventListener('click',function(e){
                console.log(this.innerHTML);
            })
        })
    </script>
</body>

分析:点击子元素就会打印出相应的内容

这样设计有两个缺点:

1.静态的事件绑定,如果动态的添加元素进去,添加进去的元素没有这个事件

<body>
    <style>
        .box1{
            background-color: darkgray;
        }
        .box2{
            width: 120px;
            height: 40px;
            background-color: firebrick;
            margin: 10px;
        }
    </style>
    <div class="box1">
        <div class="box2">hello1</div>
        <div class="box2">hello2</div>
        <div class="box2">hello3</div>
        <div class="box2">hello4</div>
    </div>
    <button id="btn" onclick="load1()">点击添加一个新子元素hello5</button>
    <script>
        //业务,点击谁就打印谁的内容
        var box2s = document.querySelectorAll('.box2');
        box2s.forEach(el=>{
            el.addEventListener('click',function(e){
                console.log(this.innerHTML);
            })
        })
        //添加新的子元素
        function load1(){
            var box1 = document.querySelector('.box1');
            var newbox2 = document.createElement('div');
            newbox2.classList = 'box2';
            newbox2.innerHTML = 'hello5';
            box1.appendChild(newbox2);
        }
    </script>
</body>

分析:点击新添加进去的子元素hello5 并不会触发点击事件,还需要重新给其添加点击事件。

这样一套操作下来就很麻烦。。。。 

2. 性能消耗更高  ,业务比较重复

像上面的代码,forEach循环只有一个,但是会生成4个监听器,给每一个子元素都.box2都设置一个,不管子元素是否触发都设置一个监听器,业务相同,设置4个,太浪费内存,也消耗性能。

利用事件代理来解决上面两个问题:

绑定事件给box2的父级box1绑定:通过事件流,

<body>
    <style>
        .box1 {
            background-color: darkgray;
        }

        .box2 {
            width: 120px;
            height: 40px;
            background-color: firebrick;
            margin: 10px;
        }
    </style>
    <div class="box1">
        <div class="box2">hello1</div>
        <div class="box2">hello2</div>
        <div class="box2">hello3</div>
        <div class="box2">hello4</div>
    </div>
    <button id="btn" onclick="load1()">点击添加一个新子元素hello5</button>
    <script>
        //业务,点击谁就打印谁的内容
        var box1 = document.querySelector('.box1');
        box1.addEventListener('click', function (e) {
            console.log(e.target.innerHTML); //根据事件流,谁触发了box1绑定的点击事件,event.target就是谁
        })
        //添加新的子元素
        function load1() {
            var box1 = document.querySelector('.box1');
            var newbox2 = document.createElement('div');
            newbox2.classList = 'box2';
            newbox2.innerHTML = 'hello5';
            box1.appendChild(newbox2);
        }
    </script>
</body>

 分析:新添加的子元素hello5,没有再去给其设置点击事件。事件代理实现了,给父级元素box1绑定一个点击事件,所有子元素都能被监听(谁触发就target指谁)。给父级元素box1绑定一个点击事件,完成了给所有子元素设置相同绑定事件的工作量。

2.一些额外的技术

1.document可以绑定事件

document虽然是一个看不到的元素,但是其是处于事件链中的一部分,可以绑定事件

        document.onclick = function(){}

2. event.target   和  event.srcElement都可以获取事件的目标对象(事件的触发者)

3.获取根元素:document.documentElement

        console.log(document.documentElement); //html

4.获取根节点:document

        console.log(document);

 

 根节点的范围比根元素更广。

5.获取body元素:document.body

        console.log(document.body); //body

 6.元素可以绑定一些自定义属性  data-自定义  data- 是固定写法

取属性的时候是  元素.dataset  固定写法取

<body>
    <div id="box5" data-blue="999" data-src1="www.123456789.com"></div>
    <script>
        var box5 = document.querySelector('#box5');
        console.log(box5.dataset);
    </script>
</body>

 分析:这些自定义属性都是在一个对象里面,它的构造函数是DOMStringMap。

7.document.write();  它所在脚本在哪个标签里面,就在哪个标签里面写内容

<body>
    <script>
        console.log(document.write('脚本script在body里面,在body里面写内容'));
    </script>
</body>

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值