Script for Hiding/Un-Hiding Text On Click

S

Ste

Hi there,

I've got a website with a list of Frequently Asked Questions, so
there's a question and answer in a long list down the page.

Can anyone recommend a simple script that would allow me to hide each
answer when the page loaded, but then made them individually
appear/disappear when clicking the question?

I'm after a solution that will degrade gracefully if a page doesn't
load, i.e. unlike this example which doesn't seem to show the answers
if JavaScript is disabled (when it should actually show everything if
there's no JavaScript): http://www.virb.com/faq

Thanks for any advice on this,

Ste
 
S

Ste

Right. Don't do it like that. Give the answers a class (eg "answer") and
use JS to write (or append) a style block containing a rule like:

p.answer {display:none}

Also write (or append) the "show answer" interface elements with script so
that users without script enabled won't see them. These are typically links
that call a common handler in their onclick events to display a single
answer. To identify which answer to display, pass its id to the handler.
To display the associated element, use document.getElementById to retrieve
it and set its display style to "block" or "inline."

That's a simple solution. If you don't know how to write it, find a FAQ
page that works without script and look at the code. Most work in a similar
fashion.

Thanks for this. I know HTML/CSS but not JavaScript, so I'll have to
try and find a site that already does this. I across them all the time
but now I want one, I can't find one!

I did find some tutorials for jQuery and mootools, but to be honest, I
couldn't get these to work even after following the tutorials!

Thanks,

Ste
 
D

David Mark

I did find some tutorials for jQuery and mootools, but to be honest, I
couldn't get these to work even after following the tutorials!

You certainly don't need jquery or mootools for this. And if you
don't know JS at all, you should learn a bit before attempting this.
 
S

Ste

You certainly don't need jquery or mootools for this. And if you
don't know JS at all, you should learn a bit before attempting this.

I actually found a script that did what I wanted, except that I had to
enter 'display = 'none' to make it hide all the text by default (as I
don't want answers to appear until the question is clicked, unless
JavaScript is disabled, then everything should appear), but this has
the side effect that it just doesn't degrade nicely when JavaScript is
disabled (so similar to tha virb link).

From the code below, is there a simple piece of code I can add in order
to make it display 'none' if JavaScript is enabled, or not if it's
disabled?

<script type="text/javascript">
<!--
function toggle_visibility(id) {
var e = document.getElementById(id);
if(e.style.display == 'none')
e.style.display = 'block';
else
e.style.display = 'none';
}
//-->
</script>

.........

<a href="#" onclick="toggle_visibility('foo');">Click here to toggle
visibility of element #foo</a><div id="foo">This is foo</div>


Thanks,

Ste
 
J

Jim

Ste, here's a css mouseover solution as well:
------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title> FAQ
</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
<style type="text/css">
div#question {
font-weight:bold;
margin-bottom:5px;
}

div#question a {
display: block;
margin-left:20px;
text-decoration: none;
color:black;
}

/*this rule must be set for it to work*/
div#question a:hover {
background: none;
}

div#question a span {
display: none;
}

div#question a:hover span {
display: inline;
padding: 25px;
width:150px;
}
</style>
</head>
<body >
<h3>Place your mouse/cursor over "Answer" to view the answers</h3>
<ol>
<li><div id="question">
Question: Who's buried in Grant's Tomb?<br/>
<a href="#" >Answer:
<span> &rarr; President Grant</span>
</a>
</div></li>

<li><div id="question">
Question: What color are bananas?<br/>
<a href="#" >Answer:
<span> &rarr; Yellow</span>
</a>
</div></li>

<li><div id="question">
Question: What is 2 + 2?<br/>
<a href="#" >Answer:
<span> &rarr; 4 </span>
</a>
</div></li>
</ol>
</body>
</html>
 
D

David Mark

Ste, here's a css mouseover solution as well:
------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title> FAQ
</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
<style type="text/css">
div#question {
font-weight:bold;
margin-bottom:5px;
}

div#question a {
display: block;
margin-left:20px;
text-decoration: none;
color:black;
}

/*this rule must be set for it to work*/
div#question a:hover {
background: none;
}

I don't see that.
div#question a span {
display: none;
}

div#question a:hover span {
display: inline;
padding: 25px;
width:150px;
}
</style>
</head>
<body >
<h3>Place your mouse/cursor over "Answer" to view the answers</h3>
<ol>
<li><div id="question">
Question: Who's buried in Grant's Tomb?<br/>
<a href="#" >Answer:
<span> &rarr; President Grant</span>
</a>
</div></li>

<li><div id="question">
Question: What color are bananas?<br/>
<a href="#" >Answer:
<span> &rarr; Yellow</span>
</a>
</div></li>

<li><div id="question">
Question: What is 2 + 2?<br/>
<a href="#" >Answer:
<span> &rarr; 4 </span>
</a>
</div></li>
</ol>
</body>
</html>

This solution overlooks keyboard users. These rules work better:

div#question {
font-weight:bold;
margin-bottom:5px;
}

div#question a {
display: block;
margin-left:20px;
text-decoration: none;
color:black;
}

div#question a span {
display: none
}

div#question a:hover span, div#question a:active span, div#question
a:focus span {
display: inline
}

But I contend that displaying the answers in this manner (on rollovers
and focus) is an odd solution.
 
D

David Mark

I actually found a script that did what I wanted, except that I had to
enter 'display = 'none' to make it hide all the text by default (as I
don't want answers to appear until the question is clicked, unless
JavaScript is disabled, then everything should appear), but this has
the side effect that it just doesn't degrade nicely when JavaScript is
disabled (so similar to tha virb link).

From the code below, is there a simple piece of code I can add in order
to make it display 'none' if JavaScript is enabled, or not if it's
disabled?

[snip]

I think I mentioned how to do this before, but I didn't realize you
had no scripting experience. Here is a simple example. Put the
script in an external file and you can reuse it with any page that
contains the same structure (a div with id="questions" that contains
one or more div's with class="question", each containing an anchor for
the question and a div for the answer.)

<html>
<head>
<script type="text/javascript">
if (document.getElementById) document.write('<style type="text/
css">div.question div {display:none} div.question a
{cursor:pointer;text-decoration:underline;color:blue}</style>');
function showAnswer() {
var p = this.parentNode;
if (p) {
var a = p.getElementsByTagName('div');
if (a.length) a[0].style.display = (a[0].style.display ==
'block')?'none':'block'
}
}
function windowLoad() {
var el = document.getElementById('questions');
if (el) {
var links = el.getElementsByTagName('a');
for (var i = links.length - 1; i >= 0; i--)
links.onclick = showAnswer
}
}
window.onload = windowLoad;
</script>
</head>
<body>
<div id="questions">
<div class="question">
<a name="q1">Q. Why am I here?</a>
<div>A. I don't know what to tell you.</div>
</div>
<div class="question">
<a name="q2">Q. Why are you here?</a>
<div>A. Don't you know?</div>
</div>
</div>
</body>
</html>
 
A

ASM

En réponse à Ste qui nous a susurré, en date du : 20/07/07 20:56, le
message sibyllin suivant :
I've got a website with a list of Frequently Asked Questions, so there's
a question and answer in a long list down the page.

Can anyone recommend a simple script

Not so "simple" because of to degrade gracefully
that would allow me to hide each
answer when the page loaded, but then made them individually
appear/disappear when clicking the question?

It could easily be made with css but ...
IE (even IE 7 I think) can't understand speudo class :hover if not in a link
I'm after a solution that will degrade gracefully if a page doesn't
load, i.e. unlike this example which doesn't seem to show the answers if
JavaScript is disabled (when it should actually show everything if
there's no JavaScript): http://www.virb.com/faq

I don't know what they do, but the easiest way could be to :
- set css rules to hide answers
and to show answers when necessary (not understood by IE<7)
- css rules to show answers if it is IE
- set by JS the css rule to hide answer
if the browser can understand the css or JS code to show them
- create JS function to hide/swhow answers if this IE can understand
Thanks for any advice on this,

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<head>
<title>questions and answers</title>
<style type="text/css">
#FAQ { cursor: pointer; _cursor: hand; }
#FAQ dd { color: maroon; background:#eee; }
#FAQ dl:hover dd,
#FAQ dl.ie dd { display: block; }
</style>
<script type="text/javascript">
if(document.getElementById)
document.write('<style type="text/css">#FAQ dd '+
'{display:none;}<\/style>');
// following is for IE (Win and Mac)
var IE = /*@cc_on!@*/false;
if(IE && document.getElementById) {
function hs(what) { // hide/show answer
while(what.tagName.toLowerCase() != 'dl') what = what.parentNode;
what.className = what.className==''? 'ie' : '';
}
window.onload = function() {
var A = document.getElementById('FAQ');
A = A.getElementsByTagName('dt');
for(var i=0; i<A.length; i++) {
A.onmouseover = function(){ hs(this);};
A.onmouseout = function(){ hs(this);};
}
}
}
</script>
</head>
<body>
<div id="FAQ">
<dl>
<dt>Question 1 :</dt>
<dd>Answer 1</dd>
</dl>
<dl>
<dt>Question 2 :</dt>
<dd>Answer 2<br>
and one line more</dd>
</dl>
<dl>
<dt>Question 3 :</dt>
<dd>Answer 3</dd>
</dl>
<dl>
<dt>Question 4 :</dt>
<dd>Answer 4</dd>
</dl>
</div>
</body>
</html>
 
D

David Mark

On Jul 21, 8:18 pm, ASM <[email protected]>
wrote:
[snip]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<head>
<title>questions and answers</title>
<style type="text/css">
#FAQ { cursor: pointer; _cursor: hand; }

Why not:

cursor:pointer;cursor:hand

Standards-based browsers will just throw out the second one. And you
should put the "hand" rule in an IE conditional comment.
#FAQ dd { color: maroon; background:#eee; }
#FAQ dl:hover dd,
#FAQ dl.ie dd { display: block; }
</style>
<script type="text/javascript">
if(document.getElementById)
document.write('<style type="text/css">#FAQ dd '+
'{display:none;}<\/style>');
// following is for IE (Win and Mac)
var IE = /*@cc_on!@*/false;
if(IE && document.getElementById) {
function hs(what) { // hide/show answer
while(what.tagName.toLowerCase() != 'dl') what = what.parentNode;
what.className = what.className==''? 'ie' : '';
}
window.onload = function() {
var A = document.getElementById('FAQ');
A = A.getElementsByTagName('dt');
for(var i=0; i<A.length; i++) {
A.onmouseover = function(){ hs(this);};
A.onmouseout = function(){ hs(this);};
}
}
}
</script>
</head>
<body>
<div id="FAQ">
<dl>
<dt>Question 1 :</dt>
<dd>Answer 1</dd>
</dl>
<dl>
<dt>Question 2 :</dt>
<dd>Answer 2<br>
and one line more</dd>
</dl>
<dl>
<dt>Question 3 :</dt>
<dd>Answer 3</dd>
</dl>
<dl>
<dt>Question 4 :</dt>
<dd>Answer 4</dd>
</dl>
</div>
</body>
</html>


I don't follow the semantics. They are slightly improved from the
empty semantics in my original example, but it seems like a FAQ would
be a single definition list.

And then there is the keyboard access issue. I think this is a
preferable solution:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/
TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>FAQ</title>
<script type="text/javascript">
if (document.getElementById) document.write('<style type="text/
css">#questions dd {display:none}<\/style>');
function showAnswer() {
var id = this.id;
var el = document.getElementById('a' + id.substring(1));
if (el) el.style.display = (el.style.display ==
'block')?'none':'block';
return false
}
function windowLoad() {
var el = document.getElementById('questions');
if (el) {
var links = el.getElementsByTagName('a');
for (var i = links.length - 1; i >= 0; i--) {
links.onclick = showAnswer;
links.href = '#';
links.tabIndex = 0
}
}
}
window.onload = windowLoad
</script>
</head>
<body>
<dl id="questions">
<dt><a id="q1">Q. Why am I here?</a></dt>
<dd id="a1">A. I don't know what to tell you.</dd>
<dt><a id="q2">Q. Why are you here?</a></dt>
<dd id="a2">A. Don't you know?</dd>
</dl>
</body>
</html>
 
D

David Mark

David Mark said the following on 7/22/2007 6:20 PM:
On Jul 21, 8:18 pm, ASM <[email protected]>
wrote:
[snip]
#FAQ { cursor: pointer; _cursor: hand; }
Why not:

Standards-based browsers will just throw out the second one. And you
should put the "hand" rule in an IE conditional comment.

And why is that? There may be a browser other than IE that doesn't
support cursor: pointer but that supports cursor:hand and by putting
them in an IE conditional you just ruled out a potential browser for no
reason at all. The "Standards-based browsers" will simply ignore it and
no harm is done.

Except your CSS is invalid!
Two ongoing threads where you are defending the use of XHTML on the web
and you post an HTML4 example. WOW!

Did you really want me to post an XML version? To do so would require
including the XML prolog as the character set meta tag would obviously
be omitted. It wouldn't be of much use as a static example.
That is a preposterously inept test. I would think that a test for the

Not true. If document.getElementById is not supported then you don't
want to write this style. See below.
ability to change the styles *might* be a better test. But, simply
testing for getElementById doesn't even come close to what you need to
test for to know whether to write the style tag or not. It also doesn't
cover the aspect of CSS disabled browsers.

Tested in Mozilla with no style, no script and both together.
Everything is fine. The only nit-pick you could make is that when
style is disabled and scripting is enabled (an odd case to be sure),
the anchors look like links. The logical solution to that is simple
and can be found at the end of the post.

Here you are correct. The onload listener should not be attached
without testing for document.getElementById. This is in symmetry with
the document.write line. I can now see why you misunderstood the
intention of testing document.getElementById before writing the style
rule.
No test here to see if the browser supports gEBI or not?


What makes you sure the browser supports getElementsByTagName?

What browser supports getElementById, but not getElementsByTagName?
If you can come up with one, then there should be two feature tests
before writing the style and attaching the onload handler.
<snip>

So no, your code doesn't come close to being a "preferable" solution. It

Preferable is relative.
may be better than what was posted.....

See the previous sentence. And by "may be", I assume you did compare
it to the previous post. So what exactly are you saying? Other than
the point about detecting getElementById, what would you suggest to
improve it?

I didn't claim the previous post was perfection. But tell me this
isn't:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/
TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>FAQ</title>
<script type="text/javascript">
if (document.getElementById) document.write('<style type="text/
css">#questions dd {display:none}<\/style>');
function showAnswer() {
var id = this.id;
var el = document.getElementById('a' + id.substring(1));
if (el) el.style.display = (el.style.display ==
'block')?'none':'block'
}
function windowLoad() {
var el = document.getElementById('questions');
if (el) {
var links = el.getElementsByTagName('a');
for (var i = links.length - 1; i >= 0; i--) {
links.onclick = showAnswer;
links.href = '#a' + (i + 1);
links.tabIndex = 0
}
}
}
if (document.getElementById) window.onload = windowLoad
</script>
</head>
<body>
<dl id="questions">
<dt><a id="q1">Q. Why am I here?</a></dt>
<dd id="a1">A. I don't know what to tell you.</dd>
<dt><a id="q2">Q. Why are you here?</a></dt>
<dd id="a2">A. Don't you know?</dd>
</dl>
</body>
</html>
 
A

ASM

En réponse à David Mark qui nous a susurré, en date du : 23/07/07 0:20,
le message sibyllin suivant :
On Jul 21, 8:18 pm, ASM <[email protected]>
wrote:
[snip]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<head>
<title>questions and answers</title>
<style type="text/css">
#FAQ { cursor: pointer; _cursor: hand; }

Why not:

cursor:pointer;cursor:hand

yes, why not.
(I don't remember if my IE(Mac) can read '_cursor'
nor if he understands 'hand')
Standards-based browsers will just throw out the second one. And you
should put the "hand" rule in an IE conditional comment.

certainly, but I built this example several times with/without IE
conditionnal comments and ... see above about IE(Mac)
(I'm almost sure IE(Mac) doesn't read '_cursor' but understands 'pointer')
#FAQ dd { color: maroon; background:#eee; }
#FAQ dl:hover dd,
#FAQ dl.ie dd { display: block; }
</style>
<script type="text/javascript">
if(document.getElementById)
document.write('<style type="text/css">#FAQ dd '+
'{display:none;}<\/style>');
// following is for IE (Win and Mac)
var IE = /*@cc_on!@*/false;
if(IE && document.getElementById) {
function hs(what) { // hide/show answer
while(what.tagName.toLowerCase() != 'dl') what = what.parentNode;
what.className = what.className==''? 'ie' : '';
}
window.onload = function() {
var A = document.getElementById('FAQ');
A = A.getElementsByTagName('dt');
for(var i=0; i<A.length; i++) {
A.onmouseover = function(){ hs(this);};
A.onmouseout = function(){ hs(this);};
}
}
}
</script>
</head>
<body>
<div id="FAQ">
<dl>
<dt>Question 1 :</dt>
<dd>Answer 1</dd>
</dl>
<dl>
<dt>Question 2 :</dt>
<dd>Answer 2<br>
and one line more</dd>
</dl>
<dl>
<dt>Question 3 :</dt>
<dd>Answer 3</dd>
</dl>
<dl>
<dt>Question 4 :</dt>
<dd>Answer 4</dd>
</dl>
</div>
</body>
</html>


I don't follow the semantics. They are slightly improved from the
empty semantics in my original example, but it seems like a FAQ would
be a single definition list.

And then there is the keyboard access issue.


As never I was abble to do something with keyboard access with my
Firefox on my Mac ... I squeeze this aspect.
I think this is a preferable solution:

Except all browsers will have to run this JS as all of them except IE
could easier do the job with CSS.

Except you need a lot of ids, growing possibilities of mistakes (or errors)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/
TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>FAQ</title>
<script type="text/javascript">
if (document.getElementById) document.write('<style type="text/
css">#questions dd {display:none}<\/style>');
function showAnswer() {
var id = this.id;
var el = document.getElementById('a' + id.substring(1));
if (el) el.style.display = (el.style.display ==
'block')?'none':'block';
return false
}
function windowLoad() {
var el = document.getElementById('questions');
if (el) {
var links = el.getElementsByTagName('a');

Why won't you assign that to DTs ?
and suppress all your anchors changed to links
and give the IDs now in the loop to the DTs and DDs
for (var i = links.length - 1; i >= 0; i--) {
links.onclick = showAnswer;
links.href = '#';
links.tabIndex = 0


not understood ...
(tabindex to 0 for everybody ?)

function windowLoad() {
var el = document.getElementById('questions');
if (el) {
var links = el.getElementsByTagName('DT');
var targs = el.getElementsByTagName('DD');
for (var i = 0; i<links.length; i++) {
links.id = 'l'+i;
targs.id = 'a'+i;
links.onclick = showAnswer;
links.tabIndex = i;
}
}
}
window.onload = windowLoad
</script>
</head>
<body>
<dl id="questions">
<dt>Q. Why am I here?</dt>
<dd>A. I don't know what to tell you.</dd>
<dt>Q. Why are you here?</dt>
<dd>A. Don't you know?</dd>
</dl>
</body>
</html>
 
D

David Mark

En r?ponse ? David Mark qui nous a susurr?, en date du : 23/07/07 0:20,
le message sibyllin suivant :
On Jul 21, 8:18 pm, ASM <[email protected]>
wrote:
[snip]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<head>
<title>questions and answers</title>
<style type="text/css">
#FAQ { cursor: pointer; _cursor: hand; }
cursor:pointer;cursor:hand

yes, why not.
(I don't remember if my IE(Mac) can read '_cursor'
nor if he understands 'hand')

If IE for the Mac does not understand "hand", then it should ignore it
and use "pointer."
certainly, but I built this example several times with/without IE
conditionnal comments and ... see above about IE(Mac)
(I'm almost sure IE(Mac) doesn't read '_cursor' but understands 'pointer')

IE Mac will ignore the contents of the conditional comment, as will
the validators.
#FAQ dd { color: maroon; background:#eee; }
#FAQ dl:hover dd,
#FAQ dl.ie dd { display: block; }
</style>
<script type="text/javascript">
if(document.getElementById)
document.write('<style type="text/css">#FAQ dd '+
'{display:none;}<\/style>');
// following is for IE (Win and Mac)
var IE = /*@cc_on!@*/false;
if(IE && document.getElementById) {
function hs(what) { // hide/show answer
while(what.tagName.toLowerCase() != 'dl') what = what.parentNode;
what.className = what.className==''? 'ie' : '';
}
window.onload = function() {
var A = document.getElementById('FAQ');
A = A.getElementsByTagName('dt');
for(var i=0; i<A.length; i++) {
A.onmouseover = function(){ hs(this);};
A.onmouseout = function(){ hs(this);};
}
}
}
</script>
</head>
<body>
<div id="FAQ">
<dl>
<dt>Question 1 :</dt>
<dd>Answer 1</dd>
</dl>
<dl>
<dt>Question 2 :</dt>
<dd>Answer 2<br>
and one line more</dd>
</dl>
<dl>
<dt>Question 3 :</dt>
<dd>Answer 3</dd>
</dl>
<dl>
<dt>Question 4 :</dt>
<dd>Answer 4</dd>
</dl>
</div>
</body>
</html>

I don't follow the semantics. They are slightly improved from the
empty semantics in my original example, but it seems like a FAQ would
be a single definition list.
And then there is the keyboard access issue.

As never I was abble to do something with keyboard access with my
Firefox on my Mac ... I squeeze this aspect.


I don't understand you there. Firefox for the Mac doesn't tab through
links?
Except all browsers will have to run this JS as all of them except IE
could easier do the job with CSS.

Without JS it degrades to show the answers without user interaction.
Except you need a lot of ids, growing possibilities of mistakes (or errors)

If it is to be semantic (eg not nested div's like my first example or
multiple lists as in yours), the id's are necessary. I would think a
FAQ would normally be created with CGI, which would eliminate the
possibility or human error in assigning the id's.
Why won't you assign that to DTs ?
and suppress all your anchors changed to links
and give the IDs now in the loop to the DTs and DDs

If I understand you correctly, you would prefer to assign a tabIndex
to the dt elements and style them to look like links. That could work
too, but I would worry that older browsers and devices might not
support tabstops for dt elements.
for (var i = links.length - 1; i >= 0; i--) {
links.onclick = showAnswer;
links.href = '#';
links.tabIndex = 0


not understood ...
(tabindex to 0 for everybody ?)


This makes the tab order the same as the source order. It is odd that
it would be required to assign a tabIndex, but at least one browser I
tested (Opera I think) refused to tab through the newly created links
without this step. BTW, I posted a follow-up that assigns meaningful
href's instead of "#" and it is useful to note that you could add
these attributes to the tags themselves (rather than with script.) I
suspect that Opera would no longer require the tabIndex assignment in
that case, but on the other hand, the anchors would always be (fairly
useless) links, even with scripting disabled (I prefer them to remain
anchors in that case.)
 
A

ASM

En réponse à Randy Webb qui nous a susurré, en date du : 23/07/07 0:37,
le message sibyllin suivant :
David Mark said the following on 7/22/2007 6:20 PM:
On Jul 21, 8:18 pm, ASM <[email protected]>
wrote: [snip]
<script type="text/javascript">
if (document.getElementById) document.write('<style type="text/
css">#questions dd {display:none}<\/style>');

That is a preposterously inept test.

Thanks a lot ! I think it is almost my own code ...
I would think that a test for the
ability to change the styles *might* be a better test.

Development ?
It also doesn't cover the aspect of CSS disabled browsers.

?? if CSS are disabled, what is the importance ?
My NC4.5 ignores these CSS (and this JS gBEI) and all seems OK.
FF css disabled : all OK
No test here to see if the browser supports gEBI or not?

I think, here it is not important as these browsers are supposed to
display all the body.
Usually if a browser doesn't support gEBI it ignores this one.
What makes you sure the browser supports getElementsByTagName?

if(el) no ?
Are there browsers that support gBEI and not getElementsByTagName ?
<snip>

So no, your code doesn't come close to being a "preferable" solution. It
may be better than what was posted.....

Is it or not ?
and why ?
(I've passed my code to the validator : all OK)
 
R

Richard Cornford

David said:
Except your CSS is invalid!

That is very questionable. The CSS specs mandate the handling of
unrecognised property names and values (they are to be ignored in all
cases, which IE fails to do) and so the question arises as to why it is
necessary to mandate the handling of unrecognised properties and values
if a notion of validity is attached that precludes their appearing in
the first place.

Not true. If document.getElementById is not supported then you don't
want to write this style. See below.
<snip>

You also don't want to write the script element whenever the browser
supports - getElementById - but does not support (or react to) the
dynamic assignment of display property values on its element's style
objects. A characteristic that was common in the days of Opera 6 but is
now relegated to the less-capable end of the embedded browser market.

Richard.
 
D

David Mark

That is very questionable. The CSS specs mandate the handling of
unrecognised property names and values (they are to be ignored in all
cases, which IE fails to do) and so the question arises as to why it is
necessary to mandate the handling of unrecognised properties and values
if a notion of validity is attached that precludes their appearing in
the first place.

According to the w3c validator and the error consoles of various
browsers, it is invalid. Maybe they will change the rules in the
future.
<snip>

You also don't want to write the script element whenever the browser

I assume you mean "style element."
supports - getElementById - but does not support (or react to) the
dynamic assignment of display property values on its element's style
objects. A characteristic that was common in the days of Opera 6 but is
now relegated to the less-capable end of the embedded browser market.

I think we can forget about Opera 6 at this point, but what other
browsers (embedded or otherwise) display this behavior? It doesn't
sound like anything that can be feature-detected and virtually any Web
application will break under the described circumstances. Is it just
the display property or do all attempts to manipulate style with
script fail?
 
A

ASM

En réponse à Randy Webb qui nous a susurré, en date du : 23/07/07 6:59,
le message sibyllin suivant :
David Mark said the following on 7/22/2007 9:37 PM:
(...)
I expect were are here :

<script type="text/javascript">
if(document.getElementById)
document.write('<style type="text/css">#FAQ dd '+
'{display:none;} said:
But, at least testing for the properties you want is better
than not testing at all, isn't it?

if (elemRef && elemRef.style && elemRef.style.visibility)

Would surely have to be better than not testing for it at all. You can
substitute display for visibility as the situation dictates.

What I would like to know is :
how do you explain to different browsers what is 'elemRef' ?
 
A

ASM

En réponse à David Mark qui nous a susurré, en date du : 23/07/07 2:13,
le message sibyllin suivant :
If IE for the Mac does not understand "hand", then it should ignore it
and use "pointer."

I like so much speaking of IE "it should" :)
Between what it should and what it does there is a world.
IE Mac will ignore the contents of the conditional comment, as will
the validators.
Good.


I don't understand you there. Firefox for the Mac doesn't tab through
links?

There are so much system's shortcuts and Fx shortcuts ...
that I can't see (or remenber) which touch or associations of touches I
have to type to go directly to a tab-indexed element.
(probably I marmalade with 'acceskey' ?)
Without JS it degrades to show the answers without user interaction.

so it does with CSS
If it is to be semantic (eg not nested div's like my first example or
multiple lists as in yours), the id's are necessary. I would think a
FAQ would normally be created with CGI, which would eliminate the
possibility or human error in assigning the id's.

OK in this point of view.

[links]
If I understand you correctly, you would prefer to assign a tabIndex
to the dt elements and style them to look like links. That could work
too, but I would worry that older browsers and devices might not
support tabstops for dt elements.

I prefer clear, small and direct html without apparent complications :)

I don't know what this or that browser (which understands given css and
js) will do with these tab-index.
I'm not sure whatever is the browser it'll can do something with
tab-index in a DT (about tab-index, is this tag referenced in specs?)
for (var i = links.length - 1; i >= 0; i--) {
links.onclick = showAnswer;
links.href = '#';
links.tabIndex = 0

not understood ...
(tabindex to 0 for everybody ?)


This makes the tab order the same as the source order.


Ha ! OK.
(but were are following source order in this loop, no ?)
(Opera I think) refused to tab through the newly created links
without this step.

Rhaaaa la la ! this Opera !
Haven't we enough jokes with IE ?
 
D

David Mark

David Mark said the following on 7/22/2007 7:36 PM:




David Mark said the following on 7/22/2007 6:20 PM:
On Jul 21, 8:18 pm, ASM <[email protected]>
wrote:
[snip]
<snip>
#FAQ { cursor: pointer; _cursor: hand; }
Why not:
cursor:pointer;cursor:hand
Standards-based browsers will just throw out the second one. And you
should put the "hand" rule in an IE conditional comment.
And why is that? There may be a browser other than IE that doesn't
support cursor: pointer but that supports cursor:hand and by putting
them in an IE conditional you just ruled out a potential browser for no
reason at all. The "Standards-based browsers" will simply ignore it and
no harm is done.
Except your CSS is invalid!

You might be intrigued to search the archives and find out what my
opinion of validation - whether it be X/HTML, CSS or anything else. Give
me what *works*, not what "validates". The "validator" says the type
attribute is required on a script element, yet the only type attribute
for it is deprecated. So much for "validation".

Type of "text/javascript" validates and works, but is deprecated.
What's the problem?
You missed the point, but I expected no more.

Posting a static XML version of an entire page would be pointless.
What I posted was appropriate and has nothing to do with the XHTML vs.
HTML threads.
Again, you missed the point. You don't want that CSS written if:
a) You can't get a reference to the element (getElementById)
Yep.

b) You can't change the style property of that element.

There's no reliable way to know that. So nobody tests for that. Name
one browser that supports getElementById, but cannot change style
properties.
Not even the supposition that gEBI is present and that the style
property is present will assure you that you can change it.

Again, name one agent. Just one. Alternatively, post a code example
that tests for this occasion.
So you agree with me that your "example" wasn't as good as you thought
it was?

How good do you think I thought it was? I said it was a preferable
example to the mouse-only version posted before it. The second
getElementById test was obviously left out by mistake. So it wasn't
perfect. Why you couldn't see the simple solution and suggested a
bunch of nonsense about testing styles in lieu of making the feature
detection symmetric is beyond me.
It had nothing to do with the onload listener. It has to do with your
assumption that if the UA supports getElementById then you can change
the styles dynamically and that is a false assumption.

I am making no such assumption. There simply is no test for whether
styles can be changed dynamically. If you had to test for that, you
couldn't write anything that hides and shows elements.
And you think that is a better position than testing for it and not
caring if a browser doesn't support it? One way the browser silently
degrades, the other way it doesn't - it throws an error. Which is more
user friendly?

There just aren't any agents out there that support one and not the
other. But it isn't hard to add a test for getElementsByClassName if
you are worried about that. I'll leave that as an exercise.
OK, it isn't. Make you feel better? Whether I think it is or not, I
simply said it because you wanted me to. But no, it isn't. Not even
close because you still haven't realized the problem with this testing:

There you go again. That test makes no sense on its own. But paired
with the identical test a few lines down, it makes perfect sense.
The simple fact that a browser supports gEBI means *nothing* when it
comes to dynamically altering the CSS properties of an element and that
is the *only* reason for wanting that CSS there to start with. It is
referred to as "feature detection" and falls into a category known as
"defensive programming".

Again. I am through explaining the symmetry of the testing in this
example. You clearly don't get it.
Again, you are - incorrectly - assuming that because the browser
supports gEBI that it must support getElementsByTagName and that is -
once again - a faulty assumption. And bear in mind that until recently
(in the last year or so) there was a *very* *regular* poster in this
group that used IE4 exclusively. And emulating gEBI on IE4 is trivial.

Now what are you talking about? If a developer creates their own gEBI
that calls document.all and pastes this example into their page and
runs it in IE4, then they will need to add the addition test for
getElementsByClassName. Like I said, I will leave that addition as an
exercise for those in this less-than-regular situation.
That test - once again - is fatally flawed. Reread the post to figure
out why.

I don't have to re-read anything. You just keep repeating the same
thing as if I don't understand and that is a silly thing to do.
No, this isn't my first rodeo.

Odd that at the end of the day, you haven't posted a single line of
code. Where's the "if styles can be changed" feature test? It
obviously is just a theoretical waste of time.
 
D

David Mark

David Mark said the following on 7/22/2007 9:37 PM:



I doubt that you would ever come up with a completely fool proof test
for whether you could successfully manipulate the style property of an

There you go. So all of that repetition advocating such a thing was a
waste of time.
element. But, at least testing for the properties you want is better
than not testing at all, isn't it?

Not really. See below.
if (elemRef && elemRef.style && elemRef.style.visibility)

And some code too! Now we are getting somewhere. Wrong property for
this example though.

That doesn't mean you can change it. In fact, it could be argued that
if the style property is absent, then the agent likely doesn't support
CSS at all and therefore the first example degrades gracefully, and
the revision degrades perfectly.
 
D

David Mark

David Mark said the following on 7/23/2007 2:08 PM:




David Mark said the following on 7/22/2007 7:36 PM:
David Mark said the following on 7/22/2007 6:20 PM:
On Jul 21, 8:18 pm, ASM <[email protected]>
wrote:
[snip]
<snip>
#FAQ { cursor: pointer; _cursor: hand; }
Why not:
cursor:pointer;cursor:hand
Standards-based browsers will just throw out the second one. And you
should put the "hand" rule in an IE conditional comment.
And why is that? There may be a browser other than IE that doesn't
support cursor: pointer but that supports cursor:hand and by putting
them in an IE conditional you just ruled out a potential browser for no
reason at all. The "Standards-based browsers" will simply ignore it and
no harm is done.
Except your CSS is invalid!
You might be intrigued to search the archives and find out what my
opinion of validation - whether it be X/HTML, CSS or anything else. Give
me what *works*, not what "validates". The "validator" says the type
attribute is required on a script element, yet the only type attribute
for it is deprecated. So much for "validation".
Type of "text/javascript" validates and works, but is deprecated.
What's the problem?

You don't find anything ironically amusing about the W3C telling you to
use a feature that it deprecated? I do.

What difference does it make if you find it amusing?
Sure there is. See my code at the bottom.



You are thinking backwards. Your attitude is "Until someone names one, I
don't have to worry about it". Mine is, if I code against that
possibility, I don't have to worry about it. One is a flawed attitude to
have.

No, I don't think you have a clue what my attitude is. I simply left
the further improvement of the example as an exercise. Do whatever
you want with it.
I can't? Hmmm. I think I can. See below.



I hope your "libraries" aren't riddled with that thought process. If
they are, then it is a good thing we haven't seen any of them.

What "libraries?" I think I mentioned one specific library in another
thread. Is that what you are talking about? If so, your hopes about
it are not of any concern as you don't use XHTML. I don't see how it
is either good or bad that you (and the mouse in your pocket) haven't
seen it.
No, the test is moronic whether it is duplicated or not. The style

Either you don't get it or you are trying to turn this discussion into
a personal attack. I don't really care either way as I am about ready
to stop reading your posts entirely.
element isn't even needed in the page at all for a modern browser. Even

What in God's name are you babbling about now? The style element
isn't needed for a modern browser? What does that mean?
if it is (I think IE6 didn't like manipulating styles that weren't
defined)

You think wrong.
it would be hard coded as display: block. See below.

Hard coded? display: block? That's the default!
I think that anyone that has coded JS for any amount of time can figure
out who "Gets it" and who doesn't.

Yes. I am sure the lurkers are with you.
It is? You get brownie points if you can correctly answer the last
question in this code:

You seem to be confused. Lets see how you did on your assignment to
improve my code. By the way, it took you long enough to complete.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>FAQ</title>
<script type="text/javascript">

function showAnswer() {
var id = this.id;
var el = document.getElementById('a' + id.substring(1));
if (el) el.style.display = (el.style.display == 'block')?'none':'block';
return false}

function windowLoad() {
var el = document.getElementById('questions')
if (el &&
el.getElementsByTagName &&
el.getElementsByTagName('a') &&
el.getElementsByTagName('dd') )
{
var links = el.getElementsByTagName('a');
var answers = el.getElementsByTagName('dd')
for (var i = links.length - 1; i >= 0; i--)
{
links.onclick = showAnswer;
links.href = '#';


If you are going to copy my code, at least copy the last version
posted.
links.tabIndex = 0;
if (answers.style)
{
answers.style.display = "none";


This is hardly an improvement. What you've done is make the answers
flash for a second during the page load. Furthermore, you now have
links that don't do anything if this assignment does not update the
screen (in whatever fantasy user agent you are "defending" against.)
}
}
}}

window.onload = windowLoad

Wrong. See below.
</script>
</head>
<body>
<dl id="questions">
<dt><a id="q1">Q. Why isn't there a style element in the source code of
this page?</a></dt>
<dd id="a1">A. It isn't needed as the styles are only set if the browser
can set it.</dd>
<dt><a id="q2">Q. What happens if the browser can't set them?</a></dt>
<dd id="a2">A. Then the answers stay visible for fallback.</dd>
<dt><a id="q3">Q. Why won't the space far activate the links?</a></dt>
<dd id="a3">A. That is a damn good question.</dd>

No it isn't. What makes you think the space bar activates links? Try
the enter key.
<dt><a id="q4">Q. Why is this solution better?</a></dt>
<dd id="a4">A. It degrades better than the previous version.</dd>

Degrades better for browsers that don't exist, but is far uglier for
many browsers that do exist. I don't like it.
<dt><a id="q5">Q. Why is there no test for gEBI on the window.onload
call?</a></dt>
<dd id="a5">A. Because whether gEBI is present or not is irrelevant
there.</dd>

You didn't test for it anywhere, which is obviously incorrect. The
very first line of windowLoad attempts to use the getElementById
method. (!)
<dt><a id="q6">Q. What happens if there is no display property of the
style elemnt?</a></dt>

I assume you meant "display property of the style object."
<dd id="a6">A. Then it assigns it a new property and leaves the answers
visible. Change it to "chicken" to see it fall through gracefully.</dd>
<dt><a id="q7">Q. Are there any other flaws in this code?</a></dt>

Yes. And apparently in your personality too.
<dd id="a7">A. Yes. Can you, as a "programmer" tell me what they are?</dd>

Can you as a "jackass" try to understand that this thread is not a
contest? Your series of posts here seem to exist only to impress me.
I'm not impressed with the noisy buildup and the "payoff" turned out
to be a flawed fizzle. What a waste of time.
 

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

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top