如果检查一个jQuery插件已经绑定到一个DOM节点,您又如何能做到呢?

时间:2022-02-14 23:11:19

Most jQuery plugins are tied/bound to a DOM node when you first initialize them.

大多数jQuery插件在第一次初始化时都绑定/绑定到DOM节点。

$('#foo').bar({options: ...});

How can you check to see what plugins or objects are currently bound to a DOM node like #foo?

如何检查当前绑定到像#foo这样的DOM节点的插件或对象?

if($('#foo').bar)
if($.inArray('bar', $('#foo').eq(0)))
if($('#foo').eq(0).indexOf('bar'))
if($('#foo').hasOwnProperty('bar'))

For example, it's possible to get the events bound to an object like this

例如,可以将事件绑定到这样的对象

console.log($('#foo').data('events'));

3 个解决方案

#1


8  

Unless the plugin itself defined some way of altering the element(s) it's working on, it's not possible. For example:

除非插件本身定义了一些改变它正在处理的元素的方法,否则这是不可能的。例如:

$.fn.extend({
  foo: function() { console.log("I am foo!"); }
});

$('#bar').foo();

Here I defined a complete (well, more-o-less) jQuery plugin which doesn't even try to interact with its calling element. Still, you can use it as you wish, on any jQuery-wrapped collection of elements, as any jQuery-wrapped collection of elements has this method in its prototype because of this line (from jquery.js):

这里我定义了一个完整的jQuery插件,它甚至不尝试与它的调用元素交互。尽管如此,您仍然可以在任何包含jquery的元素集合上使用它,因为任何包含jquery的元素集合的原型中都有这个方法(来自jquery.js):

jQuery.fn = jQuery.prototype = { ... }

... after $.fn.extend was called to plug in that plugin, no pun intended.

…后.fn美元。扩展被调用来插入那个插件,没有双关的意思。

But even if my plugin were required to change its calling element in some way, like this:

但是即使我的插件被要求以某种方式改变它的调用元素,比如:

$.fn.extend({
  bar: function() { this.html('I am all bar now!'); }
});
$('#bar').bar();

... I would still need to, basically, handle this with some external events (DOM Mutation ones), and not just depend on some internal jQuery logging.

…基本上,我仍然需要处理一些外部事件(DOM突变事件),而不仅仅依赖于一些内部jQuery日志记录。

#2


3  

In my case, the plugin I was attempting to detect happens to add some data to the elements $(element).data() store. I've also seen plugins add classes or ID's with either their name - or alterations of their name in them.

在我的示例中,我试图检测的插件恰好向$(element).data()存储元素添加了一些数据。我还看到插件添加了类或ID,其中有它们的名称,也有它们名字的更改。

Below is the code I am currently working with to solve this problem. Probably don't work for most plugins though.

下面是我目前正在处理的解决这个问题的代码。不过,对于大多数插件来说,这可能是行不通的。

$.fn.extend({
    isPluginBound: function(pluginName)
    {
        if(jQuery().pluginName)
        {
            var name = pluginName.toLowerCase();

            return this.data(pluginName) || this.data(name)
                || this.attr('class').toLowerCase().indexOf(name) !== -1 // vs hasClass()
                || this.attr('id').toLowerCase().indexOf(name) !== -1;
        }
    }
});

To use it just call $('#foo').isPluginBound('bar');

要使用它,只需调用$('#foo').isPluginBound('bar');

#3


1  

as far as i know all jQuery Widgets append their instance to their DOM node. im using follwing extension in my projects. it is also useful to call a method on a widget you dont know the name of ( calling a base method of an extended widget for example )

据我所知,所有jQuery小部件都将实例附加到它们的DOM节点上。我在我的项目中使用下列扩展。在不知道名称的小部件上调用方法也很有用(例如调用扩展小部件的基方法)

// returns first found widget instance of the first element or calls method on first widget instance of all elements
$.fn.widget = function ( method , option, value ) { 
  var wi;
  // iterate all elements 
  this.each( function() {
    var wii;
    // iterate all attached data elements, look for widget instances
    $.each( $(this).data(), function( key, data ){ 
      if ( "widgetName" in data ){ wii = data; return false } 
    })
    // if there is a widget instance but no method specified
    if ( wii && !method ) {
      wi = wii;
      return false
    }
    // if there is a widget and there is an object found with the method as the key
    else if ( wii && ( method in wii ) ) {
      // if it is truly a method of that instance, call that instance
      if ( $.isFunction( wii[method] ) ) {
        wi = wii[method].call( wii, option, value )
      } 
      // else, it is maybe a value stored in the instance you seek?
      else {
        wi = wii[method]
      }
    }
  })
  return ( wi === undefined ) ? this : wi ;
}

#1


8  

Unless the plugin itself defined some way of altering the element(s) it's working on, it's not possible. For example:

除非插件本身定义了一些改变它正在处理的元素的方法,否则这是不可能的。例如:

$.fn.extend({
  foo: function() { console.log("I am foo!"); }
});

$('#bar').foo();

Here I defined a complete (well, more-o-less) jQuery plugin which doesn't even try to interact with its calling element. Still, you can use it as you wish, on any jQuery-wrapped collection of elements, as any jQuery-wrapped collection of elements has this method in its prototype because of this line (from jquery.js):

这里我定义了一个完整的jQuery插件,它甚至不尝试与它的调用元素交互。尽管如此,您仍然可以在任何包含jquery的元素集合上使用它,因为任何包含jquery的元素集合的原型中都有这个方法(来自jquery.js):

jQuery.fn = jQuery.prototype = { ... }

... after $.fn.extend was called to plug in that plugin, no pun intended.

…后.fn美元。扩展被调用来插入那个插件,没有双关的意思。

But even if my plugin were required to change its calling element in some way, like this:

但是即使我的插件被要求以某种方式改变它的调用元素,比如:

$.fn.extend({
  bar: function() { this.html('I am all bar now!'); }
});
$('#bar').bar();

... I would still need to, basically, handle this with some external events (DOM Mutation ones), and not just depend on some internal jQuery logging.

…基本上,我仍然需要处理一些外部事件(DOM突变事件),而不仅仅依赖于一些内部jQuery日志记录。

#2


3  

In my case, the plugin I was attempting to detect happens to add some data to the elements $(element).data() store. I've also seen plugins add classes or ID's with either their name - or alterations of their name in them.

在我的示例中,我试图检测的插件恰好向$(element).data()存储元素添加了一些数据。我还看到插件添加了类或ID,其中有它们的名称,也有它们名字的更改。

Below is the code I am currently working with to solve this problem. Probably don't work for most plugins though.

下面是我目前正在处理的解决这个问题的代码。不过,对于大多数插件来说,这可能是行不通的。

$.fn.extend({
    isPluginBound: function(pluginName)
    {
        if(jQuery().pluginName)
        {
            var name = pluginName.toLowerCase();

            return this.data(pluginName) || this.data(name)
                || this.attr('class').toLowerCase().indexOf(name) !== -1 // vs hasClass()
                || this.attr('id').toLowerCase().indexOf(name) !== -1;
        }
    }
});

To use it just call $('#foo').isPluginBound('bar');

要使用它,只需调用$('#foo').isPluginBound('bar');

#3


1  

as far as i know all jQuery Widgets append their instance to their DOM node. im using follwing extension in my projects. it is also useful to call a method on a widget you dont know the name of ( calling a base method of an extended widget for example )

据我所知,所有jQuery小部件都将实例附加到它们的DOM节点上。我在我的项目中使用下列扩展。在不知道名称的小部件上调用方法也很有用(例如调用扩展小部件的基方法)

// returns first found widget instance of the first element or calls method on first widget instance of all elements
$.fn.widget = function ( method , option, value ) { 
  var wi;
  // iterate all elements 
  this.each( function() {
    var wii;
    // iterate all attached data elements, look for widget instances
    $.each( $(this).data(), function( key, data ){ 
      if ( "widgetName" in data ){ wii = data; return false } 
    })
    // if there is a widget instance but no method specified
    if ( wii && !method ) {
      wi = wii;
      return false
    }
    // if there is a widget and there is an object found with the method as the key
    else if ( wii && ( method in wii ) ) {
      // if it is truly a method of that instance, call that instance
      if ( $.isFunction( wii[method] ) ) {
        wi = wii[method].call( wii, option, value )
      } 
      // else, it is maybe a value stored in the instance you seek?
      else {
        wi = wii[method]
      }
    }
  })
  return ( wi === undefined ) ? this : wi ;
}