Mechanius
Mechanius

Reputation: 1

Add function to a jQuery element

I'm trying to add a function to an object with jQuery. Unfortunately this does not work as expected. This jsfiddle shows a minimal example of my problem. I just started with jQuery and reading the docs, but I need a hint in which direction I should go to solve my problem.

Thank you.

<ul id="ul_list">
    <li id="li_a">a</li>
</ul>
$("#li_a").speak = function () {
    alert("Hello I'm a!");
};

var button = $('<button/>').html('speak');
button.click(function () {
    $('#li_a').speak();
});
button.appendTo("body");

Upvotes: 0

Views: 56

Answers (4)

Mechanius
Mechanius

Reputation: 1

thanks for the help.

I found a solution for my problem probably no the nicest but works for me.

<ul id="ul_list">
    <li id="li_a">a</li>
</ul>   
$('#li_a') [0].speak = function () {
  alert('Hello I\'m a!');
};
var button = $('<button/>').html('speak2');
button.click(function () {
  var el = $('#li_a') [0];
  if (typeof el.speak == 'function') el.speak(); 
});
button.appendTo('body');

With [0] I get the DOM element I guess.

Upvotes: 0

itdoesntwork
itdoesntwork

Reputation: 4802

What you're doing isn't working because jQuery's $ function returns an new array-like object containing elements each time you call it. Mutating one of those only changes its instance, and the next time you call $ to fetch the elements, it's a brand new array.

What you can do instead is use jQuery's data function to store the function inside the object:

$("li_a").data("speak", function() {
    alert("Hello I'm a!");
});

and call it with

button.click(function () {
    $("li").each(function () {
        $(this).data("speak")();
    });
});

Notice how the function must be called in the loop - we first access the data under 'speak' then call it.

This method works well when you want different behaviors for each element. If they all are to behave similarly, then you might be better off extending $.fn as the other answers describe because doing this assigns behavior to all objects.

Upvotes: 0

Timmerz
Timmerz

Reputation: 6199

try this jsfiddle:

http://jsfiddle.net/w22aj7rs/

(function ($) {

    $.fn.speak = function () {
        alert("Hello I'm speaking!");
        return this;
    };

}(jQuery));

var button = $('<button/>').html('speak');
button.click(function () {
    
    $('li').each(function () {
        $(this).speak();
    });
});
button.appendTo("body");

Upvotes: 0

Alex W
Alex W

Reputation: 38253

You are adding the member function incorrectly. To do this, you need to extend jQuery's prototype object. You need to attach to $.fn.speak:

$.fn.speak = function () {
    alert("Hello I'm a!");
};

var button = $('<button/>').html('speak');
button.click(function () {
    $('#li_a').speak();
});

Upvotes: 1

Related Questions