JavaScript动态绑定详解

问题描述:

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

分析

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

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

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

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

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

这里写图片描述

由图中我们可以看到事件冒泡即由最具体的元素

(文档嵌套最深节点)

接收,然后逐步上传至document

事件捕获会由最先接收到事件的元素然后传向最里边

(我们可以将元素想象成一个盒子装一个盒子,而不是一个积木堆积)

然后我们进入dom事件流

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

① 事件捕获阶段

② 处于目标阶段

③ 事件冒泡阶段

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

解决方法(jQuery on方法)

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

jQuery on用法格式:

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

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

// 类型可以使类型映射或者句柄映射
if ( typeof types === "object" ) {
// ( types-Object,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,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,fn )
fn = data;
data = undefined;
} else {
// ( types,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,selector );
});
},

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

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

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)