jQuery插件

时间:2015-10-07 18:08:57

标签: jquery

是否有可能创建一个jQuery插件,使得语法使用带点标记的嵌套函数而不需要传入参数?

例如:

$.fn.switchElement = {};

$.fn.switchElement.in = function() {
  console.log(this); // logs $.fn.switchElement as an object containing a function called 'in'
  this.attr('id'); // TypeError: this.attr is not a function (naturally; the above line shows us that it's not a jQuery object)
}

正如评论所提到的那样,试图通过像($(selector).switchElement.in();这样的东西调用不起作用,因为对this的引用不是编写jQuery插件所需要的;即this需要成为传入的jQuery对象。

我是第一个承认,这是纯粹的语法,插件将完全正常接受" in"相反,$.fn.switchElement函数的参数。

那就是说,我可以用一种模式来实现我的目标吗?

[编辑]

我在下面尝试了其中一个建议......当然没有完全理解它。这是我理解它的最佳尝试:

定义一个将成为插件的函数,称为"切换器"接受一个论点。在我的情况下,我打算传递一个jQuery对象,这是一个目标,所以我称之为我的" $ target"。

在切换器中是嵌套函数,称为(现在)switchIn()。因为它在switcher的范围内,所以它可以访问相同的this。我理智地检查我有一个$target然后我将this(一个jQuery对象)附加到目标,然后返回this以便于链接。

现在声明了这个函数,我们将它移动到一个任意称为" inner"的对象中。在" inner"内,我们设置函数to()to()是一个基本上switchIn()的函数,但与范围内的this以及$ target绑定。

我还没有完全理解第一个setTimeout。但在其中,内部(或函数嵌套)成为名为" switchElement"的插件。

switcher结束时,会返回this,这又允许链接。

下一个$.fn[pluginName]我也不明白。我没有设置一个名为" switchElement"的插件。其中包含一个名为"到"?

的函数

最后是额外有趣的部分。首先,我通过调用链接到jQuery对象并传入我的目标来初始化插件。这样可以在封闭类比中设置this$target吗?这是否意味着在重新初始化之前$ target始终是目标?

在提供的示例代码中,我还包括一个额外的按钮单击,显示我希望我可以使用的语法,无需初始化。只需$(selector).switchElement.to($(target))。这也是一个小提琴:http://jsfiddle.net/comrhqr4/1/

(function($) {

  var pluginName = "switchElement";

  var switcher = function switcher($target) {

    var switchIn = function switchIn($target) {
        console.log('invoking fn and sanity checking $target, which is ', $target);
      if ($target) {
        this.appendTo($target);
      }
      return this
    }

    var inner = {
      "to": switchIn.bind(this, $target)
    };

    setTimeout(function() {
      $.fn[pluginName] = inner
    })

    return this
  };

  $.fn[pluginName] = switcher;

    $(document).on('click', '#switchTo1', function() {
        console.log('clicked #switchTo1');
      $('#unique').switchElement($('#container1'));
        setTimeout(function() {
          $('#unique').switchElement.to().css('color', 'blue');
        })
    });

    $(document).on('click', '#switchTo4', function() {
        console.log('clicked #switchTo4');
      $('#unique').switchElement.to($('#container4'));
    });

}(jQuery));

所以,还有一些问题:

  1. 是否正确假设$ target现在已设置,直到重新初始化?
  2. 有没有办法达到我的"按钮4所需的语法按"?

1 个答案:

答案 0 :(得分:1)

尝试使用Function.prototype.bind()setTimeout();注意,需要先调用$(element).pluginName([args])

来初始化插件

(function($) {
  
  var pluginName = "switchElement";
  
  var Foo = function Foo(args) {
    
    var fn = function fn(args) {
      console.log(this, this.attr("id"));
      if (args) {
        this.html(args)
      }
      return this
    }

    var inner = {
      "in": fn.bind(this, args)
    };

    setTimeout(function() {
      $.fn[pluginName] = inner
    })

    return this
  };

  $.fn[pluginName] = Foo;
  
}(jQuery));

$("body").switchElement("123");
setTimeout(function() {
  $("body").switchElement.in();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

<body id="abc">
</body>

或者,使用$.extend()

var switchElement = { in : function() {
    console.log(this, this.attr("id"))
  }
}
$.fn.switchElement = function() {
  return $.extend({}, this, switchElement)
};

$("body").switchElement().in()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<body id="abc"></body>