【问题标题】:How to dodge a DRY issue when calling a function with a constant?使用常量调用函数时如何避免 DRY 问题?
【发布时间】:2012-01-08 20:14:11
【问题描述】:

我还是 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);});

}

keyReleased() 没有使用正确的值调用。

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

【问题讨论】:

    标签: javascript jquery function parameters constants


    【解决方案1】:

    为什么不简单地这样做:

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

    你甚至可以用属性选择器替换那个长选择器:

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

    这将选择任何 id 以 iinp 开头的元素。

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      【讨论】:

      • 请注意,“更大的范围”始终是声明了varfunction。 JavaScript 是 function-scoped,而不是像许多其他语言那样 block-scoped。这意味着例如for 循环不会启动新范围。 JavaScript 解释器在运行代码之前将var 声明从for 循环“提升”到function 的顶部。
      【解决方案3】:

      不要使用编号的 ID。

      改为使用类。

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

      【讨论】:

        【解决方案4】:

        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)
            }
        })
        

        【讨论】:

          【解决方案5】:

          假设您的每个输入都具有相同的类,或者是相同的元素类型(如 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/

          【讨论】:

            【解决方案6】:

            这些答案的其余部分会做你想做的事,但我个人会更进一步减少正在制作的匿名函数的数量(尽管有些方法不会这样做):

            为您的输入使用类

            <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")
            

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

            【讨论】:

              猜你喜欢
              • 2020-10-02
              • 1970-01-01
              • 2018-06-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-06-22
              相关资源
              最近更新 更多