【问题标题】:Hiding Rows Given A Certain Criteria (slow)给定特定条件隐藏行(慢)
【发布时间】:2011-03-13 08:46:00
【问题描述】:

如果其中的输入符合特定条件,我会尝试将 tr 隐藏在 html 表中。 条件由下拉列表的选定值定义。 我是这样做的:

$(function () {

  $('body').find('#p_Selection').live('change', function () {

    var type = $('body').find('#p_Selection').attr('value');
    var tableRow = $('.goods').find('.detail-child tr');

    tableRow.each(function (index) {

      var Record_LidExpected = $('input[id$=Record[' + index + ']_LidExpected]').attr('value');
      var Record_LidObtained = $('input[id$=Record[' + index + ']_LidObtained]').attr('value');
      var Record_QuantityExpected = $('input[id$=Record[' + index + ']_QuantityExpected]').attr('value');
      var Record_QuantityObtained = $('input[id$=Record[' + index + ']_QuantityObtained]').attr('value');

      if (type == "1") {

        if (Record_LidExpected != Record_LidObtained) {
          $(this).hide();
        }
        else {
          if (Record_QuantityExpected != Record_QuantityObtained) {
            $(this).hide();
          }
        }
      }
      else {
        if (type == "2") {
          if (Record_LidExpected == Record_LidObtained) {
            $(this).hide();
          }
          else {
            if (Record_QuantityExpected == Record_QuantityObtained) {
              $(this).hide();
            }
          }
        }
        else {
          if (type == "0") {
            $(this).show();
          }
        }
      }
    });
  });
});​

这个脚本在我的 aspx 页面中变得非常慢,而且因为太重而无法完成。 有关如何使其更快的任何建议?

【问题讨论】:

    标签: jquery performance select html-table hide


    【解决方案1】:

    性能优化的关键点

    • 少选(不要全选onchange
    • 保存不会改变的选择
    • 选择元素时尽可能具体

    奖励:学习使用else if,因为您的分支变得更加清晰。

    代码如下:

    $(function () {
    
      // pre-select things that won't change
      var $sel = $('#p_Selection'); 
      var tableRow = $('.goods .detail-child tr');
    
      //
      // ONCHANGE EVENT 
      // keep in mind that everything in it will be very costly
      //
      $sel.live('change', function () {
    
        var type = $sel.attr('value');
    
        tableRow.each(function (index) {
    
          // this just makes the code shorter
          var record = '#Record'+index;
    
          // simple ID selector is enough, since its unique
          var Record_LidExpected =  $(record+'_LidExpected').attr('value');
          var Record_LidObtained =  $(record+'_LidObtained').attr('value');
          var Record_QuantityExpected = $(record+'_QuantityExpected').attr('value');
          var Record_QuantityObtained = $(record+'_QuantityObtained').attr('value');
    
          if (type == "1") {
            if (Record_LidExpected != Record_LidObtained) {
              $(this).hide();
            } else if (Record_QuantityExpected != Record_QuantityObtained) {
              $(this).hide();
            }
          } else if (type == "2") {
            if (Record_LidExpected == Record_LidObtained) {
              $(this).hide();
            } else if (Record_QuantityExpected == Record_QuantityObtained) {
              $(this).hide();
            }
          } else if (type == "0") {
            $(this).show();
          }
        });
      });
    });
    

    【讨论】:

    • 你说得对 Galambalazs,我接受了你的回答,但我仍然会使用 if/else 的开关。非常感谢您教我一些基础知识。
    • 不客气。 switch / if-else 同样不错。你似乎不知道else + if 可以变成else if。这是我想指出的。
    • 我刚刚尝试运行脚本,但浏览器处理起来仍然太慢,实际上它挂在浏览器上。我忘了提到,该表可以从数据库加载多达数千行。这样做不是我的选择,但我必须能够根据下拉列表中的选择隐藏行。你能帮我一把吗?
    • @Hallaghan,只是想知道您不接受我的回答并选择了这个吗?特别是因为这个有非常明显的错误。我不是不高兴,只是好奇。
    • 我上传了一个错误的版本,是的。但现在它没有错误。我在上面运行了 jslint。
    【解决方案2】:

    在我的重写中你会注意到一些事情。

    1. 我省略了$('body').find(),因为它与直接选择#p_Selection 相比没有任何优势。
    2. 当使用$() 函数选择input 值时,我将添加this 作为第二个参数。这基本上告诉 jQuery 在 this 中查找输入(在这种情况下,它指的是每个循环中的当前 tr。这里的优点是 jQuery 不需要在整个 DOM 中搜索该特定输入,就在当前的tr 标签内。
    3. 我刚刚使用 switch 语句和一些 || 运算符稍微清理了您的 if/else 逻辑。

    我认为现在应该运行得更快。

    <script type="text/javascript">
      $(function() {
    
        $('#p_Selection').live('change', function() {
          var type = $(this).val();
    
          var Record_LidExpected, 
              Record_LidObtained, 
              Record_QuantityExpected, 
              Record_QuantityObtained;
    
          $('.goods .detail-child tr').each(function(index) {
    
            Record_LidExpected = $('input[id$=Record['+index+']_LidExpected]', this).val();
            Record_LidObtained = $('input[id$=Record[' + index + ']_LidObtained]', this).val();
            Record_QuantityExpected = $('input[id$=Record[' + index + ']_QuantityExpected]', this).val();
            Record_QuantityObtained = $('input[id$=Record[' + index + ']_QuantityObtained]', this).val();
    
            switch(type) {
              case "1" :
                if (Record_LidExpected != Record_LidObtained || Record_QuantityExpected != Record_QuantityObtained) {
                  $(this).hide();
                }
              break;
              case "2" :
                if (Record_LidExpected == Record_LidObtained || Record_QuantityExpected == Record_QuantityObtained) {
                  $(this).hide();
                }
              break;
    
              case "0":
                $(this).show();
              break;
            }
          });
        });
      });
    </script>
    

    【讨论】:

    • 我喜欢每个人的建议,它们对我学习 jQuery 很有帮助,但不幸的是,我只能将一个回复标记为答案,而 Jesse 的建议是最有帮助的。感谢大家帮助我。
    • 但它仍然在一个onchange 事件中做了太多事情。在我的回答中考虑我的建议
    • $('.goods .detail-child tr') 将在每个 onchange 事件上运行,您的输入选择器效率极低,并且使用 $(this) 您还可以创建一个新的 jQuery 对象实例发生变化的时间。最后,作为旁注,将变量放在函数之外最终会使代码变慢,因为制作变量很便宜,但如果它们在作用域链中,它们的访问时间就会变慢。
    • :) 在来自 OP 的响应之后,我几乎可以肯定问题将出在 jQuery 本身,因为它给操作增加了太多开销。这就是简短代码的代价。
    猜你喜欢
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 2013-12-15
    相关资源
    最近更新 更多