jQuery扩展方法对选择器中的所有元素

时间:2015-07-09 22:07:00

标签: jquery

我尝试使用extend将一个方法添加到从选择器返回的元素集上:

$(document).ready(function () {
    $.extend($('.panel[data-refresh-url!=""][data-refresh-url]'), {
        refresh: function (successFunc) {


            // --- --- --- --- --- --- --- --- --- --- --- --- --- ---
            var refreshElement = $(this).data('refresh-element');
            if (refreshElement == undefined) { refreshElement = $(this).find('.panel-body'); }
            refreshElement.empty().append('<div class="spinner"><i class="fa fa-2x fa-spin fa-spinner"></i></div>');

            $.ajax({
                url: $(this).data('refresh-url'),
                type: 'post',
                data: null,
                success: function (data) {
                    if (successFunc == undefined) {
                        refreshElement.empty().append(data);
                    } else {
                        refreshElement.empty().append(successFunc(data));
                    }
                },
                error: function (xhr, status, error) {
                    refreshElement.empty().append('<i class="fa fa-exclamation-triangle"></i> Could not reload panel..');
                }
            });
            // --- --- --- --- --- --- --- --- --- --- --- --- --- ---


        }
    });
});

更新:我添加了完整的方法,以防万一导致问题。)

我已尝试$.extend$.fn.extend,但每当我尝试拨打$('#element').refresh()时,我都会refresh is not a function

我已经改变了使用bind('refresh')的方法,然后一切正常,但我需要传递一个在成功刷新时执行的功能,而我在印象I下不能这样做。

我真的不太熟悉jQuery - 我错过了什么?

3 个答案:

答案 0 :(得分:1)

您要做的是将refresh方法粘贴到({特定)HTMLParagraphElement组上。要在vanilla JS中执行此操作,您可以执行以下操作:

HTMLParagraphElement.prototype.refresh = function(){
    alert('f');
}

$('p').click(function(){
    this.refresh();
});

请注意您如何拨打this.refresh(),而不是$(this).refresh()

jQuery的一个原则是它封装了自身内的任何新方法 - 它不会扩展现有的DOM对象。因此,$.extend不会按照您希望的方式工作。

我(想想)正在发生的事情是你通过执行$(selector)来获取对jQuery对象中包含的元素的引用。然后,您将扩展该对象,但实际上并未向底层对象添加任何内容。 This fiddle表示您在该范围内$ .extend'对象,但是当您调用该方法时(例如,当您绑定click处理程序时),您已经丢失了任何更改。

有几种不同的方式可以实现您想要做的事情。最简单的方法是使用$.data来存储函数,并通过那里调用它。 Here's a fiddle of that

如果您真的想扩展HTMLParagraphElement,可以通过调用$.extend对象上的prototype来完成。 This blog post详细解释了这一点,但您基本上只是执行以下操作。

$.extend(HTMLParagraphElement.prototype, {
    refresh: function() {
        alert('Refresh called!');
    }
});

$('.panel').find('[data-refresh-url!=""][data-refresh-url]').click(function(){
    this.refresh();
});

我个人认为你不应该修改你不拥有的对象 - 所以我采用$.data方法。或者,jQuery UI使用一个好的模式,在this post on Stack中简要解释。

答案 1 :(得分:1)

我认为你完全滥用了$.extend$.extend用于将两个对象合并在一起,显然可以用于扩展一个带有辅助对象的主对象,就像用花括号创建的那个和单个属性{ {1}}。

现在,在这种情况下,您尝试扩展refresh返回值,这是暂时的。即使你把它放在一个变量中,如下所示:

$('.panel[data-refresh-url!=""][data-refresh-url]')

它只会向var $buttons = $('.panel[data-refresh-url!=""][data-refresh-url]'); $.extend($buttons, { /... 对象添加方法refresh,而不是匹配元素本身。

另一方面,如果你使用$buttons,你将有效地创建一个jQuery插件,并为$.fn.extend返回的每个对象添加一个方法refresh,这不是你猜我想要什么。

在一天结束时,您可以使用循环手动将方法添加到每个匹配的元素:

$

答案 2 :(得分:1)

如果您只是尝试向jQuery对象添加新方法,您是否尝试过使用$.fn.methodName=function(){}

$.fn.newMethod=function(){
    console.log(this); // jQuery object
}
$('#element').newMethod();