jQuery动态创建元素绑定事件无作用解决方案
- (一)浏览器加载顺序(重点)
- (二)普通写法演示(非动态)
- (三)知道一些方法的具体表意
- (四)错误的动态创建元素绑定事件的写法
- (五)解决方案
- (六)补充
jQuery的出现,大大简化了js中的dom操作。
当使用jQuery动态创建元素之后,想实现为动态创建出来的元素绑定相应事件。使用绑定click点击事件,但最后在浏览器中却发现创建出来的元素不响应!为什么?
(一)浏览器加载顺序(重点)
当浏览器下载完一个页面的时候
1. 首先开始渲染(翻译)HTML元素(标签);
2. 其次CSS和JS代码全部加载完毕之后;
3. 最后再添加JS文件中所写的动态创建的HTML元素;
注意:最后一步,只是添加你动态创建出来的元素;意思为:只会执行动态创建元素的那些代码,其它的代码在第一步和第二步时就已经执行完毕了!
其它的代码:包括了,你为该动态创建出来的元素绑定事件做相关处理的代码,即最常用的写法:$(“动态创建出来的元素”).click(function(){相应功能});
读者会发现,如果按照这个顺序执行,意思为,还没动态创建出需求的元素了,就执行了对该需求元素绑定相应事件的操作。能找到这个元素吗?很显然,根本找到不到!
(相当于:你家媳妇孩子都没有生出来了,你就告诉送首饰的:把首饰亲手挂在我家女儿小闹脖子上。最后的结果会是:送首饰的过去了,找不到一个叫小闹的女孩子???我根本找不到啊,我挂谁?带着首饰又回去了!之后你家媳妇才顺利生出了一个女儿叫小闹。等你回去看,脖子上有首饰吗?没有!你怪谁???)
执行步骤:
当浏览器解析到1步骤页面元素时,解析到JS的这些绑定标签事件的JS代码的时候,发现这些绑定事件的标签元素还没有生成,(因为js代码加载完后,才会动态创建出这些标签),所以这些JS 代码的绑定事件,根本就没有绑定到这些动态加载的标签上,所以事件不会触发。
(二)普通写法演示(非动态)
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="js/index.js"></script>
</head>
<body>
<input type="button" value="加入购物车" id="add_itemCar">
</body>
</html>
//加载 绑定事件
$(function(){
$("#add_itemCar").click(function(){
alert("加入成功!");
});
});
演示:为已经存在的按钮元素添加click单机事件,单机后会在页面弹出”添加成功!“窗口。
(三)知道一些方法的具体表意
这里我们先暂时只罗列常用的能够处理单机的事件方法
方法 | 描述 | 事件 |
click() | 触发、或将函数绑定到指定元素的 click 事件 | 当鼠标指针停留在元素上方,然后按下并松开鼠标左键时,就会发生一次 click |
bind() | 向匹配元素附加一个或更多事件处理器 | 第一个参数传入你所需求的相应事件方法 |
delegate() | 向匹配元素的当前或未来的子元素附加一个或多个事件处理器 | 第一个参数传入你所需求的相应事件方法 |
live() | 为当前或未来的匹配元素添加一个或多个事件处理器 | 第一个参数传入你所需求的相应事件方法 |
on() | 为当前或未来的匹配元素添加一个或多个事件处理器 | 第一个参数传入你所需求的相应事件方法 |
方法 | 写法 |
on() | $(selector).on(event,childSelector,data,function,map) |
live() | $(childSelector).live(event,data,function) |
delegate() | $(selector).delegate(childSelector,event,data,function) |
一般情况下;通常都写为:
$(document).on…
$(document).delegate…
使用事件委托的方式,将指定的事件处理器直接绑定在document上
参数 | 详解 |
event | 必需;规定添加到元素的一个或多个事件。事件的类型包含: blur, focus, focusin, focusout, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error等,由空格分隔多个事件值。必须是有效的事件 |
childSelector | 必须;需要绑定事件的标签的ID、类、属性选择器 |
data | 触发事件需要传入的数据,可选。规定传递到函数的额外数据 |
function | 必需;规定当事件发生时运行的函数 |
map | 可选,规定事件映射 ({event:function, event:function, …}),包含要添加到元素的一个或多个事件,以及当事件发生时运行的函数 |
$().on()的知识点补充:
从jQuery 1.7开始,on()函数提供了绑定事件处理程序所需的所有功能,用于统一取代以前的bind()、 delegate()、 live()等事件函数。
$().on()结合了这三个方法的优势摒弃了劣势。
(四)错误的动态创建元素绑定事件的写法
容易看出,上面的方法列表中,着色强调了,当前与未来的元素字眼。下面演示经常疏忽的错误写法,直接用click单机事件为未来元素绑定此事件并做相应逻辑处理:
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="js/index.js"></script>
</head>
<body>
<input type="button" value="加入购物车" id="add_itemCar">
//使用jQuery,动态的在此时创建一个按钮 ,按钮名称为:清空购物车
</body>
</html>
//加载 绑定事件
$(function(){
$("#add_itemCar").click(function(){
alert("加入成功!");
});
//开始动态创建
$("body").append("<input type='button' value='清空购物车' id='remove_itemCar'>");
//为创建出来的 id=”remove_itemCar" 按钮添加click单击事件,并做相应逻辑
$("#remove_itemCar").click(function(){
alert("删除成功!");
});
});
结合(一)(二)(三)可知,这样调用click单击事件附着在未来(动态创建)的元素上,是错误的写法,点击创建出来的清空购物车按钮,不会响应!
(五)解决方案
读者可以结合自身习惯运用上述给出的,可以使用在未来元素身上的方法;
官方推荐使用on()方法,编者也习惯用on()方法,所以以下用on()方法举例:
//加载 绑定事件
$(function(){
$("#add_itemCar").click(function(){
alert("加入成功!");
});
//开始动态创建
$("body").append("<input type='button' value='清空购物车' id='remove_itemCar'>");
//为创建出来的按钮添加 on()事件处理器,第一个参数挂click单机事件,并做相应逻辑
$(document).on("click","#remove_itemCar",function(){
alert("删除成功!");
});
});
(六)补充
读者一定发现,(三)中:
一般情况下;通常都写为:
$(document).on…
$(document).delegate…
使用事件委托的方式,将指定的事件处理器直接绑定在document上
是什么意思?
每个载入浏览器的 HTML 文档都会成为 Document 对象。Document 对象使我们可以从脚本中(包括js技术)对 HTML 页面中的所有元素进行访问。
这是对document的解释;意思是,只要浏览器加载HTML文档时,就知道应该为其绑定一个on()事件处理器。
至于什么时候触发,以及触发的动作效果是什么样子的,应该在on()事件处理器里面的参数给出指定。指定触发什么事件、指定哪个元素触发、指定触发的这个事件后的具体逻辑…
读者可以自己继续思考为什么要写document,可以写body吗?或者,可以写其它的吗?读者一定要理清楚浏览器的加载顺序!