【问题标题】:jquery each adding custom method over iterationjquery each 在迭代中添加自定义方法
【发布时间】:2013-12-24 22:07:43
【问题描述】:

我有一组复选框,我想根据它们的类为它们创建一个自定义方法。

var checkboxs = $("input[type=checkbox]");
    checkboxs.each(function(){
        if($(this).hasClass("class1")){
            $(this).method1 = function(){
                $(this).removeAttr("checked");
                return $(this);
            }
        }
        if($(this).hasClass("class2")){
            $(this).method1 = function(){
                $(this).parents("tr").next().hide();
                $(this).removeAttr("checked");
                return $(this);
            }
        }
    });

如果,我想这样做:

checkboxs.each(function(){
        $(this).method1();
    });

它告诉我没有 method1 方法。为什么这不起作用?

【问题讨论】:

    标签: jquery object methods each


    【解决方案1】:

    问题在于$(this) 使用this 变量创建了一个新的jQuery 对象。每次调用 $(this) 时都会执行此操作,因此在某个位置向 $(this) 添加方法不会使该方法在后续调用 $(this) 时持续存在。

    这个jsFiddle显示问题http://jsfiddle.net/92cub/1/

    编辑:我认为每个元素的函数可能不同,我已将给定代码更改为在 jQuery 中使用 data 函数。你也在重复$(this),所以我删除了它。一遍又一遍地调用$(this) 非常繁重。

    您可以这样做:

    var checkboxs = $("input[type=checkbox]");
        checkboxs.each(function(){
          var $this = $(this);  
    
          if($this.hasClass("class1")){
               $this.data("func", function (){
                    $this.removeAttr("checked");
                    return $this;
                });
            }
            if($this.hasClass("class2")){
                $this.data("func", function(){
                    $this.parents("tr").next().hide();
                    $this.removeAttr("checked");
                    return $this;
                });
            }
        });
    

    调用函数使用:

    checkboxs.each(function(){
        $(this).data("func").apply();      
    });
    

    【讨论】:

      【解决方案2】:

      或者您可以编写一个扩展 jquery 原型的通用函数。

      $.fn.method1 = function(){
          if(!this.is(':checkbox')) return this; //If it is called on a non check box just do nothing
          if(!this.is('.class1, .class2')) return this; //if this is not of targetted classes return
      
          if(this.is('.class2')){ //if class2 hide the next of its closest tr which comes up in its parent hierarchy.
              this.closest('tr').next().hide();  //using closest assuming you want to check only its immediate tr in its parent hierarchy
          }
          this.prop("checked", false); //uncheck it if it is class 1 or 2
          return this;
      }
      

      Demo

      • 通过这种方式,您可以将此功能扩展到任何其他元素。
      • 您可以通过设置选项进行自定义,(例如:指定类回调等)

      通过以下方式,您可以避免源代码迭代:

      方法:

      $.fn.method1 = function () {
          this.each(function(){
              var $this = $(this);
              if (!$this.is(':checkbox')) return true;
              if (!$this.is('.class1, .class2')) return true;
              if ($this.is('.class2')) {
                  $this.next().css('color', 'red');
              }
              $this.prop("checked", false);
          });
          return this;
      }
      

      用法:

      $("input[type=checkbox]").method1();
      

      Demo

      【讨论】:

      • 很好,这是一种非常优雅(和 jQuery)解决实际问题的方法。
      • @cincodenada 谢谢。虽然可能可以改进得更好......但是如果OP有兴趣扩展功能,猜测会更可重用......
      【解决方案3】:

      您不能只将这样的属性分配给 jQuery 对象,因为它只是元素的包装器,并且每次都会重新创建。

      如果要将属性附加到元素,请使用data() method。我不确定这是否适用于函数,但值得一试。

      不过,在你的情况下,我怀疑我们有一点 XY problem。我只是在回调中检查对象的类。

      这可能是什么样子的一个例子:

      method1 = function() {
          if($(this).hasClass("class2")) {
              $(this).parents("tr").next().hide();
          }
          $(this).removeAttr("checked");
          return $(this);
      }
      
      checkboxs.each(function(){
          method1();
      });
      

      根据您的用例,在选择时调用 each() 也可能有效,这可能看起来像只运行此代码而不是最后一段代码:

      $('input[type=checkbox].class1').each(function(){
          $(this).method1 = function(){
              $(this).removeAttr("checked");
              return $(this);
          }
      });
      $('input[type=checkbox].class2').each(function(){
          $(this).method1 = function(){
              $(this).parents("tr").next().hide();
              $(this).removeAttr("checked");
              return $(this);
          }
      });
      

      如果没有一些实际的代码和上下文,我们无法真正告诉你如何最好地做你想做的事。

      【讨论】:

      • 关于XY 问题的观点非常好。 OP 应该比我更坚持你的答案。
      猜你喜欢
      • 2010-12-14
      • 2012-10-17
      • 2013-03-08
      • 1970-01-01
      • 2019-02-15
      • 1970-01-01
      • 2011-07-09
      相关资源
      最近更新 更多