JQuery实现英雄联盟英雄查找页面出现的bug汇总
1.on.(“click”,”li,function(){ })绑定li中button按钮重复根据li点击次数重复执行问题及解决方案
先看下修改部分的代码
$(function() {
var regexp = /上路|中路|打野|下路|辅助/
//------------on后面写li动态绑定后来增加或减少的li----------------
$("#hero").off('click').on("click", "li", function() {
load();
//获取当前点击盒子的id
var index = $(this).attr("id")
$(".changebox").stop().slideToggle();
//点击关闭按钮
$("#clo").on("click", function() {
$("#changeName").val('');
$("#changePos").val('');
$(".changebox").slideUp();
})
//点击确认按钮
$("#con").on("click", function() {
//判断更改的英雄在数据中是否出现
var ves = 0;
var inputhero = $("#changeName").val();
var local = getData();
for(let i = 0; i < local.length; i++) {
if(local[i].heroName == inputhero)
++ves;
}
console.log($("#changeName").val() + " " + ves);
if(ves == 1) {
alert("该英雄已经存在,无法修改");
$("#changeName").val('');
$("#changePos").val('');
//英雄没有存在
} else {
// -------判断输入内容是否合法-----------
if($("#changeName").val().trim() == '') {
alert("请输入英雄姓名?");
console.log($("#changeName").val().trim());
} else if(regexp.test($("#changePos").val()) == false) {
alert("请输入正确的位置");
} else {
let data = getData();
data[index].heroName = $("#changeName").val();
data[index].heroPosition = $("#changePos").val();
saveData(data)
$(".changebox").slideUp();
}
$("#changeName").val('');
$("#changePos").val('');
}
//全部操作完毕后渲染一遍,将该过的东西显示出来
load();
});
});
});
此时所有点击更改后弹出的内容都在和li绑定的事件中,所以出现的问题如下图所示
可以看见当第二次点击修改时,点击修改框中的确认更改时,他会执行两次判断输入英雄姓名的窗口,也就是会多弹出一次警告框,第三次更改就会弹出三次窗口,通过左边的调试台可以看见,除了第一次数据存入后,后来的两次都是空值.也就是说,点击了几次修改,他的确认更改就会执行几次?!!whatf**,一开始我也是很懵逼,为什么绑定的li点击次数和后来的确认按键有很大的关系,为此也查了很多博客,但是都没有一个关于此问题的解释和回答.问了很多人包括学长也没有得到一个答案
于是我就用我的所学浅浅的分析了一下:
jQuery中有隐式迭代这个概念,就是给匹配的所有元素进行循环遍历,执行相应的方法.所以我就想,是不是有可能因为绑定的每个li,每个li被点击的次数被循环执行到点击确认里,所以会出现上面的bug,于是乎我就把绑定事件内的内容减少,只留了一个获取当前点击的li下标,其他方法写在外面,于是,问题就解决了…,虽然没彻底的弄清楚问题所在,但是能确定的一点就是on的动态绑定的问题.希望也有大佬能解释一下为什么会出现这种情况
$(function() {
var regexp = /上路|中路|打野|下路|辅助/
var index;
//------------on后面写li动态绑定后来增加或减少的li----------------
$("#hero").off('click').on("click", "li", function() {
load();
//获取当前点击盒子的id
index = $(this).attr("id")
$(".changebox").stop().slideToggle();
});
//-----------------------单独将上面的点击封装起来-----------
//点击关闭按钮
$("#clo").on("click", function() {
$("#changeName").val('');
$("#changePos").val('');
$(".changebox").slideUp();
})
//点击确认按钮
$("#con").on("click", function() {
//判断更改的英雄在数据中是否出现
var ves = 0;
var inputhero = $("#changeName").val();
var local = getData();
for(let i = 0; i < local.length; i++) {
if(local[i].heroName == inputhero)
++ves;
}
console.log($("#changeName").val() + " " + ves);
if(ves == 1) {
alert("该英雄已经存在,无法修改");
$("#changeName").val('');
$("#changePos").val('');
//英雄没有存在
} else {
// -------判断输入内容是否合法-----------
if($("#changeName").val().trim() == '') {
alert("请输入英雄姓名?");
console.log($("#changeName").val().trim());
} else if(regexp.test($("#changePos").val()) == false) {
alert("请输入正确的位置");
} else {
let data = getData();
data[index].heroName = $("#changeName").val();
data[index].heroPosition = $("#changePos").val();
saveData(data)
$(".changebox").slideUp();
}
$("#changeName").val('');
$("#changePos").val('');
}
//全部操作完毕后渲染一遍,将该过的东西显示出来
load();
});
});
2…jQuery中关于each方法的坑
---->$.each(),这里先引入官方对each方法的解释
$(selector).each(function(index,element){...})
index: 选择器里数组的下标
element:每一个数组具体的值(内容)
很明显,each方法在给我们遍历一个数组对象时提供了遍历,能够能快速的输出和找到每个相应的数据,只要确定了数组下标即可,例如遍历每个li元素:
$("li").each(function(){
console.log($(this).text());
})
li里面的内容就出来了
如果已经知到了数组或数组对象也可以这样写
$.each(array,function(indexInarray,valueOfElement){...})
array:需要遍历的数组
indexInarray:遍历的数组下标
valueOfelement:每个下标对应的内容
他会依次遍历每一个数组对象,然后里面每一个对象执行一下function方法,==但是!==这样就会产生一个问题,这也是我在做查找功能时发现的,这里我想要实现的功能是判断localstorage里是否出现同一个对象,如果出现,则不在进行添加
原本思路就是把最新的要添加是数据和本地存储里已经存在的数据以此进行比较,然后就想到了each(),利用each循环判断是否出现过名字相同的数据,如果有就弹出窗口提示,没有就执行添加数据功能.
判断的标准就是输入框内容在本地中heroName是否重复出现,如果有则表示英雄重复出现,可是,each是以此循环遍历,比如说,你要新添加一个heroName为剑圣的英雄,他会以此和本地里已经存在进行比较,发现第一个是剑圣,所以弹出英雄已经存在的窗口,然后,他会和第二个对象安妮进行比较,发现名字不一样,所以这里,他就又创建了一个剑圣英雄对象,这就是each循环的在本情景的重大问题所在!!!