如何在调用带有常量的函数时避免DRY问题



我对Javascript还是个新手。我需要附加一个函数来处理一些HTML元素上的事件。

我正在做以下事情:

$('#iinp0').keyup(function(){keyReleased('iinp0');});
$('#iinp1').keyup(function(){keyReleased('iinp1');});
$('#iinp2').keyup(function(){keyReleased('iinp2');});
$('#iinp3').keyup(function(){keyReleased('iinp3');});
$('#iinp4').keyup(function(){keyReleased('iinp4');});
$('#iinp5').keyup(function(){keyReleased('iinp5');});
$('#iinp6').keyup(function(){keyReleased('iinp6');});
$('#iinp7').keyup(function(){keyReleased('iinp7');});

我希望我能将"不要重复自己"(DRY)原则应用于以下内容:

for (i=0;i<=7;i++) {
    var tmp = 'iinp' + i;
    $('#'+tmp).keyup(function(){keyReleased(tmp);});
}

但是CCD_ 1没有用适当的值被调用。

这个问题有解决办法吗?我的意思是,有没有一种简单的方法来附加具有常量参数的函数?

为什么不简单地说:

$('#iinp0, #iinp1, #iinp2, #iinp3, #iinp4, #iinp5, #iinp6, #iinp7').keyup(function()
{
    keyReleased(this.id);
});

您甚至可以用属性选择器替换长选择器:

$('[id^=iinp]').keyup(function()
{
    keyReleased(this.id);
});

其将选择id以CCD_ 2开头的任何元素。

注意:这个选择器比纯ID选择器慢一点,但更容易读取和维护(如果你可以用标记选择器来限定它,它会快一点)。

在您的情况下,这将是最好的:

$('[id^="iinp"]').keyup(function()
{
    keyReleased(this.id);
});

但您可能想听听它不起作用的原因:这是因为JavaScript将tmpvar绑定到更大的范围。

以下代码之所以有效,是因为我们将tmp的当前值显式绑定到正在创建的新函数:

for (i=0;i<=7;i++) {
    var tmp = 'iinp' + i;
    $("#"+tmp).keyup((function(xtmp){ return function(){keyReleased(xtmp);} })(tmp));
}

不要使用带编号的id。

而是使用类。

$('.iinp').keyup(function() {
  var index = $(this).index('.iinp');
  keyReleased('iinp', index);
});

HTML

<input class="input" id="iinp0" />
<input class="input" id="iinp1" />
<input class="input" id="iinp2" />

JS

$(function(){
    $('.input').keyup(function() {
        keyReleased(this.id.replace('iinp', ''));
    });
    function keyReleased(key) {
        console.log(key)
    }
})

假设每个输入都有相同的类,或者是相同的元素类型(如input),则可以使用选择器和on()函数将它们全部分配给同一函数,并将元素的id传递给keyReleased()函数:

示例HTML:

<div id="formData">
    <input type="text" id="iinp0" >
    <input type="text" id="iinp1" >    
</div>

jQuery JavaScript:

$("#formData").on("keyup", "input", function() {
    keyReleased($(this).attr('id')); 
});

http://jsfiddle.net/4SKgU/

剩下的答案会按照你的意愿进行,但就我个人而言,我会更进一步地减少匿名函数的数量(尽管有些方法不会做到这一点):

使用类进行输入

<input class="keyup" id="iinp01" />

使用类和非匿名事件处理程序绑定

(function ($) { // closure
    $(function () { // on document ready
        $("input.keyup").keyup(keyReleased);
    });
    function keyReleased(e) {
        var id = this.id,
            $input = $(this);
        // Do whatever you want
    }
})(jQuery);

希望这会有所帮助。如果您不熟悉闭包,请了解它们!

如果可能的话,我还会为上下文提供一个父元素:

<div id="keyup-container"><!-- inputs here --></div>
$("#keyup-container input.keyup")

它会更有效率(如果你担心的话)。

最新更新