当前位置:首页 > 日记 > 正文

JavaScript动态绑定详解

JavaScript动态绑定详解

问题描述:

假设我们的网页中动态生成了一个按钮,在这个按钮生成之前我们按照一般的事件绑定方法为此按钮绑定了触发事件,但是问题是绑定的事件并没有生效(JavaScript中为元素绑定的事件失效)

分析

1.首先我们来看一下这个按钮是怎么回事:

问题中按钮有一个很关键的特性:动态生成,也就是说是在网页加载完成之后执行某些操作才产生的,它一开始是不存在的;

2.然后我们来分析一下事件的绑定

对于动态生成的元素,它不同于一般的网页既有元素,它的事件绑定不能通过普通的事件绑定实现。

3.关于JavaScript事件绑定的小解(针对本题盗图解析)

这里写图片描述

由图中我们可以看到事件冒泡即由最具体的元素(文档嵌套最深节点)接收,然后逐步上传至document

事件捕获会由最先接收到事件的元素然后传向最里边(我们可以将元素想象成一个盒子装一个盒子,而不是一个积木堆积)

然后我们进入dom事件流

DOM2级事件规定事件包括三个阶段:

① 事件捕获阶段

② 处于目标阶段

③ 事件冒泡阶段

我们分析一下第一阶段就可以知道为什么了,js中一般事件绑定是在网页生成的时候针对具体元素去绑定的,那么请问:网页初始生成时按钮存在吗?答:NOP。这就是为什么事件没有绑定上去,因为都没找到元素啊啊啊啊啊,绑个毛线

解决方法(jQuery on方法)

通过将事件绑定到存在的父元素上让子元素的事件有效

jQuery on用法格式:

$(selector).on(event,childSelector,data,function,map)

示例,比如说id为btn的元素为动态生成,它的父元素为btnParent(必须是网页加载时就有的元素,也可以直接绑定到body上去)那么我们可以这样为它绑定处理事件

$("#btnParent").on("click","#btn",function(){  console.log('binded!'); });

如果想要更深层次的理解,那么请跟我一起阅读一下jQuery.on()的源码实现

on: function( types, selector, data, fn, /*INTERNAL*/ one ) {  var type, origFn;  // 类型可以使类型映射或者句柄映射  if ( typeof types === "object" ) {    // ( types-Object, selector, data )    if ( typeof selector !== "string" ) {      // ( types-Object, data )      data = data || selector;      selector = undefined;    }    // 遍历types对象,针对每一个属性绑定on()方法    // 将types[type]作为fn传入    for ( type in types ) {      this.on( type, selector, data, types[ type ], one );    }    return this;  }  // 参数修正  // jQuery这种参数修正的方法很好  // 可以兼容多种参数形式  // 可见在灵活调用的背后做了很多处理  if ( data == null && fn == null ) {    // ( types, fn )    fn = selector;    data = selector = undefined;  } else if ( fn == null ) {    if ( typeof selector === "string" ) {      // ( types, selector, fn )      fn = data;      data = undefined;    } else {      // ( types, data, fn )      fn = data;      data = selector;      selector = undefined;    }  }  if ( fn === false ) {    // fn传入false时,阻止该事件的默认行为    // function returnFalse() {return false;}    fn = returnFalse;  } else if ( !fn ) {    return this;  }  // one()调用on()  if ( one === 1 ) {    origFn = fn;    fn = function( event ) {      // Can use an empty set, since event contains the info      // 用一个空jQuery对象,这样可以使用.off方法,      // 并且event带有remove事件需要的信息      jQuery().off( event );      return origFn.apply( this, arguments );    };    // Use same guid so caller can remove using origFn    // 事件删除依赖于guid    fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );  }  // 这里调用jQuery的each方法遍历调用on()方法的jQuery对象  // 如$('li').on(...)则遍历每一个li传入add()  // 推荐使用$(document).on()或者集合元素的父元素  return this.each( function() {    jQuery.event.add( this, types, fn, data, selector );  });},

关于jQuery还有很多其他的事件绑定方法,当然不一定适用,也提一下

.bind(), .live(), .delegate()

但是说到底.bind(), .live(), .delegate()都是通过.on()来实现的,.unbind(), .die(), .undelegate(),也是一样的都是通过.off()来实现的

我们看一下jQuery的.bind(), .live(), .delegate()的实现源码就清楚了

jQuery.fn.extend( {  bind: function( types, data, fn ) {    return this.on( types, null, data, fn );    //注意this.on()  },  unbind: function( types, fn ) {    return this.off( types, null, fn );    //注意this.off()  },  delegate: function( selector, types, data, fn ) {    return this.on( types, selector, data, fn );  },  undelegate: function( selector, types, fn ) {    return arguments.length === 1 ?      this.off( selector, "**" ) :      this.off( types, selector || "**", fn );  }} );

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关文章

PPT2010如何制作翻书动画效果图文

PPT2010如何制作翻书动画效果图文

动画效果,图文教程,方法,翻书,电脑软件,  是不是已经厌倦了平淡无奇的PPT展示方式呢?是不是已经讨厌了毫无新意的图片展示形式呢?是不是还木有掌握PPT的翻书动画效果呢?下面小编马上就告诉大家PPT2010制作翻书动画效果的方法。PPT2010制…

如何手写Ajax实现异步刷新

如何手写Ajax实现异步刷新

异步刷新,电脑软件,Ajax,所谓的异步刷新,就是不刷新整个网页进行更新数据。只有通过js才能实现Ajax,进而实行异步刷新表单提交数据和Ajax提交数据的区别:表单提交是提交的整个页面中的数据,提交数据之后会抛弃之前的页面(刷新页面);ajax是在当前…

Photoshop制作可爱甜美的浮面立体

Photoshop制作可爱甜美的浮面立体

立体字,美的,浮面,可爱,电脑软件,这篇教程是向的朋友分享Photoshop制作可爱甜美的浮面立体字方法,很简单的一个方法,打好文字后直接用上图层样式,再加上笔刷就能做出很好的浮面效果。先上效果图。步骤:1、新建,宽度600,高度400,选择一种颜色,这里选…

基于vue.js轮播组件vue-awesome-sw

基于vue.js轮播组件vue-awesome-sw

轮播图,组件,电脑软件,vue,js,一般做移动端轮播图的时候,最常用的就是Swiper插件了,而vue.js也有一个轮播组件vue-awesome-swiper,用法跟swiper相似。1.安装vie-awesome-swipernam install vue-awesome-swiper --save-dev2.引用vie-awesome-sw…

VUE多层路由嵌套实现代码

VUE多层路由嵌套实现代码

嵌套,路由,多层,代码,电脑软件,先看看效果图:例如:在做系统时,主页面有两个功能【home】and【news】,在【home】下又分为登录和注册。首先需要将各种模板进行抽离。定义模板<template id="home"> //home模板,里面含子视口 <div> <router-li…

ps怎么制作一款立体滑动的UI按钮?

ps怎么制作一款立体滑动的UI按钮?

按钮,电脑软件,ps,UI,在很多地方我们都会看到按钮的图形,想要绘制一款立体滑动的按钮,该怎么设计呢?下面我们就来看详细的教程。软件名称:Adobe Photoshop 8.0 中文完整绿色破解版软件大小:150.1MB更新时间:2015-11-041、新建700*500PX白色画布,网…

PS设计大苹果Macintosh标志

PS设计大苹果Macintosh标志

标志,电脑软件,PS,Macintosh,大苹果Macintosh喜欢吗? 如果是的,我有一个非常有趣的教程对你如何重现苹果标志,喜欢的朋友可以参考本文,希望能对大家有所帮助!最终效果图:步骤:1、创建一个新的文档大小的500&times;500像素。 拖动一个线性渐变的…

vue-cli + sass 的正确打开方式图

vue-cli + sass 的正确打开方式图

打开方式,详解,正确,图文,电脑软件,关于在vue-cli搭建的项目中怎么配置sass,网上搜到的基本是这种答案:但是我认为,直接将样式写在每个单文件的<style>里,是十分不明智的做法。且不说node-sass安装过程的各种坑,内嵌的<style>也让组件显得十分混…

Node.js之网络通讯模块实现浅析

Node.js之网络通讯模块实现浅析

模块,网络通讯,电脑软件,Node,js,前言想必我们在用Node.js用的最多的应该是创建http服务,所以对于每个Web开发工程师而言,Node.js的网络相关模块学习是必不可少。Node.js的网络模块架构在Node.js的模块里面,与网络相关的模块有Net、DNS、HTTP…

ps中怎样设置打印

ps中怎样设置打印

设置,方法,图片,电脑软件,ps,  一张好的照片P好了还需要在ps中打印,但是打印也需要设置的。那么大家知道ps中怎样设置打印图片吗?下面是小编整理的ps中怎样设置打印图片的方法,希望能帮到大家!ps中设置打印图片的方法首先双击软件图标,进入…

ubuntu编译nodejs所需的软件并安装

ubuntu编译nodejs所需的软件并安装

编译,所需,并安装,电脑软件,ubuntu,闲了一段时间后,要开始做个项目了!公司以java为主,因此一直以来的技术栈为springboot,zookeeper,jredis,dubbo,druid.....经典的分布式服务器体系架构。我花了点时间,统计了一下maven中的依赖包,共计35个以上,…

PS怎么设置自动更改其它文件相关内

PS怎么设置自动更改其它文件相关内

文件,相关内容,设置自动,电脑软件,PS,打个比方,用PS做了一本书,很多页,里面有很多一样的内容,比如说LO,怎么才能做到,在一个文件里面修改这个LO,其它的文件里的LO,自动更改呢?软件名称:Adobe Photoshop 8.0 中文完整绿色破解版软件大小:150.1MB更新时…