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吗?或者,可以写其它的吗?读者一定要理清楚浏览器的加载顺序!