【问题标题】:Is it possible to beautify this JavaScript code?是否可以美化这段 JavaScript 代码?
【发布时间】:2017-11-20 07:41:17
【问题描述】:

我已经完成了我的研究,但我找不到任何与我的问题相关的有用信息。

原始 JavaScript 代码

$("#furniture1").keyup(function(){
  samefunction();
});
$("#furniture2").keyup(function(){
  samefunction();
});
$("#furniture3").keyup(function(){
  samefunction();
});

$("#color1").keyup(function(){
  samefunction();
});
$("#color2").keyup(function(){
  samefunction();
});
$("#color3").keyup(function(){
  samefunction();
});

我只能想出这个解决方案,有没有更好的解决方案?

var index_no = 0;

for(var i=1; i<=3; i++)
{
    index_no++;
    var name = '#furniture';
    name += index_no;

    $(name).keyup(function () {
        samefunction();
    });

    var name = '#color';
    name += index_no;

    $(name).keyup(function () {
        samefunction();
    });
}

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    只需用 , 分隔选择器。

    $("#furniture1, #furniture2, #furniture3, #color1, #color2, #color3").keyup(function(){
      samefunction();
    });
    

    例子

    $("#furniture1, #furniture2, #furniture3, #color1, #color2, #color3").keyup(function(){
        console.log(`Fired from the input ${this.id}`);
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <input id="furniture1">
    <input id="furniture2">
    <input id="furniture3">

    对于动态,您需要一个循环。您可以减少循环中编写的代码,如

    for(var i = 1; i <= 3; i++)
    {
        $(`#furniture${i}, #color${i}`).keyup(function () {
            samefunction();
        });
    }
    

    或者正如@Satpal 在 cmets 中提到的,您可以为所有元素添加一个公共类,并使用该类来绑定事件处理程序。

    $(".someClass").keyup(function(){
        console.log(`Fired from the input ${this.id}`);
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <input id="furniture1" class='someClass'>
    <input id="furniture2" class='someClass'>
    <input id="furniture3" class='someClass'>

    【讨论】:

    • 如果我的索引号是 24 怎么办?
    • 你会有动态索引吗?
    • @learnprogramming,添加一个CSS通用类然后使用类选择器绑定事件处理程序
    • @SurenSrapyan 不是动态的...只是好奇如果索引号大于 10 会怎样...如果我输入名称并后跟逗号直到达到 10 会很混乱
    • @learnprogramming 是的,它会很乱。我已经编辑了答案。请再读一遍
    【解决方案2】:

    选项 1:使用事件委托。这个解决方案是纯javascript:

    document.querySelector('body').addEventListener('keyup', (e) => {
      if (e.target.classList.contains('keyup-capturer')) {
        somefunction();
      }
    });
    

    演示

    $ctr = document.getElementById('counter');
    document.querySelector('body').addEventListener('keyup', (e) => {
      if (e.target.classList.contains('keyup-capturer')) {
        somefunction();
      }
    });
    function somefunction() {
        console.log(`Fired from the input ${this.id}`);
        $ctr.innerHTML = parseInt($ctr.innerHTML, 10) + 1;
    };
    <input id="furniture1" class="keyup-capturer">
    <input id="furniture2" class="keyup-capturer">
    <input id="furniture3" class="keyup-capturer">
    <input id="color1" class="keyup-capturer">
    <input id="color2" class="keyup-capturer">
    <input id="color3" class="keyup-capturer">
    
    <div>Key Ups: <span id="counter">0</span></div>

    选项 2 [*]:如果您确实需要使用 jQuery,您可以使用事件委托,或者使用 class 在任何元素中捕获 keyup 时调用相同的函数在那堂课上:

    $('.keyup-capturer').keyup(function() { samefunction(); });
    

    并将.keyup-capturer 类分配给所有#furniture-x#color-x 元素ID。 我不再推荐这种方法。请参阅下面的讨论。


    [*] 一些观察:

    • 使用event delegation over 基于类的侦听器以获得最佳结果。
    • 不要使用 for 循环或 forEachmap 附加事件处理程序。您只会添加大量事件处理程序,最终您会发现页面变得更慢且更复杂。
    • 避免将侦听器附加到选定元素的集合(如选项#2 中所示)。见this line in jQuery's source code。 jQuery 对您隐藏了实现细节,但在幕后,它仍然为每个元素附加一个事件侦听器。因此,如果您使用非基于 ID 的选择器,例如类选择器 $('.c1') 或属性选择器 $('[disabled]') 等),请记住这一事实。感谢 @t.niese 在 cmets 中的 pointing this out

    【讨论】:

    • 为什么你在另一个问题和这个答案中抱怨mapforEach 的糟糕表现,而在你的答案中却提出了同样的建议? $(".keyup-capturer").keyup(...) 还将遍历每个匹配的元素,以将单独的事件侦听器附加到每个元素。
    • 是的。使用 addEventListener
    • 与使用forEachaddEventListener 的解决方案相比,使用$(".keyup-capturer").keyup(...) 将添加相同数量的事件处理程序,jQuery api 只是对您隐藏了这一点。
    • 我不推荐 $classSelector.keyup 方法。我推荐事件委托方法。
    • 当时我写cmets你不推荐事件委托,答案是矛盾的,现在你已经纠正了大部分。选项 2 中的 [...]you can either use event delegation, or use a class for calling the same function on when keyup is captured in any element on that class[...]Don't use for loops 仍然具有误导性,因为它表明使用类和委托事件是相似的,但使用类会使用循环。
    【解决方案3】:

    尝试在所有家具上添加类furniture,在所有颜色上添加类color,等等...以便您可以按组选择它们:

    let furnitures = document.querySelectorAll('.furnitures');
    furnitures.forEach((furniture) => {
       furniture.addEventListener('keyup', function() {
          // your code here
       })
    })
    

    或者你可以直接传递你的函数:

    let furnitures = document.querySelectorAll('.furnitures');
    furnitures.forEach((furniture) => {
       furniture.addEventListener('keyup', samefunction)
    })
    

    【讨论】:

    • furnitures.forEach((furniture) =&gt; { furniture.addEventListener('keyup', samefunction()) }) 不起作用,因为您将执行处理程序而不是绑定它。应该是 ``` let Furnitures = document.querySelectorAll('.furnitures');家具.forEach((家具)=> {家具.addEventListener('keyup',samefunction)})```
    猜你喜欢
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多