将jQuery功能添加到特定元素

63
我知道你可以通过$.fn.someFunction = function()添加新的jQuery函数。
但是,我想仅将函数添加到特定的元素上。 我尝试了以下语法,但它不起作用:$('.someElements').fn.someFunction = function() 我想这样做是为了在代码的某个地方像这样调用函数:$('someElements').someFunction();

我不确定这是否可能,但如果可能的话,为什么要削弱你的代码呢?如果你想将其限制在某些选择器中,请使用这些选择器。或者,缓存 $('.someElements') 的结果,并稍后使用该变量加上 .someFunction() 调用函数。 - Robert
问题在于$(...).fn不存在,只有$.fn。而仅仅设置$(...).someFunction并不能产生相同的效果,因为它不会在每个元素中以自己的上下文运行。 - crimson_penguin
@Robert 我不知道为什么OP想要这样做,但我想将函数绑定到元素上,以便调用函数不需要区分元素。我有多个字段类型,每个类型都需要自己的验证方法--由于我的AJAX调用大部分是在不使用AJAX的情况下复制表单所做的操作,因此编写一个可以调用验证函数的单个函数并使用名称属性和值来构建POST数据似乎更符合面向对象编程的思想。 - RonLugge
1
简单示例: var someElements = $('.someElements'); someElements.myFunc = function() { /* 在此处编写代码 */ }; - jbyrd
9个回答

59

对于 jQuery 1.7 及更高版本,请使用.on().trigger()

$('button').on('someFunction',function() {
    alert('go away!')
});


$('button').click(function(){
    $(this).trigger('someFunction');
});

在 jQuery 1.7 之前,我们使用 .bind() 方法来附加事件处理程序(而不是 .on())。


2
使用triggerHandler方法来获取函数返回的数据,而不是使用jQuery链式调用。 - r043v
9
更新一下,'bind' 已经被弃用,现在使用 'on' 替代。 - DMTintner
4
不是 someFunction,而是 someEvent。您为自定义事件绑定事件处理程序并触发事件。触发事件和调用插件函数是两个不同的操作。 - Green

21

你可以使用以下代码实现:

$.fn.testFn = function(){
    this.each(function(){
        var className = $(this).attr('class');
        $(this).html(className);
    });    
};

$('li').testFn(); //or any element you want

测试:http://jsfiddle.net/DarkThrone/nUzJN/


3
为了链式调用,应该加上 "return this"。 - qwertymk
@qwertymk: 我知道,这只是为了说明问题,并不是要定义整个jQuery插件。@Reigil: 同上,我试图说明的是,这已经可以通过jQuery实现。整个答案毫无意义。你可以使用$(..)选择精确的集合,而不是遍历所有匹配的DOM来通过新标准消除它们。 - DarkThrone
@DarkThrone 如果我想给函数添加一个参数怎么办?我已经尝试将其放在函数()中,但它没有起作用。 - javal88

11

嗨,我需要做同样的事情,我想到了这个。它很好,因为你可以销毁元素并让函数消失!我认为...

var snippet=jQuery(".myElement");
snippet.data('destructor', function(){
    //do something
});
snippet.data('destructor')();

如果snippet不是全局的,也就是在大多数UI代码中的情况下,您的析构函数将无法在其他函数和事件中使用。 - AaA

10
@Reigel的回答很棒!不过,你还可以使用$.fn语法,并让你的函数仅处理特定的元素:
$.fn.someFunction = function(){
    this.each(function(){
        // only handle "someElement"
        if (false == $(this).hasClass("someElement")) {
            return; // do nothing
        }

        $(this).append(" some element has been modified");

        return $(this); // support chaining
    });    
};

// now you can call your function like this
$('.someElement').someFunction();            

请查看可工作的jsfiddle:http:// jsfiddle.net / AKnKj / 3 /


将"return"从"each"语句中移出以进行链接的动作: return this.each(function(){ ... }); - andronick83
将"return"从"each"中移出以进行链式操作: return this.each(function(){ ... }); - undefined

9
如果你只想针对特定的选择器使用此功能,以下内容适合你。我最近遇到了一个需要这个功能的场景,它可以很好地工作。
$('.my-selector').each(function(){

    $(this).init.prototype.getUrl = function(){
        // do things
    };
})

稍后您可以执行以下操作:
$('.my-selector').getUrl()

无需将其定义为插件,也不需要使用数据或绑定/触发事件即可使用。

如果您想在链接中使用它,请显式更改函数以返回包含对象,通过返回this实现。

$('.my-selector').each(function(){

    $(this).init.prototype.getUrl = function(){
        // do things
        return this;
    };
})

3
这将把 getUrl 附加到 jQuery 上,不仅仅针对该元素。 - Jithin Jose
很想知道为什么在3年后,有人会对此进行负评。能否解释一下呢? - dan richardson
1
我不是那个给你点踩的人,但是这个踩可能是因为这个函数并不仅仅针对特定选择器,它会将其附加到所有元素上(就像@JithinJose所评论的那样,这将把getURL附加到jQuery上,而不仅仅是元素)。这里有一个jsfiddle链接:http://jsfiddle.net/xpvt214o/563274/。 - patrick
2
@danrichardson,当我在寻找解决问题的答案时,我仍然发现了这个答案,所以,不,我认为告诉其他遇到同样问题的人你发布的解决方案不起作用并且显然在2014年9月也不起作用并不是一个坏主意... - patrick
对我来说,这种方法是唯一有效的。我需要添加一个特定的函数来装饰文本框结果,所以我使用了domObject.init.prototype.MyFunc...然后调用MyFunc(),效果很好。谢谢。 - Yogurtu
显示剩余2条评论

8

我也曾遇到这种情况,只不过是针对缓存对象的。所以我已经有了一个jQuery对象,一个可切换的菜单,并且我想将两个函数"open"和"close"附加到该对象上。这些函数需要保留元素本身的作用域,而且就这样,所以我希望this是菜单对象。无论如何,你可以像处理其他javascript对象一样随意添加函数和变量。有时候我会忘记这一点。

var $menu = $('#menu');
$menu.open = function(){
   this.css('left', 0);
   this.is_open = true; // you can also set arbitrary values on the object
};
$menu.close = function(){
   this.css('left', '-100%');
   this.is_open = false;
};

$menu.close();

这是一个很好的处理方式。特别是当您向DOM中添加了某些内容(例如弹出窗口)并且您只希望该函数存在于该DOM元素中时,这非常有用。因此,当您稍后删除弹出窗口时,函数也会随之消失。您还可以通过以下方式完成:$('#menu')[0].open = function(){ ... }; 这样,您可以一步获取句柄并将任意函数分配给它。 - JaredC
不错的想法,正是我一直在寻找的。不幸的是它并没有起作用。当我在代码中稍后调用它时,会出现“open()不是一个函数”的错误。问题在于,您将函数绑定到了jQuery对象而不是DOM上。这意味着,当您稍后通过另一个选择器访问此DOM元素时,将不再与分配的函数有任何关联。 - Radon8472
谢谢@JaredC的评论,帮助我修改了上面的代码,以满足我的需求。 - Radon8472

2
最明显的解决方法是将函数分配为对象的属性:
obj.prop("myFunc", function() {
  return (function(arg) {
    alert("It works! " + arg);
  });
});

然后这样在对象上调用它:

obj.prop("myFunc")("Cool!");

注意:您的函数是外部函数的返回值, 请参考:http://api.jquery.com/prop/#prop-propertyName-function

1

我也不确定我的回答是否会对你有帮助,但是可以试着使用.live怎么样?

$(selector).live(click,function(){
    //some codes here
});

-1

我已经做到了,它运行得很好。

 function do_write(){
     $("#script").append("<script> $(\'#t"+(id_app+4)+"\').change(function(){  alert('Write Your Code here');    });<\/script>");
     console.log("<script> $(\'#t"+(id_app+4)+"\').change(function(){  alert('hello');    });<\/script>");
}

并从您的动态函数调用函数,该函数在HTML中创建动态控件


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接