Encapsulation and js, html, css

O

optimistx

It is fun to add a piece of short code to a project, eg. a method of
a nice object/constructor without worrying, which other possibly
numerous locations in the same project have to be changed.

But as the code grows, everything starts to depend on everything
else, the code feels like spaghetti, entangled, and the fun ends.
Which practical principles would keep the fun as long as possible?

How to arrange code so that more or less unknown future changes
would occur in as few separate locations as possible and reasonable?

with still other words:

How to organize js, html, css to achieve good encapsulation and
modularity of all written code?



Books about programming recommend writing classes/objects, which
have clear interfaces, follow certain design patterns and rules:
Separate interface and implementation.
Use encapsulation.
Define classes carefully, avoid monster classes.
Put one task to a method, not many.
Put css to a separate file.
Put js to separet file(s).

Etc, those generally make sense and feel good.

So I do that and the problem is solved, uh?

Between css and html there seems to be no serious problems:
selectors and tags are their common ground, nothing else
to worry about.

css and js seem to live in different worlds in my programs (so far),
no entanglement, no problems.

Between js and html there is a chicken and egg problem. Who is
the boss?

If I write a nice js-'class'/object e.g. to update some program
settings given by the user, the program soon ends up in manipulating
complex forms 'far away on an html-page', breaking encapsulation.
There are at least two code locations to worry about: html-form and
js-methods of the object ( with events).

The obvious idea to generate html-code inside js-object sounded
fascinating at first, but in tests the code started to feel
artificial, long and clumsy especially, if avoiding usage of
innerHTML. The generated html-code would be appended to the
existing htmlelement(s) using the class or id.(compare css).

Is this way of 'having js-constructor as a boss', and generating
html-code with commands document.createElement, element.appendChild
etc the way to go, anyhow? What have you used?

If the input form is written in html and js-code is added to its
elements, the code feels oldfashioned <a href="#" onclick=
"do wonderful things here>...</a> type
of code, but it has the advantage of being in one place only.

There is the other extreme: put everything into js, leave only
minimal html, generate html dynamically with js.

The balance between the extremes has to be found, but how?
Example pages?
 
W

wilq

It is fun to add  a piece of short code to a project, eg. a method of
a nice object/constructor without worrying, which other possibly
numerous locations in the same project have to be changed.

But as the code grows, everything starts to depend on everything
else, the code feels like spaghetti, entangled,  and the fun ends.
Which practical principles would keep the fun as long as possible?

How to arrange code so that more or less unknown future changes
would occur in as few separate locations as possible and reasonable?

with still other words:

How to organize js, html, css  to achieve good encapsulation and
modularity of all written code?

Books about programming recommend writing classes/objects, which
have clear interfaces, follow certain design patterns and rules:
Separate interface and implementation.
Use encapsulation.
Define classes carefully, avoid monster classes.
Put one task to a method, not many.
Put css to a separate file.
Put js to separet file(s).

Etc, those generally make sense and feel good.

So I do that and the problem is solved, uh?

Between css and html there seems to be no serious problems:
selectors and tags are their common ground, nothing else
to worry about.

css and js seem to live in different worlds in my programs (so far),
no entanglement, no problems.

Between js and html there is a chicken and egg problem. Who is
the boss?

If I write a nice js-'class'/object e.g. to update some program
settings given by the user, the program soon ends up in manipulating
complex forms 'far away on an html-page', breaking encapsulation.
There are at least two code locations to worry about: html-form and
js-methods of the object ( with events).

The obvious idea to generate html-code inside js-object sounded
fascinating at first, but in tests the code started to feel
artificial, long and clumsy especially, if avoiding usage of
innerHTML. The generated html-code would be appended to the
existing htmlelement(s) using the class or id.(compare css).

Is this way of 'having js-constructor as a boss', and generating
html-code with commands document.createElement, element.appendChild
etc the way to go, anyhow? What have you used?

If the input form is written in html and js-code is added to its
elements, the code feels oldfashioned <a href="#" onclick=
"do wonderful things here>...</a>  type
of code, but it has the advantage of being in one place only.

There is the other extreme: put everything into js, leave only
minimal html, generate html dynamically with js.

The balance between the extremes has to be found, but how?
Example pages?

1. Its more complicated that you would think at first... In bigger
project its good to have a nice build system (there are at least few
solutions for that right now, and its easy to create own one). It
could take care of things like building needed HTML/CSS/JS from many
separated files that you create to manage fragmentation.

2. IMHO, and after doing some test on different environment I have to
say that from performance side its adviceable to put everything in
simple HTML. I never tried that, but you could even put some
"template" elements in HTML with "display:none" in CSS, and then clone
them if needed from JS side. Basically I think that its a good idea to
separate those layers, but... It all depends on cases. Sometimes you
just cant do it differently :(

3. I would rather not use inline Javascript as it makes more difficult
to maintain in future. This might be only personal feeling, but try to
do some bigger project this way then - I think - you will
understand ;)
 
D

David Mark

1. Its more complicated that you would think at first... In bigger
project its good to have a nice build system (there are at least few
solutions for that right now, and its easy to create own one). It
could take care of things like building needed HTML/CSS/JS from many
separated files that you create to manage fragmentation.

Yes. Offline automated processes eliminate redundant editing without
affecting the end-user.
2. IMHO, and after doing some test on different environment I have to
say that from performance side its adviceable to put everything in
simple HTML. I never tried that, but you could even put some
"template" elements in HTML with "display:none" in CSS, and then clone
them if needed from JS side.

No. You can't hide "templates" in your markup. Some users will end
up seeing (or hearing) them.
Basically I think that its a good idea to
separate those layers, but... It all depends on cases. Sometimes you
just cant do it differently :(

There is virtually always some coupling (e.g. ID's and classes in the
markup are referenced in the CSS and sometimes by scripts).
3. I would rather not use inline Javascript as it makes more difficult
to maintain in future.

See #1. ;)
This might be only personal feeling, but try to
do some bigger project this way then - I think - you will
understand ;)

There are exceptions to this rule. For instance, if you want client
side validation to work during the load, you use the onsubmit
attribute. Otherwise you would either have to hide the form during
loading and show it on load (else the user sees two different
behaviors, one during the load and one after).

That's what has led to all of the "unobtrusive" nuttiness (e.g.
endlessly trying and failing to spot a viable DOMContentReady pattern
to get around self-imposed performance penalties and other avoidable
issues). Easy enough to avoid all of that without penalizing your
users (or yourself) if you understand point #1.
 
O

optimistx

wilq said:
1. Its more complicated that you would think at first... In bigger
project its good to have a nice build system (there are at least few
solutions for that right now, and its easy to create own one). It
could take care of things like building needed HTML/CSS/JS from many
separated files that you create to manage fragmentation.

2. IMHO, and after doing some test on different environment I have to
say that from performance side its adviceable to put everything in
simple HTML. I never tried that, but you could even put some
"template" elements in HTML with "display:none" in CSS, and then clone
them if needed from JS side. Basically I think that its a good idea to
separate those layers, but... It all depends on cases. Sometimes you
just cant do it differently :(

3. I would rather not use inline Javascript as it makes more difficult
to maintain in future. This might be only personal feeling, but try to
do some bigger project this way then - I think - you will
understand ;)

Thanks for your opinions. I see that at least you understood my
complicated question correctly :)

Could you or any other reader give an example of a build
system of item 1 above? (I tried with google, but got too
indefinite hits).

Item 2 of your list: yes, that trick is nice, I have used that also,
but now I am experimenting to generate the html dynamically
with js. My programs are mostly under 100 kbytes each, and
currently no need to work in teams.

---------

As an example we could imagine a task to view/update some
javascript program settings. In principle the program contains
a sets of values in various objects and the user wants to
update one or several of them:

1. display a form to update parameter(s)
2. show parameter name(s) and value(s) on a form.
3. if the user changes a value, check it, and if it is
ok, the accept it as a new value of the parameter, else
give an error message
4. hide the form

It is almost ridiculous how a simple task becomes so complicated
that the best brains of all humankind think of this days in an out,
getting ziljons of different ways to accomplish this.

I tried to write a general little js-program with appropriate
principles proclaimed here and elsewhere: inheritance,
encapsulation, oop , reuse, short and compact, easy to read
(and write).
Hundreds of lines of code, soon thousands. Ugly.
Too complicated. `Lots of things to improve or redesign.

a(i) = 'something'
....update...
a(i) = 'something else' ;

How to accomplish this simply, nicely, ...?

(uh, it helped to complain ...)
 
R

Richard Cornford

On Nov 26, 11:06 am, optimistx wrote:
It is almost ridiculous how a simple task becomes so
complicated that the best brains of all humankind think
of this days in an out, getting ziljons of different
ways to accomplish this.

If the intention is that readers derive sense from that sequence of
words then it is unlikely to be achieved.
I tried to write a general little js-program with appropriate
principles proclaimed
Proclaimed?

here and elsewhere: inheritance,
encapsulation, oop , reuse, short and compact,

"short and compact"?
easy to read (and write).

"easy to write"?
Hundreds of lines of code, soon thousands. Ugly.
Too complicated. `Lots of things to improve or redesign.

a(i) = 'something'
...update...
a(i) = 'something else' ;

Assigning to the result of a function call is not something that you
should expect to get away with in javascript (the language's syntax
allows it, but only host methods are allowed to return something that
can be assigned to).
How to accomplish this simply, nicely, ...?

(uh, it helped to complain ...)

Psychologically, perhaps. From this, and a previous question you
asked, it seems that you are experiencing problems following from the
accumulating complexity in the code you are writing. Which isn't
surprising as increasing complexity does introduce problems with
managing that complexity, and that is why there are (at lest some of)
those "principles" you mentioned.

The thing is that you can talk about as many "principles" as you like
but if you are not perceiving them as assisting in managing the
complexity you are building all that talk is hollow. Either you don't
understand them fully, are not applying them correctly/appropriately,
or are trying to apply the wrong principles or apply them in the wrong
places or in the wrong way. Any of these are unlikely to be addressed
by more abstract talk of "principles", 'best practices', etc. At some
point it will come down to the code you are writing, and getting
someone with practical experience of complex systems written in
javascript to look at it and say what you are doing wrong (obviously
in their opinion, but that is why you need someone with the experience
to do it). Granted you may not enjoy the experience, but you are
likely to benefit form it.

Richard.
 
R

RobG

I tried to write a general little js-program with appropriate
principles proclaimed here and elsewhere: inheritance,
encapsulation, oop , reuse, short and compact, easy to read
(and write).

If a non-trivial program meets some or most of those requirements, it
will only be easy to write if you are particularly gifted and
knowledgable.
 Hundreds of lines of code, soon thousands. Ugly.
 Too complicated. `Lots of things to improve or redesign.

You likely have too many competing concerns. Define your goals within
parameters that you are reasonably certain you can acheive, then work
to achieve them. As you get better at development, your goals will get
higher.
 
O

optimistx

RobG said:
[...] ....
You likely have too many competing concerns. Define your goals within
parameters that you are reasonably certain you can acheive, then work
to achieve them. As you get better at development, your goals will get
higher.
You may be right.

As an example I mean something like this code of Peter Michaux:
http://peter.michaux.ca/articles/how-i-write-javascript-widgets
but his example is about a logger. Logging is a bit simpler task.
I had written my own logger earlier without seeing Peter's, and
I was pleased and proud to see some similarities in the code :)
(mine did not use any libraries and could be created before the
dom is ready to report things during page load).

I admire Peter Michaux's writings and openmindednes. He
seems to be honest about his mistakes and does not pretend to
something else, and can affort to be kind. Another js-idol for me,
Douglas Cornford, dares to confess his mistakes,
too. More people resembling them , kind and capable of
explaining things pedagocially well?
 
G

Garrett Smith

Richard said:
On Nov 26, 11:06 am, optimistx wrote:
[snip]

Assigning to the result of a function call is not something that you
should expect to get away with in javascript (the language's syntax
allows it, but only host methods are allowed to return something that
can be assigned to).

I am aware of the provision, but unaware of any host methods that return
a Reference. Do you know of any?
 
T

Thomas 'PointedEars' Lahn

kangax said:
Yep. Unfortunately, some of the screen readers (less popular ones,
though) pronounce even display:none content.

It should be obvious why they are less popular then (it's a bug, not a
feature!), and you can safely ignore them.
You can still hide things with comments.

Error-prone.


PointedEars
 
S

Scott Sauyet

David said:
[ ... ] I never tried that, but you could even put some
"template" elements in HTML with "display:none" in CSS, and then clone
them if needed from JS side.
No.  You can't hide "templates" in your markup.  Some users will end
up seeing (or hearing) them.

Yep. Unfortunately, some of the screen readers (less popular ones,
though) pronounce even display:none content. You can still hide things
with comments.

There's a technique I've heard discussed, but never tried myself,
which is to put templates inside script elements with type something
other than "text/javascript". Does anyone have experience with
something like this? Does it interfere with an otherwise clean page
for non-JS users? Does it have the same problem with screen-readers
that the "display:none" technique has?

To be clear, I mean templates marked up something like this:

<script id="template1" type="text/template">
<p>
<span>${firstName}</span>
<span>${lastName}</span>
</p>
</script>

Used with JS something like this:

var person = {firstName: "Scott", lastName: "Sauyet"},
text = fillTemplate("template1", person);


Has anyone here had experience with this technique? Is it worth
doing? What kinds of pitfalls do you see?

-- Scott
 
T

Thomas 'PointedEars' Lahn

Scott said:
There's a technique I've heard discussed, but never tried myself,
which is to put templates inside script elements with type something
other than "text/javascript". Does anyone have experience with
something like this?

Yes, I have had to experience it today ;-)
Does it interfere with an otherwise clean page for non-JS users?

Potentially, yes. But ask yourself instead would trouble it could mean for
JS-enabled users.
Does it have the same problem with screen-readers
that the "display:none" technique has?

Depends on where it is located (`head' or `body') and how conforming the
screen reader is. But it is rather likely that it has other problems, ...
To be clear, I mean templates marked up something like this:

<script id="template1" type="text/template">
<p>
<span>${firstName}</span>
<span>${lastName}</span>
</p>
</script>

.... such as errors.
Used with JS something like this:

var person = {firstName: "Scott", lastName: "Sauyet"},
text = fillTemplate("template1", person);

Has anyone here had experience with this technique?

Hopefully not.
Is it worth doing?

No. Use server-side scripting instead.
What kinds of pitfalls do you see?

1. Syntax errors:

- SCRIPT/script elements do not have an `id' attribute.
Lose this to be compliant, and you have to iterate over
NodeLists to find your template. Sounds like fun ;-)

- `text/template' is not a registered MIME media type.
Not yet, that is. Later registering could invalidate
your template, wreaking havoc with the browsers that
support it. At least use `text/x-markup-template',
but the risk stays the same. You cannot just make up
media types.

- In XHTML you would need at least a CDATA section
for this to be well-formed. And never, ever use
`]]>' in your template then, except at the end,
because it delimits that section and everything
before or after it is parsed as markup.

- If a UA ignores the invalid `type' attribute because
it does not support anything but an ECMAScript
implementation or is not HTML 4.01-compliant, you're doomed.

2. Semantical errors: A template is _not_ a (standalone) program.

3. Compatibility:

- Suppose you have properly declared the content
of the `script' element CDATA (if necessary, not so in HTML),
and the invalid `type' attribute gets ignored, then

<p>
<span>${firstName}</span>
<span>${lastName}</span>
</p>

is a syntactically valid E4X XML expression, supported by
JavaScript 1.6+ (and ActionScript 2.0). However, if it
were not well-formed, that would be a syntax error per E4X.

And if it were not parsed as an XML expression, it would be
a syntax error per ES3/5.

And probably I have forgotten something.


HTH

PointedEars
 
S

Scott Sauyet

Yes, I have had to experience it today ;-)

:)

It definitely sounds as though this is generally a bad idea. Thank
you for your thoughtful and detailed response. Before I go ahead and
pick apart your response, I want to say that I generally agree. I
don't think this technique is a very good idea.

But... :)

Potentially, yes.  But ask yourself instead would trouble it could meanfor
JS-enabled users.

I think that could be reasonably tested for the current crop of
browsers. I don't know if there are specs to prohibit the browser
from trying to execute scripts with such a mime-type, but if there
are, it might be reasonable to think it would continue to work.

Hopefully not.


No.  Use server-side scripting instead.

I would assume that the use for this would be for dynamic templating.
There is clearly a reasonable alternative in AJAX, but this technique
would require less server load, which might be important.

1. Syntax errors:

   - SCRIPT/script elements do not have an `id' attribute.
     Lose this to be compliant, and you have to iterate over
     NodeLists to find your template.  Sounds like fun ;-)

I guess it depends upon your doctype. XHTML does allow it. [1]
   - `text/template' is not a registered MIME media type.
     Not yet, that is.  Later registering could invalidate
     your template, wreaking havoc with the browsers that
     support it.  At least use `text/x-markup-template',
     but the risk stays the same.  You cannot just make up
     media types.

Yes, that is of course a risk. And it's even possible that some super-
strict validator or even UA might test the type against RFC2045.

   - In XHTML you would need at least a CDATA section
     for this to be well-formed.  And never, ever use
     `]]>' in your template then, except at the end,
     because it delimits that section and everything
     before or after it is parsed as markup.

Yes, that is clear. But it certainly is not a show-stopper.

   - If a UA ignores the invalid `type' attribute because
     it does not support anything but an ECMAScript
     implementation or is not HTML 4.01-compliant, you're doomed.

Well, perhaps. The content could be wrapped in comments, which adds
to the forbidden content the "*/" end-comment marker, but doesn't do
more harm that I can see. Just remove a leading /\s*\/\*/ and
trailing /\*\/\s*/ .

2. Semantical errors: A template is _not_ a (standalone) program.

I guess I don't understand what you mean. A single script element
often does not represent a standalone program either. This would be a
hack, and I don't think an elegant one, but I'm not sure I see much of
a semantic difference between the original suggestion and something
like this:

<script type="text/javascript">
function getText(person) {
return "<p>" +
"<span>" + person.firstName + "</span>" +
"<span>" + person.lastName + "</span>" +
"</p>";
}
</script>


   - Suppose you have properly declared the content
     of the `script' element CDATA (if necessary, not so in HTML),
     and the invalid `type' attribute gets ignored, then

       <p>
         <span>${firstName}</span>
         <span>${lastName}</span>
       </p>

     is a syntactically valid E4X XML expression, supported by
     JavaScript 1.6+ (and ActionScript 2.0).  However, if it
     were not well-formed, that would be a syntax error per E4X.

     And if it were not parsed as an XML expression, it would be
     a syntax error per ES3/5.

I never thought about that. Again, comments might take care of it,
but it's an intriguing point.
And probably I have forgotten something.

HTH

It does, thank you. And I want to say again that although I'm not
sure about many individual elements of your critique, taken together,
they make a pretty compelling case against doing this.

Cheers,

-- Scott
____________________
[1] http://www.w3.org/TR/xhtml1/dtds.html#dtdentry_xhtml1-strict.dtd_script
 
T

Thomas 'PointedEars' Lahn

Scott said:
I would assume that the use for this would be for dynamic templating.
There is clearly a reasonable alternative in AJAX, but this technique
would require less server load,

Probably only slightly less, because HTTP/1.1 connections are persistent by
default.
which might be important.

Better to write the template with a JSON-like structure or with a string
value, preferring the former.
1. Syntax errors:

- SCRIPT/script elements do not have an `id' attribute.
Lose this to be compliant, and you have to iterate over
NodeLists to find your template. Sounds like fun ;-)

I guess it depends upon your doctype. XHTML does allow it. [1]

ACK, thanks. Apparently there are more differences between HTML and XHTML
than I was aware of.
- In XHTML you would need at least a CDATA section
for this to be well-formed. And never, ever use
`]]>' in your template then, except at the end,
because it delimits that section and everything
before or after it is parsed as markup.

Yes, that is clear. But it certainly is not a show-stopper.

It is if you consider that MSHTML is, well, MS*HTML*. Since it does not
support application/xhtml+xml which is required to trigger Gecko's and
perhaps other XML parsers, you would need to serve it text/xml or
application/xml, and I am not sure how well the DOM works then. (It would
be worth investigating, though.)

However, you can forget about using `innerHTML' then (at least for Geckos
to date), so instead of applying a DOM parser on the replaced declared
CDATA content of the `script' element to get the node for standards-
compliant insertion, you might as well better forget the whole idea and use
a reasonably compatible JSON-like approach instead in the first place. It
would not even need XHR.
Well, perhaps. The content could be wrapped in comments, which adds
to the forbidden content the "*/" end-comment marker, but doesn't do
more harm that I can see. Just remove a leading /\s*\/\*/ and
trailing /\*\/\s*/ .

That is one thing I forgot: if you use HTML SCRIPT elements with content,
regardless of multi-line script comments in it or not, you need to escape
all ETAGO delimiters in that template, too. Pretty ugly and tedious to
write by comparison, if you ask me.
I guess I don't understand what you mean. A single script element
often does not represent a standalone program either.

Most certainly it always does (see below). However, the inner details of
SCRIPT element processing remain a mystery for at least Closed Source like
NN4, MSHTML, and Opera (I was not inclined to dig through the respective
Gecko code yet, because I presume it is not trivially written; same for
WebKit).

We can only observe the curious outcome: Somehow several SCRIPT elements in
a document can work as if they were one (I remember peculiarities with the
Global Object in MSHTML/JScript), yet an unhandled exception of code in one
SCRIPT element does not appear to affect the execution of the other.
(Which is why detection of missing try-catch support works in NN4.)
This would be a hack, and I don't think an elegant one, but I'm not sure
I see much of a semantic difference between the original suggestion and
something like this:

Yes, you could do this if you wanted to use `innerHTML' or parse it
into a node that you insert later. But you really don't want to.
<script type="text/javascript">
function getText(person) {
return "<p>" +
"<span>" + person.firstName + "</span>" +
"<span>" + person.lastName + "</span>" +
"</p>";
}
</script>

The content of this `script' element is a (standalone) program, just of
itself not a very useful one (it only instantiates a function as property
of the global object), global property namespace spoiling notwithstanding.

This is neither a Valid HTML or XHTML fragment, though. For Valid HTML all
ETAGO delimiters need to be escaped --

<script type="text/javascript">
function getText(person) {
return "<p>" +
"<span>" + person.firstName + "<\/span>" +
"<span>" + person.lastName + "<\/span>" +
"<\/p>";
}
</script>

--, and for Valid XHTML either the `<' need to be escaped --

<script type="text/javascript">
function getText(person) {
return "&lt;p>" +
"&lt;span>" + person.firstName + "&lt;/span>" +
"&lt;span>" + person.lastName + "&lt;/span>" +
"&lt;/p>";
}
</script>

-- or a CDATA section must be used which somewhat takes away the simple
beauty of it. While it could be moved to an external script, to work
around that, is it really worth the extra effort and HTTP request?
Somehow I doubt it.


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top