473,323 Members | 1,570 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,323 software developers and data experts.

JS and OO: Tying objects to elements

I am having trouble trying to more closely relate objects (as
functions) in javascript with HTML elements. For example, I have an
object 'class' MyImage:

function MyImage(file)
{
var img = document.createElement('IMG');
img.src = file;
img.myProperty = 'myValue';

return img;
}

This uses the DOM to construct and return an HTML IMG element. I can
then instantiate this and refer directly to the img attributes as well
as any properties I have defined, e.g.

var myImage = new MyImage('mypicture.jpg');
document.body.appendChild(myImage);
myImage.style.width = 300;
myImage.myProperty = 'anotherValue';

The problem comes when I then try to define methods on the object's
prototype, e.g.

MyImage.prototype.myMethod = function()
{
alert("shiver in eternal darkness");
}

When called, this gives the error: "Object doesn't support this
property or method".

Is what I am doing by returning a created HTML element from the object
constructor valid and acceptable? If so, how do I define methods on
the object?

Any help would be much appreciated.
Jul 23 '05 #1
6 1444
Martin wrote:
I am having trouble trying to more closely relate objects (as
functions) in javascript with HTML elements. For example, I have an
object 'class' MyImage:

function MyImage(file)
{
var img = document.createElement('IMG');
img.src = file;
img.myProperty = 'myValue';

return img;
}

This uses the DOM to construct and return an HTML IMG element. I can
then instantiate this and refer directly to the img attributes as well
as any properties I have defined, e.g.

var myImage = new MyImage('mypicture.jpg');


By this, you have created a new MyImage object.

You can do what you want in two ways:

a) In the line above, delete 'new'. This will return a DOM Element object to
the myImage variable.
b) Do not return from MyImage function. This way the above line will create
a new MyImage object, which might be a wrapper for images. If you define img
internal variable as this.img, that will create a member of the MyImage
class which could be reached (in this example) as myImage.img.

For more information on OO in Javascript, I recommend
http://www.crockford.com/javascript/private.html and other articles about JS
on http://www.crockford.com/

Berislav

--
If the Internet is a Marx Brothers movie, and Web, e-mail, and IRC are
Groucho, Chico, and Harpo, then Usenet is Zeppo.
Jul 23 '05 #2
On 1 Sep 2004 01:49:40 -0700, Martin <dj*********@gmx.net> wrote:
I am having trouble trying to more closely relate objects (as functions)
in javascript with HTML elements. For example, I have an object 'class'
MyImage:

function MyImage(file)
{
var img = document.createElement('IMG');
Make sure that you feature test DOM methods and objects before using them.
img.src = file;
img.myProperty = 'myValue';

return img;
Returning an object other than null from a constructor returns that
object. To me, that seems pointless. If you want to create objects based
on some sort of pattern, use a factory. This can be something as simple as
a global function, or an object with static methods that instantiate,
modify, then return the object.

[snip]
The problem comes when I then try to define methods on the object's
prototype, e.g.

MyImage.prototype.myMethod = function()
{
alert("shiver in eternal darkness");
}

When called, this gives the error: "Object doesn't support this
property or method".

Is what I am doing by returning a created HTML element from the object
constructor valid and acceptable?
If you return null or a non-object, the result of the constructor
instantiation will be just like normal. If you return an object, the
result will be that object. So, yes it's valid, but it seems to defeat the
object of a constructor.
If so, how do I define methods on the object?


With user-defined objects, what you have done is fine. However, you aren't
dealing with a user-defined object anymore (part of the confusion
resulting from your code). You've got a host object.

Whilst some browsers do allow the prototyping of user-defined members on
host object, IE certainly doesn't. You'll either have to attach the
members on a per-item basis, or encapsulate the functionality in your own
objects.

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
Jul 23 '05 #3
Thanks. I think I understand.

I thought it would be neat to have the DOM element synonymous with the
JS object. This would be useful if you had a more complex object made up
of many DOM elements, all contained within, for example, a div. The
containing div would be created, have the other elements appended to it,
and then be returned from the constructor. For example, if you had a
Graph object:

function Graph()
{
var div = createElement('DIV');
...
this.title = createElement('SPAN');
...
div.appendChild(title);
div.appendChild(chart);

return div;
}

var myGraph = new Graph();
myGraph.title.style...
myGraph.chart.style... etc.

However, it would appear that returning DOM elements from a constructor
is not a good thing. Therefore you would have to make the div a member
of the object too, and then refer to:

myGraph.div.title.style...

This is what Berislav suggested as option (b) above. I must admit that I
don't quite understand what option (a) achieves (removing 'new'), since
you still can't add methods to the prototype of the object.

The only other option I see is the following:

function Graph()
{
var div = ...
this.myMethod = myMethod;
...
return div;
}
function myMethod()
{
// this method is a member of Graph
}

I assume this is what Michael meant by "attaching members on a per-item
basis". Although I'm not sure if you can refer to the keyword 'this'
inside myMethod.
______________________
replace 'nospam' with 'net' for email.

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Jul 23 '05 #4
On 01 Sep 2004 13:02:28 GMT, Martin <dj*********@gmx.nospam> wrote:
Thanks. I think I understand.
Unfortunately, it seems you missed a point that both I and Berislav made.

In the normal scheme of things,

function MyConstructor() {
this.myProperty = 'Test';
}

var myObject = new MyConstructor();
alert(myObject.myProperty);

the code above would display, "Test". An object is made from a function
that acts as a constructor.

However, if you return an object the affects of normal operation are
ignored. An object isn't made out of the constructor; the returned object
is what results. This can be demonstrated by:

function MyConstructor() {
this.myProperty = 'Test';
return {}; // Return an object
}

var myObject = new MyConstructor();
alert(myObject.myProperty);

Instead of "Test", the alert shows "undefined". The object that would have
normally resulted has been destroyed, including the property, myProperty.
I thought it would be neat to have the DOM element synonymous with the
JS object. This would be useful if you had a more complex object made up
of many DOM elements, all contained within, for example, a div. The
containing div would be created, have the other elements appended to it,
and then be returned from the constructor.
To do this, you need to encapsulate everything inside a user-defined
object:

function Graph() {
this.div = document.createElement('DIV');
// ...
this.title = document.createElement('SPAN');
// ...
this.div.appendChild(this.title);
}

var myGraph = new Graph();
// myGraph.div.<whatever>

Alternatively, you could use a proper OO approach and make the data
private:

function Graph() {
var div = document.createElement('DIV'),
title = document.createElement('SPAN');

// ...
div.appendChild(title);

this.setTitleStyle = function(prop, value) {
if(title.style) {title.style[prop] = value;}
};
// Other "privaledged" methods
}

[snip]
However, it would appear that returning DOM elements from a constructor
is not a good thing.
Returning any object[1] is a bad thing. Just like in C++ and Java,
constructors should not return values.

[snip]
function Graph()
{
var div = ...
this.myMethod = myMethod;
...
return div;
}
function myMethod()
{
// this method is a member of Graph
}


You should now see that that won't work. There is no Graph object as a
result of using the Graph constructor. All you get is a DIV host object,
and the property, myMethod, will not be a part of it.

If you want to use the host object as the encapsulating object, then use a
standard function to create the various contained objects and return the
DIV that way:

function Graph_myMethod() {
// ...
}

function createGraph() {
var div = document.createElement('DIV');

div.myMethod = Graph_myMethod;
// ...
return div;
}

var myGraph = createGraph();

The variable, myGraph, now references a DIV element that contains the
method, myMethod.

myGraph.myMethod(); // calls Graph_myMethod with the this operator
// set to the object referred to by myGraph

[snip]

Hope that helps,
Mike
[1] Except possibly the this object, but that's redundant.

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
Jul 23 '05 #5
Martin wrote:
I am having trouble trying to more closely relate objects (as
functions) in javascript with HTML elements.
...


You've received some very good replies to this question - but
I thought I would throw mine in as well :-)

I have a demo that is related to the question:

http://cross-browser.com/toys/tristateimage.html

Feedback (good or bad) is welcome.
Jul 23 '05 #6
Martin wrote:
I am having trouble trying to more closely relate objects (as
functions) in javascript with HTML elements. For example, I have
an object 'class' MyImage:
There are no classes in ECMAScript < 4, JavaScript < 2 and JScript < 6.
You have defined a constructor.
function MyImage(file)
{
var img = document.createElement('IMG');
img.src = file;
img.myProperty = 'myValue';

return img;
}

This uses the DOM to construct and return an HTML IMG element. I can
then instantiate this and refer directly to the img attributes as well
as any properties I have defined, e.g.

var myImage = new MyImage('mypicture.jpg');
document.body.appendChild(myImage);
myImage.style.width = 300;
myImage.myProperty = 'anotherValue';

The problem comes when I then try to define methods on the object's
prototype, e.g.

MyImage.prototype.myMethod = function()
{
alert("shiver in eternal darkness");
}

When called, this gives the error: "Object doesn't support this
property or method".
How do you call the method?
Is what I am doing by returning a created HTML element from the
object constructor valid and acceptable?
Yes and no. A constructor must not return an object reference if not
intended to be a factory. You may not use this method as a constructor
(using the "new" keyword) if you want to return a reference to the DOM
object, only as a factory (calling it and evaluate the result).
If so, how do I define methods on the object?
Exactly as you did.
Any help would be much appreciated.


You're welcome.
PointedEars
--
Life is like a grapefruit. -- F. Prefect
Jul 23 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Andrés Giraldo | last post by:
Hi! I'm trying to pass trough all the objects of a form but I have some text inputs in a DIV and I have many DIVs like this on my form. I'm doing something like: for (i = 0; i <...
9
by: F. Da Costa | last post by:
Hi, Does anybody know why IE5+ does *not* honour array objects (like a table) across a session? Example: Frame A contains a var tableVar which is set via form Frame B (on init) using...
11
by: Bo Peng | last post by:
Dear List, It is not clear what the title means. :-) Here is the details: I need to manage a big bunch of small objects, like struct{ int a; int b; }obj;
6
by: Alfonso Morra | last post by:
I have written the following code, to test the concept of storing objects in a vector. I encounter two run time errors: 1). myClass gets destructed when pushed onto the vector 2). Prog throws a...
3
by: ytrewq | last post by:
Should dynamic ("expando") properties be restricted to native and user-defined objects? Or should host objects - such as references to the browser or a plug-in or to the document and its elements -...
13
by: Markus Ernst | last post by:
Hello In a content administration tool I call classes from inside classes in order to separate the admin functions from the display-only functions: class book { var $title; var $author;...
25
by: Jack | last post by:
Hi, Is there a general solution for the following problem: I have an array of instances of class B. Class B is publicly derived from class A. Then I have a class named Buffer that generally...
3
by: orkonoid | last post by:
Hello, I am having trouble with a Polymorphism issue using container classes. I have a longwinded and shortwinded version of my question: Shortwinded version: How can I store base class...
15
by: Juha Nieminen | last post by:
I'm sure this is not a new idea, but I have never heard about it before. I'm wondering if this could work: Assume that you have a common base class and a bunch of classes derived from it, and...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.