array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 javascript事件委托和jquery事件委托 - 爱码网
oxiaojiano

元旦过后,新年第一篇。
初衷:很多的面试都会涉及到事件委托,前前后后也看过好多博文,写的都很不错,写的各有千秋,自己思前想后,为了以后自己的查看,也同时为现在找工作的前端小伙伴提供一个看似更全方位的解读事件委托的地方来认识了解他的原理,本篇文章汇总了两个版本的事件委托:javascript、jquery;

事件委托的定义:

利用事件冒泡,指定一个事件处理程序,就可以管理某一类型的所有事件。

事件委托的优势:

  • 在js中添加到页面上的事件处理程序的个数直接影响到网页的运行性能。因为每个事件处理函数都是一个对象,是对象就会占用内存,而内存中对象越多,导致的结果就是性能越差;而访问dom的次数越多,就会引起结构的重绘或者重排的次数也随之增多,会延迟整个页面的交互就绪时间;
  • 对于在页面进行处理过后新增的dom元素,运用事件委托可以为新增的dom元素一并增减事件处理程序;

    在下面的代码中p标签要实现的效果是鼠标点击p标签的时候背景色变为红色,以下是js、jq的处理方法

<body>
    <div id="nodes">
      <P class="node_p">第一个p</P>
      <P class="node_p">第二个p</P>
      <P class="node_p">第三个p</P>
      <div id="childDiv">
          <p>这是子集菜单</p>
          <div>我是子集的div
              <p>我是子集的p</p>
          </div>
      </div>
    </div>
    <button>点击加一</button>
  </body>

一、js事件委托

在js中不用事件委托的情况:获取页面中所有的p标签然后用for循环遍历给每一个元素增加事件处理函数

let nodes = document.getElementById("nodes");
    let ps = document.getElementsByTagName("p");
    console.log(ps);
    let btn = document.getElementsByTagName("button")[0];
    let inner = 33;

    btn.onclick = function() {
      inner++;
      let p = document.createElement("p");
      p.innerHTML = inner + "新增的p标签啊";
      nodes.appendChild(p);
      console.log(ps);
    };
    for (let i= 0;i<ps.length;i++){
        ps[i].onclick= function(){
            this.style.background = 'red'
        }  
    }

这时候在浏览器中运行之后进行测试,发现如图一所示的结果;
图一
那么js不用事件委托怎么给新增加的标签添加事件处理函数呢?解决方案如下:

let nodes = document.getElementById("nodes");
    let ps = document.getElementsByTagName("p");
    console.log(ps);
    let btn = document.getElementsByTagName("button")[0];
    let inner = 33;

    btn.onclick = function () {
        inner++;
        let p = document.createElement("p");
        p.innerHTML = inner + "新增的p标签啊";
        nodes.appendChild(p);
        addEvent();//将新dom元素增加到页面后再执行循环函数
        console.log(ps);
    };

    function addEvent() {
        for (let i = 0; i < ps.length; i++) {
            ps[i].onclick = function () {
                this.style.background = 'red'
            }
        }
    }
    addEvent() //先执行一遍循环

这时候浏览器中运行如图二所示:
图二
这时候虽然解决了为新增dom元素增加事件处理函数的问题,但是仔细考虑他的性能却是比之前都有所下降,究其原因就是又增加了一个事件处理函数(对象),又一次占用了内存;所以,这个时候就会用但事件委托,这时候事件委托的优势也有所体现出来:

let nodes = document.getElementById("nodes");
    let ps = document.getElementsByTagName("p");
    console.log(ps);
    let btn = document.getElementsByTagName("button")[0];
    let inner = 33;

    btn.onclick = function () {
        inner++;
        let p = document.createElement("p");
        p.innerHTML = inner + "新增的p标签啊";
        nodes.appendChild(p);
        console.log(ps);
    };
//事件委托,为nodes指定一个事件处理函数,处理nodes下为p标签的所有元素的cilck事件
    nodes.onclick= function(e){
        let ev = e || window.event
        let target = ev.target || ev.srcElement //srcElement IE浏览器
        //这里要判被处理元素节点的名字,也可以增加相应的判断条件 target.nodeName.toLowerCase() == 'p'||target.nodeName.toLowerCase() == 'span',但是要注意不要使用父级元素的名称,因为再点击子元素之间的空气的时候,由于事件冒泡他会给父级元素也增加相应的事件处理函数;因为返回的节点名称一般都是大写,所以这时要用toLowerCase()处理一下;
        if(target.nodeName.toLowerCase() == 'p'){ 
            target.style.background = 'green'
        }
    }

这时候浏览器中运行的结果如图三所示:
图三

二、jquery事件委托:

相较于js事件委托,jquery事件委托的优势:执行事件委托的时候只有子元素会触发事件函数,而代为执行的父元素不会触发时间函数,因此不用去判断元素节点的名称;
这里nodes节点下所有标签为p的子节点都被赋予事件处理函数;这里的子节点还可以是多个类似' p,span',需要注意这里面也不可以写同nodes一样的标签,否则点击元素之间的间隔会给nodes下的div赋予事件处理函数;如例二:
例一:

let inner = 33;
//这里nodes节点下所有标签为p的子节点都被赋予事件处理函数;这里的子节点还可以是多个类似' p,span',需要注意这里面也不可以写同nodes一样的标签,否则点击元素之间的间隔会给nodes下的div赋予事件处理函数
$('#nodes').on('click','p',function(e){
        let target = $(e.target)
        target.css('backgroundColor','red')
    })
    $('button').click(()=>{
        inner++;
        $('#nodes').append($('<p>我是新增加的p标签'+inner+'</p>'))
    })

浏览器运行的效果如图四所示:
图四
例二:

<body>
    <div id="nodes">
        <P class="node_p">第一个p</P>
        <P class="node_p">第二个p</P>
        <P class="node_p">第三个p</P>
        <span class="node_p">span</span>
        <div id="childDiv">
            <p>这是子集菜单</p>
            <div>我是子集的div
                <p>我是子集的p</p>
            </div>
        </div>
    </div>
    <button>点击加一</button>
</body>
<script>
let inner =33;
$('#nodes').on('click','p,div,span',function(e){
        let target = $(e.target)
        target.css('backgroundColor','red')
    })
    $('button').click(()=>{
        inner++;
        $('#nodes').append($('<p>我是新增加的p标签'+inner+'</p>'))
    })
</script>

浏览器运行效果如图五所示:
图五

事件委托不仅仅只是为处理一种dom操作类型,他可以进行增删改查等功能:

js事件委托:不同操作

<body>
    <div id="events">
        <input type="button" id='addHandle' value='增加'>
        <input type="button" id='deleteHandle' value='减少'>
    </div>
    <div id="content">

    </div>
</body>
<script src='http://code.jquery.com/jquery-2.1.1.min.js'></script>
<script>
    let events = document.getElementById('events');
    let content = document.getElementById('content');
    events.onclick=function(e){
        let ev = e || window.event;
        let target = ev.target || ev.srcElement;
        if(target.nodeName.toLowerCase()=='input'){
            switch(target.id){
                case 'addHandle':
                return addEvent();
                break
                case 'deleteHandle':
                return deleteEvent();
                break
            }
        }
    }
    function addEvent(){
        let add = document.createElement('p')
        add.innerHTML = '这是增加按钮'
        content.appendChild(add)
    }
    function deleteEvent(){
        let del = document.createElement('p')
        del.innerHTML = '这是删除按钮'
        content.appendChild(del)
    }
</script>

浏览器中的效果如图六所示:
图六

jquery事件委托:不同操作

$('#events').on('click','input',(e)=>{
        let target = $(e.target);
        switch(target[0].id){
                case 'addHandle':
                return addEvent();
                break
                case 'deleteHandle':
                return deleteEvent();
                break
        }
    })
    function addEvent(){
        $('#content').append($('<div>这是增加按钮</div>'))
    }
    function deleteEvent(){
        $('#content').append($('<div>这是删除按钮</div>'))
    }

浏览器中的效果如图七所示:
图七

本文如有不实之处,还望大神指点一二,欢迎讨论!

2019我在路上,加油!

分类:

技术点:

js

相关文章: