views:

377

answers:

5

I'd like to extend a DOM element without extending all of them. That is, I'd like a custom class with its own methods and properties, but also be able to treat it as a div. E.g.

 MyClass function(){
    this.foo = "waaa";
 }
 MyClass.prototype.changeText = function(newtext){
    // if this extended $(document.createElement("div") something
    // like this might be possible
    this.html(newtext);
 }
 MyClass.prototype.alertFoo = function(){
    alert(this.foo);
 }

 var m = new MyClass();
 $("body").append(m);
 m.changetext();

Is this possible?

A: 

jQuery won't be able to understand m when you pass it to the append line, because it only accepts strings and elements. Your MyClass will probably have a specific key to hold the element itself (e.g. this.el = document.createElement("div");), but jQuery won't be able to find that on its own.

Salty
Understood, the above was just an example of what I was looking to do. In essence I'm looking for something like:MyClass : document.createElement("div")That is, I don't want to tell jquery to find the specific key, but have jquery think the object itself is the element, i.e. my object extends the element.
bingle
+1  A: 

You could make your own object, like you are doing. Then you can use jQuery's extend method to extend the element.

geowa4
This doesn't work:function more(){ this.myname = "more!" } more.prototype.alert = function(){ alert('alert!') } var div = $(document.createElement("div")); div.html("this is s"); $.extend(true, div, more); $(document).ready(function(){ $("body").append(div); div.alert(); alert(div.myname); });
bingle
right, you need an object, not a function for it to work with the `extend` method. replace the appropriate line with this: `$.extend(true, div, new more);`
geowa4
+1  A: 

The problem will come when you want to retrieve the element later. Maybe you can just store the extensions as data of the element like such:

var new_div = $('<div id="new_div" />');
new_div.data('m', new MyClass());

Then to call the functions later, you would do something like:

new_div.data('m').changetext(new_div)

And pass the div as an argument.

Augustus
Yeah, I realize something like this is possible, but it's certainly not elegant. For all the hype about javascript being so great, the fact that I can't make my custom class walk like a jquery duck kinda sucks.
bingle
A: 

You can also do it as a plugin:

jQuery.fn.myKindOfElement = function(msg) {
    var foo = msg; // foo is basically a private member
    this.alertFoo = function() {
        alert(foo);
    };
    this.setFoo = function(msg) {
        foo = msg;
    };
    this.changeText = function(text) {
        // doesn't make sense because html already exists here
        this.html(text);
    };
};

Then for any element:

var myKind = $('<div/>').myKindOfElement('bar');
$('body').append(myKind);
myKind.alertFoo(); // alerts 'bar'
myKind.changeText('blah'); // same as myKind.html('blah')
Prestaul
A: 

You can make your class a child class of the jquery generated DIV element:

function MyClass (){
    this.foo = "waaa";
}
MyClass.prototype = $('<div/>');
MyClass.prototype.changeText = function(newtext){
    this.html(newtext);
}
MyClass.prototype.alertFoo = function(){
    alert(this.foo);
}

var m = new MyClass();
$("body").append(m);
m.changeText('appletree');