当我的loadNav()
函数循环遍历nav
数组并为动态创建的元素分配单击侦听器时,一切似乎都很好。如果break
的第一个循环中的navItem.id
为'newGL'
,则第二次'litGL'
为'litGL'
,应该如此。
但是当我在完成循环后检查侦听器时,它们都具有 'b'
的id(以及navItem.text
的类型)。但是元素本身具有正确的.click
,所以我想我不理解变量在传递函数中如何分配给var nav = [
{
id:'newGL',
text:'new',
type:'a'
},
{
id:'litGL',
text:'lit',
type:'b'
}
]
function loadNav(nav){
for(item in nav){
var navItem = nav[item];
var element = $("<div>" + navItem.text + "</div>");
element.click(function(){
getContent(navItem.id,navItem.type);
//in practice I'm getting two click listeners with a navItem.id of 'litGL' and a navItem.type of 'b'
});
$('#horzNav').append(element);
}
}
方法。
为什么我的第一次点击监听器被第二个值覆盖的任何提示?
Code package linkedlist;
import java.util.Scanner;
/**
*
* @author Spock-II
*/
public class LinkedList {
public static LinkedInt Trueadd(LinkedInt A, LinkedInt B) {
LinkedInt a = A;
LinkedInt b = B;
int next;
LinkedInt sum = new LinkedInt();
System.out.println("Switches!");
if (a.size() > b.size()) {
System.out.println("size: " + (a.size() - b.size()));
int limit = a.size() - b.size();
for (int i = 0; i < limit; i++) {
b.addToLinkList("0", i);
System.out.println("inloop b");
System.out.println("i : " + i);
}
System.out.println("loop complete");
} else if (a.size() < b.size()) {
System.out.println("size: " + (b.size() - a.size()));
int limit = b.size() - a.size();
for (int i = 0; i < limit; i++) {
a.addToLinkList("0", i);
System.out.println("inloop b");
System.out.println("i : " + i);
}
System.out.println("loop complete");
}
System.out.println("Switch overcame");
int carryover = 0;
while (a.head != null & b.head != null) {
String[] carryCheck = (Integer.valueOf(a.head.getItem()) + Integer.valueOf(b.head.getItem()) + "").split("");
if (carryCheck.length == 2) {
sum.addToLinkList((Integer.valueOf(carryCheck[1])+carryover)+"", 0);
carryover = Integer.valueOf(carryCheck[0]);
} else {
int i = Integer.valueOf(a.head.getItem()) + Integer.valueOf(b.head.getItem());
sum.addToLinkList(i + "", 0);
}
System.out.println("a: " + a.head.getItem());
System.out.println("b: " + b.head.getItem());
a.head = a.head.getLink();
b.head = b.head.getLink();
}
System.out.println("Completed");
return sum;
}
public static LinkedInt subtract(LinkedInt a, LinkedInt b) {
a.combine();
b.combine();
LinkedInt difference = new LinkedInt(a.x - b.x);
difference.combine();
return difference;
}
public static LinkedInt multiply(LinkedInt a, LinkedInt b) {
a.combine();
b.combine();
LinkedInt product = new LinkedInt(a.x + b.x);
product.combine();
return product;
}
public static LinkedInt divide(LinkedInt a, LinkedInt b) {
a.combine();
b.combine();
LinkedInt sum = new LinkedInt(a.x + b.x);
sum.combine();
return sum;
}
public static LinkedInt modulus(LinkedInt a, LinkedInt b) {
a.combine();
b.combine();
LinkedInt rem = new LinkedInt(a.x + b.x);
rem.combine();
return rem;
}
public static void main(String[] args) {
// TODO code application logic here
Scanner i1 = new Scanner(System.in);
System.out.print("Please enter the first no. : ");
int a = i1.nextInt();
Scanner i2 = new Scanner(System.in);
System.out.print("Please enter the second no. : ");
int b = i2.nextInt();
System.out.println();
LinkedInt a1 = new LinkedInt(a);
LinkedInt a2 = new LinkedInt(b);
a1 = a1.populate();
a2 = a2.populate();
a1.combine();
a2.combine();
LinkedInt sum = Trueadd(a1, a2);
sum.combine2();
// LinkedInt sum = a1;
}
}
`
答案 0 :(得分:3)
当前的问题是,当事件稍后触发时,navItem的值不同。要解决此常见问题,请使用范围IIFE(立即调用函数表达式):
function loadNav(nav){
for(item in nav){
var navItem = nav[item];
var element = $("<div>" + navItem.text + "</div>");
(function(navItem){
element.click(function(){
getContent(navItem.id,navItem.type);
//in practice I'm getting two click listeners with a navItem.id of 'litGL' and a navItem.type of 'b'
});
})(navItem);
$('#horzNav').append(element);
}
}
更好的解决方案包括将require属性放入注入的元素中,然后在事件时提取它们。这简化了事件处理程序并消除了对原始navItem变量的依赖。
e.g。类似的东西:
function loadNav(nav){
for(var i = 0; i < nav.length; i++){
var navItem = nav[i];
var element = $("div", {id: navItem.id}).html(navItem.text).data('type', navitem.type ).appendTo('#horzNav');
}
}
并使用带有选择器的委托事件处理程序:
$(function () {
$(document).on("click", ".navItem", function () {
getContent($(this).attr("id"), $(this).data("type"));
});
});
这可以通过监听事件(例如点击)来冒泡到一个不变的祖先元素(例如document
),然后将选择器应用于泡泡中的项目-chain,然后仅将函数应用于导致事件的匹配元素。
这样的结果是项目只需要在活动时间匹配,而不是在活动登记时。非常适合动态添加项目。
如果没有其他祖先更接近/方便, document
是最好的默认值。不要将body
用于委派事件,因为它有错误(样式可能导致它无法获取鼠标事件)。
答案 1 :(得分:2)
您的问题是确定范围,但您确实需要委派该事件(否则,如果您有100个元素,那就是100个事件:/),那么您可以指定属性需要在标记内使用数据属性,例如:
$(function () {
$(document).on("click", ".navItem", function () {
getContent($(this).attr("id"), $(this).data("type"));
});
});
然后您的loadNav
将是:
function loadNav(nav){
for(item in nav){
var navItem = nav[item];
var element = $(document.createElement("div"));
element.html(navItem.text);
element.prop("id", navItem.id);
element.data("type", navItem.type);
$('#horzNav').append(element);
}
}