动态事件附件无法正常工作

时间:2014-02-18 07:24:49

标签: javascript jquery

var smartActionsId = ['smartActions1','smartActions5','smartActions10'];

for (var i in smartActionsId) {
     console.log("smartActionsId ="+smartActionsId[i]);
    $('#' + smartActionsId[i] + ' select').change(function () {
        var value = $(this).val();
        var disableValue;
        var ruleIndex = smartActionsId[i].substr(11);
        console.log("smartActionsId ="+smartActionsId[i]+" i ="+i);
        if (value === '0') {
            disableValue = true;
            onRuleToggle(disableValue, ruleIndex)
        }
        else if (value === '1') {
            disableValue = false;
            onRuleToggle(disableValue, ruleIndex)
        }
    });
}

我正在使用上面的JavaScript代码为多个切换滑块项动态创建更改事件。但是我面临的问题是,当我点击任何开关'i'时,值被替换为最后一个值,即在smartActionsId中,我有3个元素,这些元素曾经切换过我改变了最后一个开关的效果(smartActions10)。

你能帮我解决一下这个问题吗?

4 个答案:

答案 0 :(得分:2)

此处的其他答案解决了您的问题,但我认为您可以稍微重构一下代码并使其更容易理解。

首先,我不喜欢ID。在您的方案中,您有多个ID需要被视为相同。为什么不使用一个强大的班级?

另外,ruleIndex是根据元素的ID计算的?闻起来很烂。 如果它告诉你关于元素的一些信息,它应该在属性或data- *属性中。

第一段代码通过添加ruleIndex作为数据属性并添加.smart-actionable类来修复标记。 (也许你甚至可以将这部分移到服务器端,为JS提供更简单的标记)。

现在,这使事件处理变得非常简单。

var smartActionsId = ['smartActions1','smartActions5','smartActions10'];

for (var i in smartActionsId) {
    $('#' + smartActionsId[i])
      .data('ruleIndex', smartActionsId[i].substr(11))
      .addClass('smart-actionable');
}

$('.smart-actionable').on('change', 'select', function() {
    var value = $(this).val();
    var disableValue = (value === '0');
    onRuleToggle(disableValue, $(this).data('ruleIndex'));
});

希望它会有所帮助。

答案 1 :(得分:1)

在这种情况下,您无法使用for...in。请尝试以下代码:

var smartActionsId = ['smartActions1', 'smartActions5', 'smartActions10'];

for (var i = 0; i < smartActionsId.length; i++) {
    console.log("smartActionsId =" + smartActionsId[i]);
    $('#' + smartActionsId[i] + ' select').change(function() {
        var value = $(this).val();
        var disableValue;
        var ruleIndex = smartActionsId[i].substr(11);
        console.log("smartActionsId =" + smartActionsId[i] + " i =" + i);
        if (value === '0') {
            disableValue = true;
            onRuleToggle(disableValue, ruleIndex)
        } else if (value === '1') {
            disableValue = false;
            onRuleToggle(disableValue, ruleIndex)
        }
    });
}

答案 2 :(得分:1)

您不希望在for循环中附加事件侦听器,因为每个循环周期都会使用跟踪索引的变量。如果您这样做,i变量将始终等于数组的长度减1.使用Array.prototype.forEach()来防止这种情况发生。

var smartActionsId = ['smartActions1','smartActions5','smartActions10'];

smartActionsId.forEach(function (identifier, index) {
  console.log("smartActionsId ="+identifier);
  $('#' + smartActionsId[index] + ' select').change(function () {
    var value = $(this).val();
    var disableValue;
    var ruleIndex = smartActionsId[index].substr(11);
    console.log("smartActionsId ="+smartActionsId[index]+" index ="+index);
    if (value === '0') {
      disableValue = true;
      onRuleToggle(disableValue, ruleIndex)
    }
    else if (value === '1') {
      disableValue = false;
      onRuleToggle(disableValue, ruleIndex)
    }
  });
});

请注意:IE8及以下版本不支持Array.prototype.forEach()

答案 3 :(得分:1)

我总是使用像smartActions_1这样的名字。如果您可以使用它,那么在您的.change功能中,您可以使用

// if 'smartActionsId' is global variable
// and if you need to get position in 'smartActionsId' array
var numInArray = $.inArray( this.parentNode.id, smartActionsId );
// this - your select DOM object
var ruleIndex = parseInt( this.parentNode.id.split( "_" )[ 1 ] );  

请记住this.change的{​​{1}}函数select没有id,您必须使用this.parentNode$( this ).parent()来获取它持有人(我认为它是div或者是那种想法)。

评论中的@Jack是对的:选择可能不是直接的孩子。然后你可以使用这段代码:

var parent = $( this ).closest( "[id^=smartActions]" );
var numInArray = $.inArray( parent.attr( "id" ), smartActionsId );
var ruleIndex = parseInt( parent.attr( "id" ).split( "_" )[ 1 ] );