分享一个jquery重复绑定事件的问题

这篇文章主要分享一下前端在使用jQuery给元素绑定click事件时遇到的一点小问题。

今天在通过JS代码动态绑定元素的点击事件时遇到一点问题,如上图所示,需要实现动态控制低级内丹格子的解锁,每种宠物造型都有一个内丹数量。如图,忘川童子可学习的内丹数量是4(包含了高级内丹),所以实际的内丹数量是3,所以上图只解锁了3个低级内丹的格子。

对比游戏内数据

前端实现的效果如下,点击对话框左边的数据列表,动态加载上方和右侧面板的数据,这里只关注内丹的加载。

javascript 复制代码
/**
 * 加载宠物内丹
 */
function loadNeidans() {
	let rowData = $("#chongwu_datalist").datalist("getSelected");

	$("#chongwu_id").val(rowData.id);
	$("#chongwu_id_").val(rowData.id);

	for (let i = 1; i <= 4; i++) {
		$(".neidan_" + i + ">img").attr("src", "/images/lock.png");
	}
	$(".gaoji_neidan>img").attr("src", "/images/add.png");
	$(".zhaunshu_neidan>img").attr("src", "/images/add.png");

    // 根据当前宠物的造型为4个低级内丹格子动态绑定点击事件
	get("/chongwu_category/selectById", {
		id: rowData.categoryId
	}, function (res) {
		// 得到当前宠物造型可以学习的低级内丹数
		let count = res.neidanQuantity - 1;

		// 如果小于4,则有内丹格子未解锁
		if (count < 4) {
			for (let i = 1; i <= count; i++) {
				$(".neidan_" + i).click(function() {
					loc = i;

					clickNeidan(0);
				});
				$(".neidan_" + i + ">img").attr("src", "/images/add.png");
			}
			for (let i = count + 1; i <= 4; i++) {
				$(".neidan_" + i).click(function () {
					alertMsg("这只召唤灵只能学习" + count + "个低级内丹");
				});
			}
		} else {
			for (let i = 1; i <= 4; i++) {
				$(".neidan_" + i + ">img").attr("src", "/images/add.png");

				$(".neidan_" + i).on("click", function() {
					loc = i;

					clickNeidan(0);
				});
			}
		}
	}, error);

	get("/chongwu_neidan/selectNeidans", {
		chongwuId: rowData.id
	}, function (res) {
		if (res && res.length > 0) {
			for (let i = 0; i < res.length; i++) {
				let neidan = res[i];
				let image = neidan.image;
				let location = neidan.location;

				if (location === 0) {
					$(".gaoji_neidan>img").attr("src", image);
				} else {
					$(".neidan_" + neidan.location + ">img").attr("src", image);
				}
			}
		}
	}, error);

	get("/zhuanshu_neidan/selectByChongwuId", {
		chongwuId: rowData.id
	}, function (response) {
		let result = response.data;

		if (result) {
			$(".zhaunshu_neidan>img").attr("src", result.image).attr("title", result.name);
		}
	}, error);
}

重点关注下面这块代码,这里通过选中宠物的宠物类型ID查询宠物类型信息,根据内丹数量动态设置低级内丹对应格子的图片以及点击事件。

javascript 复制代码
    // 根据当前宠物的造型为4个低级内丹格子动态绑定点击事件
	get("/chongwu_category/selectById", {
		id: rowData.categoryId
	}, function (res) {
		// 得到当前宠物造型可以学习的低级内丹数
		let count = res.neidanQuantity - 1;

		// 如果小于4,则有内丹格子未解锁
		if (count < 4) {
			for (let i = 1; i <= count; i++) {
				$(".neidan_" + i).click(function() {
					loc = i;

					clickNeidan(0);
				});
				$(".neidan_" + i + ">img").attr("src", "/images/add.png");
			}
			for (let i = count + 1; i <= 4; i++) {
				$(".neidan_" + i).click(function () {
					alertMsg("这只召唤灵只能学习" + count + "个低级内丹");
				});
			}
		} else {
			for (let i = 1; i <= 4; i++) {
				$(".neidan_" + i + ">img").attr("src", "/images/add.png");

				$(".neidan_" + i).on("click", function() {
					loc = i;

					clickNeidan(0);
				});
			}
		}
	}, error);

比如,忘川童子的内丹数量是4-1=3,所以最后一个内丹格子无效,点击时应该提示进行相应提示

上面的代码看起来好像没什么问题,但是多点几次左边列表的宠物就会发现,点击锁图标所在的格子会弹出越来越多的对话框。

具体原因是每次选择宠物都会给元素绑定一次click事件,那么在每次绑定之前解绑之前的click事件就行了,通过jQuery的unbind(事件名)方法解除事件的绑定,修改之后的代码如下,问题完美解决了。

javascript 复制代码
/**
 * 加载宠物内丹
 */
function loadNeidans() {
	let rowData = $("#chongwu_datalist").datalist("getSelected");

	$("#chongwu_id").val(rowData.id);
	$("#chongwu_id_").val(rowData.id);

	for (let i = 1; i <= 4; i++) {
		$(".neidan_" + i + ">img").attr("src", "/images/lock.png");
	}
	$(".gaoji_neidan>img").attr("src", "/images/add.png");
	$(".zhaunshu_neidan>img").attr("src", "/images/add.png");

	// 根据当前宠物的造型为4个低级内丹格子动态绑定点击事件
	get("/chongwu_category/selectById", {
		id: rowData.categoryId
	}, function (res) {
		// 得到当前宠物造型可以学习的低级内丹数
		let count = res.neidanQuantity - 1;

		// 如果小于4,则有内丹格子未解锁
		if (count < 4) {
			for (let i = 1; i <= count; i++) {
				$(".neidan_" + i).unbind("click").click(function() {
					loc = i;

					clickNeidan(0);
				});
				$(".neidan_" + i + ">img").attr("src", "/images/add.png");
			}
			for (let i = count + 1; i <= 4; i++) {
				$(".neidan_" + i).unbind("click").click(function () {
					alertMsg("这只召唤灵只能学习" + count + "个低级内丹");
				});
			}
		} else {
			for (let i = 1; i <= 4; i++) {
				$(".neidan_" + i + ">img").attr("src", "/images/add.png");

				$(".neidan_" + i).unbind("click").click(function() {
					loc = i;

					clickNeidan(0);
				});
			}
		}
	}, error);

	get("/chongwu_neidan/selectNeidans", {
		chongwuId: rowData.id
	}, function (res) {
		if (res && res.length > 0) {
			for (let i = 0; i < res.length; i++) {
				let neidan = res[i];
				let image = neidan.image;
				let location = neidan.location;

				if (location === 0) {
					$(".gaoji_neidan>img").attr("src", image);
				} else {
					$(".neidan_" + neidan.location + ">img").attr("src", image);
				}
			}
		}
	}, error);

	get("/zhuanshu_neidan/selectByChongwuId", {
		chongwuId: rowData.id
	}, function (response) {
		let result = response.data;

		if (result) {
			$(".zhaunshu_neidan>img").attr("src", result.image).attr("title", result.name);
		}
	}, error);
}

总结:这种问题一般遇上的几率很少,因为很少有这种动态绑定事件的需求,写这篇文章是为了记录自己项目中遇到的问题,可能这篇文章会对部分遇到类似问题的童鞋有点帮助。

好了,文章就分享到这里了,看完觉得对你有所帮助,不要忘了点赞+收藏哦~

相关推荐
写代码写到手抽筋9 分钟前
C++性能优化之访存优化(未完)
开发语言·c++
Dovis(誓平步青云)21 分钟前
基于面向对象设计的C++日期推算引擎:精准高效的时间运算实现与运算重载工程化实践
开发语言·c++·经验分享·笔记
不爱吃饭爱吃菜22 分钟前
uniapp微信小程序-长按按钮百度语音识别回显文字
前端·javascript·vue.js·百度·微信小程序·uni-app·语音识别
夜晚中的人海35 分钟前
【C语言】初阶数据结构相关习题(二)
c语言·开发语言·数据结构
武昌库里写JAVA1 小时前
MacOS Python3安装
java·开发语言·spring boot·学习·课程设计
Dxy12393102161 小时前
python如何设置excel单元格边框样式
开发语言·python·excel
chaodaibing1 小时前
Python解析Excel入库如何做到行的拆分
开发语言·python·excel
程序员拂雨1 小时前
Angular 知识框架
前端·javascript·angular.js
dudly2 小时前
Python类的力量:第五篇:魔法方法与协议——让类拥有Python的“超能力”
开发语言·python
ghost1432 小时前
C#学习第22天:网络编程
开发语言·学习·c#