分享一个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);
}

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

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

相关推荐
故事不长丨7 小时前
C#正则表达式完全攻略:从基础到实战的全场景应用指南
开发语言·正则表达式·c#·regex
源心锁7 小时前
👋 手搓 gzip 实现的文件分块压缩上传
前端·javascript
哈库纳玛塔塔7 小时前
放弃 MyBatis,拥抱新一代 Java 数据访问库
java·开发语言·数据库·mybatis·orm·dbvisitor
phltxy8 小时前
从零入门JavaScript:基础语法全解析
开发语言·javascript
Kagol8 小时前
JavaScript 中的 sort 排序问题
前端·javascript
天“码”行空8 小时前
java面向对象的三大特性之一多态
java·开发语言·jvm
cos9 小时前
Fork 主题如何更新?基于 Ink 构建主题更新 CLI 工具
前端·javascript·git
odoo中国9 小时前
Odoo 19 模块结构概述
开发语言·python·module·odoo·核心组件·py文件按
代码N年归来仍是新手村成员10 小时前
【Java转Go】即时通信系统代码分析(一)基础Server 构建
java·开发语言·golang
Z1Jxxx10 小时前
01序列01序列
开发语言·c++·算法