68

I know that you can add new jQuery functions by $.fn.someFunction = function()

However, I want to add functions to specific elements only. I tried this syntax and it doesn't work $('.someElements').fn.someFunction = function()

I want to do this so that I can call the function like this somewhere in the code $('someElements').someFunction();

5
  • I'm not sure if this is even possible, but if it was, why would you want to cripple your code? If you want to restrict it to certain selectors, use those selectors. Or, cache the result from $('.someElements') and call the function as that variable plus .someFunction() later. Commented Jan 17, 2011 at 3:37
  • The problem is $(...).fn doesn't exist, only $.fn. And just setting $(...).someFunction doesn't have the same effect, because it won't run it on each element in its own context. Commented Jan 17, 2011 at 3:41
  • @Robert I don't know why the OP wanted it, but I want to bind functions to elements so that the calling function doesn't need to differentiate between the elements. I have multiple field types each calling for it's own validation method -- since my AJAX call is mostly replicating what the form does without AJAX, it makes sense to write a single function that could call the validate function, then just use the name attribute and value to build up the POST data that would be sent if I used the HTML submit button. It just seems more OOP that way. Commented Jan 14, 2013 at 22:33
  • 1
    Simple: var someElements = $('.someElements'); someElements.myFunc = function() { /* code here */ }; Commented Aug 20, 2015 at 3:05
  • Possible duplicate of How to limit a jQuery plugin function to only some elements? Commented Jan 4, 2016 at 8:10

9 Answers 9

59

For jQuery 1.7 and later, use .on() and .trigger()

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


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

Before jQuery 1.7 we used .bind() method for attaching event handlers (instead of .on()).

Sign up to request clarification or add additional context in comments.

3 Comments

and to get data returned by the function instead of jquery chaining use triggerHandler method
just an update here, 'bind' is deprecated and replaced with 'on'
It is not someFunction. It is someEvent. You bind an event handler for your custom event and triggers an event. To trigger an event and to invoke a plugin function are two different things.
22

yo can do the above with this:

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

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

Test: http://jsfiddle.net/DarkThrone/nUzJN/

3 Comments

there should be a return this in order to chain
@qwertymk: I know, it was to make a point, not to define an entire jQuery plugin. @Reigil: ibidem, I was trying to maka point, that this can already be achieved through jQuery. The entire answer makes no sense. You could select the exact set with $(..) instead of traversing all the matched DOM to eliminate via a new criteria.
@DarkThrone what if i'd like to add a parameter to the function? I've tried to put it in the function() but it doesn't work.
11

@Reigel's answer is great! However you could also use the $.fn syntax and let your function only handle certain elements:

$.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();            

See working jsfiddle: http://jsfiddle.net/AKnKj/3/

1 Comment

For chaining move "return" out of "each": return this.each(funtion(){ ... });
11

Yo, needed to do the same thing, came up with this. its nice cause you destroy the element and function goes poof! I think...

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

1 Comment

your destructor function will not be available inside other functions and events, if snippet is not global which is the case in most UI codes
9

If you're wanting this function only for particular selectors, the following will work for you. I've just had a scenario where I've needed this and it works nicely.

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

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

then later on you can do

$('.my-selector').getUrl()

without having to define it as a plugin, or use data or bind/on/trigger events.

Obviously you can change the function to return the containing object if you want to use it in chaining by returning this

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

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

7 Comments

this will attach getUrl to jquery not just for that element
Would love to why after 3 years, someone down-votes this. An explanation would be nice
I wasn't the one downvoting, but the downvote is probably 'cause this will NOT attach this function only for particular selectors, it will attach it to ALL elements (like commented by @JithinJose, this will attach getURL to jQuery, not just the element). There's a jsfiddle here: jsfiddle.net/xpvt214o/563274
@patrick I honestly don't know if it did previously, but did you stop to think that in 3-4 years that the framework may have actually also changed? After 7 years, I do not think stackoverflow should be the oracle of technical information for current releases of software! Think about it.
@danrichardson, I still found this answer when I was looking for an answer to a problem, so, no, I don't think it was a bad idea to tell others that have the same problem that the solution you posted isn't working, and apparently wasn't working in Sep '14 either...
|
8

I actually had this use case as well, but with a cached object. So I already had a jQuery object, a toggle-able menu, and I wanted to attach two functions to that object, "open" and "close". The functions needed to preserve the scope of the element itself and that was it, so I wanted this to be the menu object. Anyway, you can just add functions and variables all willy nilly, just like any other javascript object. Sometimes I forget that.

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();

3 Comments

This is a great way to handle it. Particularly this is useful if you've added something to the DOM (i.e. a pop-over window) and you only want the functions to be present for that one DOM element. So when you later remove the pop-over, the functions disappear along with it. You could also do it this way: $('#menu')[0].open = function(){ ... }; So that you can get a handle and assign an arbitrary function to it all in one step.
Nice idea, that I was looking for. Unfortunally it does not work. I get open() is not a function when I call it later in code. The problem is, that you bind your function to the jQuery object, not to the DOM. What means, when you access this DOM element later via another selector will no longer have a connection to the assigned function.
Thx @JaredC your comment helped me to rework the code above for my desires
2

The most obvious solution is to assign a function as the object's property:

obj.prop("myFunc", function() {
  return (function(arg) {
    alert("It works! " + arg);
  });
});

Then call it on the object this way:

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

Note: your function is the return value of the outer one, see: http://api.jquery.com/prop/#prop-propertyName-function

Comments

1

I'm not also sure with my answer if this will help you but just a try how about using .live?

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

Comments

-1

I did this and its working fine..

 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>");
}

and call function from your dynamic function which is creating a dynamic control in html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.