为什么要将 jquery.fn 对象传递给 jqueryobject

发布于 2024-08-16 18:42:13 字数 4462 浏览 5 评论 0原文

我仍在尝试了解插件程序 这样我就可以自己编写或改编另一个。

我尝试向这个插件学习 它使用 fn.extend 设置方法,然后将其自身(使用此)传递给某个函数 在 jquery.extend 中制作。

jQuery.fn.extend({
    everyTime: function(interval, label, fn, times) {
        return this.each(function() {
            jQuery.timer.add(this, interval, label, fn, times);
        });
    },

我还看到其他插件不这样做。

这是为什么??或者它背后的想法是什么。

(我读了一些其他解释,说一个用于函数,另一个用于方法,但这对我来说很模糊。)

谢谢,理查德

编辑

完整的插件代码,它使用两个不同的扩展

jQuery.fn.extend({
    everyTime: function(interval, label, fn, times) {
        return this.each(function() {
            jQuery.timer.add(this, interval, label, fn, times);
        });
    },
    oneTime: function(interval, label, fn) {
        return this.each(function() {
            jQuery.timer.add(this, interval, label, fn, 1);
        });
    },
    stopTime: function(label, fn) {
        return this.each(function() {
            jQuery.timer.remove(this, label, fn);
        });
    }
});

jQuery.extend({
    timer: {
        global: [],
        guid: 1,
        dataKey: "jQuery.timer",
        regex: /^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,
        powers: {
            // Yeah this is major overkill...
            'ms': 1,
            'cs': 10,
            'ds': 100,
            's': 1000,
            'das': 10000,
            'hs': 100000,
            'ks': 1000000
        },
        timeParse: function(value) {
            if (value == undefined || value == null)
                return null;
            var result = this.regex.exec(jQuery.trim(value.toString()));
            if (result[2]) {
                var num = parseFloat(result[1]);
                var mult = this.powers[result[2]] || 1;
                return num * mult;
            } else {
                return value;
            }
        },
        add: function(element, interval, label, fn, times) {
            var counter = 0;

            if (jQuery.isFunction(label)) {
                if (!times) 
                    times = fn;
                fn = label;
                label = interval;
            }

            interval = jQuery.timer.timeParse(interval);

            if (typeof interval != 'number' || isNaN(interval) || interval < 0)
                return;

            if (typeof times != 'number' || isNaN(times) || times < 0) 
                times = 0;

            times = times || 0;

            var timers = jQuery.data(element, this.dataKey) || jQuery.data(element, this.dataKey, {});

            if (!timers[label])
                timers[label] = {};

            fn.timerID = fn.timerID || this.guid++;

            var handler = function() {
                if ((++counter > times && times !== 0) || fn.call(element, counter) === false)
                    jQuery.timer.remove(element, label, fn);
            };

            handler.timerID = fn.timerID;

            if (!timers[label][fn.timerID])
                timers[label][fn.timerID] = window.setInterval(handler,interval);

            this.global.push( element );

        },
        remove: function(element, label, fn) {
            var timers = jQuery.data(element, this.dataKey), ret;

            if ( timers ) {

                if (!label) {
                    for ( label in timers )
                        this.remove(element, label, fn);
                } else if ( timers[label] ) {
                    if ( fn ) {
                        if ( fn.timerID ) {
                            window.clearInterval(timers[label][fn.timerID]);
                            delete timers[label][fn.timerID];
                        }
                    } else {
                        for ( var fn in timers[label] ) {
                            window.clearInterval(timers[label][fn]);
                            delete timers[label][fn];
                        }
                    }

                    for ( ret in timers[label] ) break;
                    if ( !ret ) {
                        ret = null;
                        delete timers[label];
                    }
                }

                for ( ret in timers ) break;
                if ( !ret ) 
                    jQuery.removeData(element, this.dataKey);
            }
        }
    }
});

jQuery(window).bind("unload", function() {
    jQuery.each(jQuery.timer.global, function(index, item) {
        jQuery.timer.remove(item);
    });
});

I am still trying to understand plugin procedure
so I can write my own or adapt another.

I try to learn from this plugin
It sets methods with fn.extend and then passes itself(with this) to some function
made in jquery.extend.

jQuery.fn.extend({
    everyTime: function(interval, label, fn, times) {
        return this.each(function() {
            jQuery.timer.add(this, interval, label, fn, times);
        });
    },

I also see other plugins that don't do that.

Why is that?? or what's the idea behind it.

(I read some other explanations, saying one is used for functions and the other for methods, but that's to vague for me.)

thanks, Richard

EDIT

complete plugin code wich uses two different extends

jQuery.fn.extend({
    everyTime: function(interval, label, fn, times) {
        return this.each(function() {
            jQuery.timer.add(this, interval, label, fn, times);
        });
    },
    oneTime: function(interval, label, fn) {
        return this.each(function() {
            jQuery.timer.add(this, interval, label, fn, 1);
        });
    },
    stopTime: function(label, fn) {
        return this.each(function() {
            jQuery.timer.remove(this, label, fn);
        });
    }
});

jQuery.extend({
    timer: {
        global: [],
        guid: 1,
        dataKey: "jQuery.timer",
        regex: /^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,
        powers: {
            // Yeah this is major overkill...
            'ms': 1,
            'cs': 10,
            'ds': 100,
            's': 1000,
            'das': 10000,
            'hs': 100000,
            'ks': 1000000
        },
        timeParse: function(value) {
            if (value == undefined || value == null)
                return null;
            var result = this.regex.exec(jQuery.trim(value.toString()));
            if (result[2]) {
                var num = parseFloat(result[1]);
                var mult = this.powers[result[2]] || 1;
                return num * mult;
            } else {
                return value;
            }
        },
        add: function(element, interval, label, fn, times) {
            var counter = 0;

            if (jQuery.isFunction(label)) {
                if (!times) 
                    times = fn;
                fn = label;
                label = interval;
            }

            interval = jQuery.timer.timeParse(interval);

            if (typeof interval != 'number' || isNaN(interval) || interval < 0)
                return;

            if (typeof times != 'number' || isNaN(times) || times < 0) 
                times = 0;

            times = times || 0;

            var timers = jQuery.data(element, this.dataKey) || jQuery.data(element, this.dataKey, {});

            if (!timers[label])
                timers[label] = {};

            fn.timerID = fn.timerID || this.guid++;

            var handler = function() {
                if ((++counter > times && times !== 0) || fn.call(element, counter) === false)
                    jQuery.timer.remove(element, label, fn);
            };

            handler.timerID = fn.timerID;

            if (!timers[label][fn.timerID])
                timers[label][fn.timerID] = window.setInterval(handler,interval);

            this.global.push( element );

        },
        remove: function(element, label, fn) {
            var timers = jQuery.data(element, this.dataKey), ret;

            if ( timers ) {

                if (!label) {
                    for ( label in timers )
                        this.remove(element, label, fn);
                } else if ( timers[label] ) {
                    if ( fn ) {
                        if ( fn.timerID ) {
                            window.clearInterval(timers[label][fn.timerID]);
                            delete timers[label][fn.timerID];
                        }
                    } else {
                        for ( var fn in timers[label] ) {
                            window.clearInterval(timers[label][fn]);
                            delete timers[label][fn];
                        }
                    }

                    for ( ret in timers[label] ) break;
                    if ( !ret ) {
                        ret = null;
                        delete timers[label];
                    }
                }

                for ( ret in timers ) break;
                if ( !ret ) 
                    jQuery.removeData(element, this.dataKey);
            }
        }
    }
});

jQuery(window).bind("unload", function() {
    jQuery.each(jQuery.timer.global, function(index, item) {
        jQuery.timer.remove(item);
    });
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

久夏青 2024-08-23 18:42:13

这就是插件机制的工作原理。您可以通过使用自己的函数扩展 jQuery.fn 对象来创建 jQuery 插件。通过直接向 jQuery.fn 对象添加函数,或者通过调用 jQuery.fn.extend()

这些插件函数总是传递 jQuery 对象(即调用它的 DOM 元素的选择)作为 this< /strong> 变量。

例如,假设您想创建一个 jQuery 插件,使用警报显示 DOM 集中的项目数量:

$.fn.showCount = function() { 
   alert("Count = " + this.length); // "this" is a refernce to the jQuery object
}

或 (完全相同):

// $.fn.extend is just a convenience method for extending the jQuery.fn object
// It's also the same as calling $.extend($.fn, { ... })

$.fn.extend( {
                showCount: function() { 
                        alert("Count = " + this.length);
                }
             });

因此,当您调用时:

$("a").showCount();

它会弹出一个警报,告诉您数量文档中的 标记。

编辑

看到您的代码后,我认为我知道您的意思。

当使用 jQuery.extend() (不是 jQuery.fn.extend)时,您并不是在创建一个真正的插件。您只是创建一个全局函数或对象,与 jQuery 本身无关。

事实上,计时器插件可以这样写,并且它会做完全相同的事情:

var timerPlugin = {
       global: [],
        guid: 1,
        dataKey: "jQuery.timer",
        regex: /^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,
        powers: {
            // Yeah this is major overkill...
            'ms': 1,
            'cs': 10,
            'ds': 100,
            's': 1000,
            'das': 10000,
            'hs': 100000,
            'ks': 1000000
        },
        timeParse: function(value) {
           //...
        }
        // ...
  };

然后(例如)您调用 timerPlugin.remove() 而不是 jQuery.timer .remove()。

扩展 jQuery.fn 对象是为了允许在 jQuery 对象上调用您自己的函数。例如: $("a").myPlugin()

需要记住的是 jQuery.extend() 与 jQuery 或 jQuery 插件无关。它只是 jQuery 库提供的一个实用函数。

It's just how the plugin mechanism works. You create jQuery plugins by extending the jQuery.fn object with your own functions. Either by directly adding functions to the jQuery.fn object, or by calling jQuery.fn.extend()

These plugin functions are always passed the jQuery object (i.e. the selection of DOM elements it was invoked on) as the this variable.

For example, let's say you want to create a jQuery plugin that shows the number of items in a DOM set using an alert:

$.fn.showCount = function() { 
   alert("Count = " + this.length); // "this" is a refernce to the jQuery object
}

or (which is exactly the same):

// $.fn.extend is just a convenience method for extending the jQuery.fn object
// It's also the same as calling $.extend($.fn, { ... })

$.fn.extend( {
                showCount: function() { 
                        alert("Count = " + this.length);
                }
             });

So when you call:

$("a").showCount();

It will pop up an alert telling you the number of <a> tags in your document.

EDIT:

After seeing your code, I think I know what you're getting at.

When using jQuery.extend() (not jQuery.fn.extend), you're not creating a REAL plugin. You're merely creating a global function or object, unrelated to jQuery itself.

In fact, the timer plugin could have been written like this, and it would have done exactly the same thing:

var timerPlugin = {
       global: [],
        guid: 1,
        dataKey: "jQuery.timer",
        regex: /^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,
        powers: {
            // Yeah this is major overkill...
            'ms': 1,
            'cs': 10,
            'ds': 100,
            's': 1000,
            'das': 10000,
            'hs': 100000,
            'ks': 1000000
        },
        timeParse: function(value) {
           //...
        }
        // ...
  };

Then (for example) you call timerPlugin.remove() instead of jQuery.timer.remove().

Extending the jQuery.fn object is done to allow calling your own functions on jQuery objects. For example: $("a").myPlugin()

The thing to remember is that jQuery.extend() has nothing to do with jQuery or jQuery plugins. It's simply a utility function provided by the jQuery library.

神魇的王 2024-08-23 18:42:13

有几种方法可以定义插件

$.fn.myFunc=function(opt){

};

$.fn.myOtherFunc=function(opt){

};

$.fn.extend({
  myFunc:function(opt){

  },
  myOtherFunc:function(opt){

  }
});

There are a couple of ways you can define plugins

$.fn.myFunc=function(opt){

};

$.fn.myOtherFunc=function(opt){

};

Is the same as

$.fn.extend({
  myFunc:function(opt){

  },
  myOtherFunc:function(opt){

  }
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文