【问题标题】:jQuery function ignoring incremented valuejQuery函数忽略增量值
【发布时间】:2016-09-21 04:45:54
【问题描述】:

我似乎无法解决这个问题,大约两个小时后我放弃了。我一点也不擅长 javascript。

这是我在这里找到的一个带有漂亮 jquery 的 jfiddle:

 [html]
<button id="addProduct">Add Product</button>
<div id="someContainer"></div>
<span></span>


[javascript]
var i = 1;
$("#addProduct").click(function() {
$("<div />", { "class":"wrapper", id:"product"+i })
 .append($("<input />", { type: "text", id:"name"+i }))
 .append($("<input />", { type: "text", id:"property"+i }))
 .appendTo("#someContainer");
i++;
});

$("input").live("click", function() {
 $("span").text("Clicked ID: " + this.id);
});

它会附加两个具有唯一 ID 的新输入。现在我想做的是使用 on() 在“焦点”时重置不同输入的值。问题是,我希望它清除其相应的输入,例如,关注“id=name1”会重置“id=property2”,反之亦然,关注“id=name2”会重置“id=property2”,反之亦然,所以上...

所以我添加了它:

var i = 1;
   $("#addProduct").click(function() {
   $("<div />", { "class":"wrapper", id:"product"+i })
   .append($("<input />", { type: "text", class:"name"+i }))
   .append($("<input />", { type: "text", class:"property"+i }))
   .appendTo("#someContainer");

$("#product"+i).on("focus", $(".name"+i), function() {
 $(".property"+i).val("");
});

$("#product"+i).on("focus", $(".property"+i), function() {
  $(".name"+i).val("");
});

i++;

});

但无论出于何种原因,我都无法重置这些输入。该函数似乎忽略了递增值。如果我删除 var i 它似乎可以工作,但它会清除我所有的输入。从逻辑上将“+i”添加到类的末尾应该可以解决问题,但事实并非如此。我尝试过使用不同形式的选择类:

$("#product"+i).find(".name"+i);

但这似乎也无济于事。我真的不明白这有什么问题。如果有人可以提供帮助,我将不胜感激。

【问题讨论】:

  • 你能创建jsFiddler吗?

标签: javascript jquery increment


【解决方案1】:

不要尝试将增量 ID 用于此类事情。相反,使用类。以这种方式使用动态元素要容易得多。请看下面的例子:

$("#addProduct").click(function() {
   $("<div />", { "class":"wrapper", class:"product"})
   .append($("<input />", { type: "text", class:"name" }))
   .append($("<input />", { type: "text", class:"property" }))
   .appendTo("#someContainer");
});

$('#someContainer').on('click', '.name, .property', function() {
  var $this = $(this);
  var $otherInput = $this.parent().find('.name, .property').not($this).val('');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="addProduct">Add Product</button>
<div id="someContainer"></div>
<span></span>

那么,这是如何工作的呢?嗯....

首先,此处理程序侦听#someContainer 元素内的任何点击。当听到点击时,它会检查点击的元素是否具有nameproperty 类,如果有,则调用该函数。

$('#someContainer').on('click', '.name, .property', function() {
  
});

接下来,我们将this 缓存为一个 jQuery 对象。这是被点击的元素。

var $this = $(this);

现在我们有了:

$this.parent().find('.name, .property').not($this).val('');
  • $this.parent() 获取被点击元素的父元素
  • .find('.name, .property') 查找该父级的任何具有nameproperty 类的子级
  • .not($this) 从匹配的元素中排除点击的元素
  • val('') 清除所有匹配元素的值,本例中只有一个

请注意,madalin ivascu 对.siblings().val(""); 的使用更加简洁。老实说,我忘记了,虽然如果你以后有更多元素并且不想清除一些,这种方式会更灵活。


现在我们知道了更好的方法,让我们谈谈为什么您的尝试没有成功。

第一个问题是处理程序的绑定。你有:

$("#product"+i).on("focus", $(".name"+i), function() {
   //.....
});

如果你看一下docs for .on(),它会说第二个参数如下:

选择器

类型:字符串

一个选择器字符串,用于过滤触发事件的选定元素的后代。如果选择器为 null 或省略,则始终在到达所选元素时触发事件。

您正在传递一个 jQuery 对象 $(".name"+i) 但这应该是一个字符串,所以只需 ".name"+i 就像这样:

$("#product"+i).on("focus", ".name"+i, function() {
   //.....
});

第二个问题是递增i 的逻辑有缺陷。让我们看看为什么:

var i = 1; // here we set i to 1, cool

$("#addProduct").click(function() {
   $("<div />", { "class":"wrapper", id:"product"+i })
   .append($("<input />", { type: "text", class:"name"+i }))
   .append($("<input />", { type: "text", class:"property"+i }))
   .appendTo("#someContainer");
   
   // the 3 lines above all use i and i=1, so far so good

  $("#product" + i).on("focus", ".name" + i, function() { // for clarity, I have corrected this line, again, here i=1 so we're fine 
    $(".property" + i).val(""); // here is the issue, but we'll come back to this...
  });
 
  //..... other code....

  i++; // here we increment i so now, i=2 , seems ok, but it's not

});

所以我们现在知道问题出在嵌套处理程序上。这是发生了什么:

当我们绑定处理程序时,i 立即被评估并且 i=1 在这一行

$("#product" + i).on("focus", ".name" + i, function() { 
    //....
});

然而,处理程序中的代码直到用户点击$("#product1")后才会被执行这将是在我们增加i之后

这意味着,当下面的行运行时,i 将始终比添加到页面的最后一个元素高一个数字。因此,即使您修复了选择器,您也会尝试清除不存在的元素

$(".property" + i).val(""); // i here will always be the newest value for i 
                            // NOT the value of i when the handler was attached

运行下面的 sn-p 并观察控制台输出以了解我的意思:

var i = 1;
$("#addProduct").click(function() {
   $("<div />", { "class":"wrapper", id:"product"+i })
   .append($("<input />", { type: "text", class:"name"+i }))
   .append($("<input />", { type: "text", class:"property"+i }))
   .appendTo("#someContainer");
    
  $("#product" + i).on("focus", ".property" + i, function() {
    console.log(".property" + i);
  }); 
  $("#product" + i).on("focus", ".name" + i, function() {
    console.log(".name" + i);
  });  
  i++;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="addProduct">Add Product</button>
<div id="someContainer"></div>
<span></span>

【讨论】:

  • 哇,这代码真聪明。选择被点击的父元素的子元素,但那不是被点击的元素。惊人的。我需要更多地查看 jQuery 文档。我会把这个作为答案,因为你解释得非常透彻。如果可以,您能解释一下为什么我的代码不起作用吗?再次感谢
  • @Juan 当然,请参阅上面的更新。让我知道这是否有任何意义:)
【解决方案2】:

试试下面的

$('#someContainer').on("focus", 'input[clas^="name"],input[class^="property"]',function() {
  $(this).siblings().val("");
});

演示:https://jsfiddle.net/Le81qo5h/1/

或更好地删除计数器并将 id 更改为类:

$("#addProduct").click(function() {
$("<div />", { "class":"wrapper", class:"product"})
 .append($("<input />", { type: "text", class:"name"}))
 .append($("<input />", { type: "text", class:"property" }))
 .appendTo("#someContainer");

});
 $('#someContainer').on("focus", '.name,.property',function() {
      $(this).siblings().val('');
    });

演示:https://jsfiddle.net/Le81qo5h/

【讨论】:

  • 这将清除焦点输入的值。我认为 OP 希望专注于其中一个以清除另一个
  • 感谢各位:)
  • @madalin ivascu 这真是太好了!!谢谢你的演示,我很感激。
猜你喜欢
  • 1970-01-01
  • 2011-06-07
  • 1970-01-01
  • 2017-01-30
  • 1970-01-01
  • 2013-02-11
  • 2014-04-19
  • 2018-04-24
  • 1970-01-01
相关资源
最近更新 更多