Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 14 of 14
  1. #1
    New Coder
    Join Date
    Feb 2007
    Posts
    15
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Unhappy style inside noscript

    Hey everyone, I'm at a classic impasse and I need your help

    I am creating a fun little mouseover event for my scouting website, but I want it to be valid and usable (strange, huh?). When a user hovers over a question, the answer will appear. But if the user isn't using javascript, I want the answers to default appear. I am having trouble, because when a page is valid, it doesn't work, and when it works, it isn't valid.

    1. This works, but isn't valid:
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html>
     <head>
      <title>noscript, bah!</title>
      <style type='text/css'>#answer { display:none; }</style>
      <script type='text/javascript' language='javascript'>
       function show() {document.getElementById("answer").style.display="block";}
       function hide() {document.getElementById("answer").style.display="none";}
      </script>
      <noscript>
       <style type='text/css'>#answer { display:block; }</style>
      </noscript>
     </head>
     <body>
      <div id='question' onmouseover='javascript:show()' onmouseout='javascript:hide()'>
       What is the scout motto?
      </div>
      <div id='answer'>Be prepared.</div>
     </body>
    </html>
    The noscript tag isn't supposed to go inside the head tag. The noscript tag is supposed to go inside the body tag. Okay, fine, let's put it there.


    2. This works, but isn't valid:
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html>
     <head>
      <title>noscript, bah!</title>
      <style type='text/css'>#answer { display:none; }</style>
      <script type='text/javascript' language='javascript'>
       function show() {document.getElementById("answer").style.display="block";}
       function hide() {document.getElementById("answer").style.display="none";}
      </script>
     </head>
     <body>
      <noscript>
       <style type='text/css'>#answer { display:block; }</style>
      </noscript>
        <div id='question' onmouseover='javascript:show()' onmouseout='javascript:hide()'>
       What is the scout motto?
      </div>
      <div id='answer'>Be prepared.</div>
     </body>
    </html>
    Now, the noscript tag is inside the body as it should be. But the style tag shouldn't be in the body. Rats! So, I guess I can't put the style tag inside the noscript tag. Let's try a workaround.


    3. This validates, but doesn't work very well:
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html>
     <head>
      <title>noscript, bah!</title>
      <style type='text/css'>#answer { display:block; }</style>
      <script type='text/javascript' language='javascript'>
       function show() {document.getElementById("answer").style.display="block";}
       function hide() {document.getElementById("answer").style.display="none";}
      </script>
     </head>
     <body onload='javascript:hide()'>
        <div id='question' onmouseover='javascript:show()' onmouseout='javascript:hide()'>
       What is the scout motto?
      </div>
      <div id='answer'>Be prepared.</div>
     </body>
    </html>
    The reason this doesn't work very well is because this technique is going onto a fairly large page with a lot of these questions. So when the page is loading, all of the answers are visible. Then, suddenly, they disappear. This really annoys me and (I bet) the user, too.

    So, any ideas? I found this thread, but it basically uses the ideas from Example 3. It would be really nice if we could have a:hover action affect another element in css (without javascript, of course). It would also be nice if we could use the style tag inside the noscript tag. Anyway, thanks a bunch guys! Let me know if you can come up with anything.

  • #2
    Senior Coder koyama's Avatar
    Join Date
    Dec 2006
    Location
    Copenhagen, Denmark
    Posts
    1,246
    Thanks
    1
    Thanked 5 Times in 5 Posts
    This is a classic problem. Maybe this article by Peter-Paul Koch will interest you. Read the section “The single correct use of document.write”.

    Basically, the solutions is to use this in the head section:
    Code:
    <script type="text/javascript">
    document.write('<link rel="stylesheet" href="advanced.css" />');
    </script>

  • #3
    Senior Coder
    Join Date
    Feb 2003
    Posts
    1,665
    Thanks
    0
    Thanked 27 Times in 25 Posts
    I'd be inclined to opt for a DOM-based approach, as some mention in the comments in that article.
    Given that the article was written in 2005, I suspect that PPK would also favour the DOM over document.write for a page authored these days.

    e.g.

    site.js
    Code:
    window.onload = prep;
    
    function prep() {
    
    	var q = document.getElementById('question');
    	q.onmouseover = toggleAnswer;
    	q.onmouseout = toggleAnswer;
    	
    
    }
    
    function toggleAnswer() {
    
    	var a = document.getElementById('answer');
    	a.className = (a.className == '') ? 'hide' : '';
    
    }
    
    var headEl = document.getElementsByTagName('head')[0];
    var newCSS = document.createElement('link');
    newCSS.rel = 'stylesheet';
    newCSS.type = 'text/css';
    newCSS.href = 'hasjs.css';
    headEl.appendChild(newCSS);
    hasjs.css
    Code:
    .hide {
    	display: none;
    }
    markup
    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="en-GB">
    <head>
    	<meta http-equiv="content-type" content="text/html; charset=utf-8">
    	<title>noscript, bah!</title>
    	<script type="text/javascript" src="site.js"></script>
    </head>
    <body>
    
    <div id="question">
    	What is the scout motto? 
    </div>
    
    <div id="answer" class="hide">
    	Be prepared.
    </div>
    
    </body>
    </html>
    If I were being a bit more picky, I'd suggest that two divs may not be the best way to markup the question and answer.

  • #4
    Senior Coder koyama's Avatar
    Join Date
    Dec 2006
    Location
    Copenhagen, Denmark
    Posts
    1,246
    Thanks
    1
    Thanked 5 Times in 5 Posts
    Quote Originally Posted by Bill Posters View Post
    I'd be inclined to opt for a DOM-based approach, as some mention in the comments in that article.
    Given that the article was written in 2005, I suspect that PPK would also favour the DOM over document.write for a page authored these days.
    Interesting... PPK has devoted a section in his book “ppk on JavaScript” (september 2006) for this issue. He defends his statement from the article that I linked to in section 9C in his book:

    Quote from “ppk on JavaScript” (buy book here)
    Alternative: Adding a <Link /> Tag
    You can also use the W3C DOM to create an extra element that holds the special styles. For instance, you could create a new <link /> tag, give it the correct href, and add it to the document. Since it avoids the use of a document.write, some people prefer this method.

    However, it has its drawbacks, too. It's impossible to add a <link /> tag to the document when it hasn't yet been loaded completely; the <head> element, to which you must append the <link />, is not yet available. Therefore, you must either wait until after the load event, which may cause elements to flicker, or add an extra hard-coded <link /> tag and give it its proper href when JavaScript turns out to be supported.

    I leave it to others to decide on the semantic value of empty <link /> tags, but personally I don't like these potentially useless elements. I prefer the document.write method. Feel free to use <link /> tags, though, if you like them better.
    Now I'm confused because here he is saying that the head element isn't available for scripting puposes until after page load. But then your example code shouldn't be working, but it does seem to work?

  • #5
    New Coder
    Join Date
    Feb 2007
    Posts
    15
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Bill Posters View Post
    I'd be inclined to opt for a DOM-based approach, as some mention in the comments in that article.
    Given that the article was written in 2005, I suspect that PPK would also favour the DOM over document.write for a page authored these days.
    I don't think I understand this method. Wouldn't it create the same effect as Example 3? The script wouldn't load until the page loads, so the answers will appear, then disappear. Correct?

    Quote Originally Posted by koyama View Post
    Now I'm confused because here he is saying that the head element isn't available for scripting puposes until after page load. But then your example code shouldn't be working, but it does seem to work?
    Who's example code? Mine? Which one?

    Anyway, if the page doesn't load javascript until it finishes loading itself, I see two options:
    1. find out if the user has javascript enabled before the server sends them the page (php or redirects)
    2. don't use javascript (css)

    Some questions:
    -Is there any php function that can tell if the requester has javascript enabled?
    -Is there any way that one css element can change another css element? If not, how do they do those pure-css menus?
    -Does onload have to be for the body? Can I <div onload=""> and it will load the script when the div loads, not the whole page?

  • #6
    Regular Coder BWiz's Avatar
    Join Date
    Mar 2006
    Location
    Sol System
    Posts
    471
    Thanks
    7
    Thanked 21 Times in 21 Posts
    Some questions...

    1) I don't think there is a PHP function which requests JavaScript - but my PHP knowledge is limited.

    2) These CSS Menus displays other hidden divs set below them.

    3) No, the onload property is for the <body> tag. But I myself don't use <body onload="someFunction()">. I use something similiar to this:
    Code:
    <script type="text/javascript">
    <!--
    window.onload = function someFunction()
    {
     alert("Some Function.");
    }
    -->
    </script>
    BWiz :: Happy Coding!
    2006
    2007 2008 2009
    2010 2011
    Irrational numbers make no sense.

  • #7
    Senior Coder koyama's Avatar
    Join Date
    Dec 2006
    Location
    Copenhagen, Denmark
    Posts
    1,246
    Thanks
    1
    Thanked 5 Times in 5 Posts
    Quote Originally Posted by diafygi View Post
    I don't think I understand this method. Wouldn't it create the same effect as Example 3? The script wouldn't load until the page loads, so the answers will appear, then disappear. Correct?
    Not correct. If you look at Bill Posters code then the creation of the link happens on the fly while the page is being loaded. Only the event handlers to control the toggling are assigned onload (which really means after load). That way you will avoid the “flashing” content. Try his method for yourself.

    Quote Originally Posted by diafygi View Post
    Who's example code? Mine? Which one?
    I was referring to Bill Posters code. His example does the same as the suggestion in my first post, but it uses the correct method for creating the link element. What was confusing me was why PPK did not in the first place use Bill Posters method when it appears to be working. I'd still like to hear Bill Posters or some other JavaScript guru to comment on that.
    Last edited by koyama; 07-08-2007 at 11:22 PM. Reason: typo

  • #8
    Senior Coder
    Join Date
    Feb 2003
    Posts
    1,665
    Thanks
    0
    Thanked 27 Times in 25 Posts
    Quote Originally Posted by diafygi View Post
    Anyway, if the page doesn't load javascript until it finishes loading itself, I see two options:
    1. find out if the user has javascript enabled before the server sends them the page (php or redirects)
    2. don't use javascript (css)
    1) A page built according to progressive enhancement will perform the same functional check with fallback.

    2) CSS presents its own support problems in that the :hover pseudo-class isn't supported for non-anchor elements in IE6 or below.

    Is there any way that one css element can change another css element? If not, how do they do those pure-css menus?
    Nested :hovering.

    e.g.
    Code:
    .question .answer {
    	display: none;
    }
    
    .question:hover .answer {
    	display: block;
    }
    
    ...
    
    <div class="question">Question here...
    
    	<div class="answer">Answer here...</div>
    
    </div>
    Does onload have to be for the body? Can I <div onload=""> and it will load the script when the div loads, not the whole page?
    A number of popular 3rd-party js libraries now establish a 'DOMReady' event, which gives full access to a page's DOM structure before the body elements have started to show up on screen.

    It would be the ideal approach for something such as the OP's task, but I thought that it might be a bit advanced under the circumstances as some complex functions would be needed to support the event.

  • #9
    Senior Coder
    Join Date
    Feb 2003
    Posts
    1,665
    Thanks
    0
    Thanked 27 Times in 25 Posts
    Quote Originally Posted by koyama View Post
    Now I'm confused because here he is saying that the head element isn't available for scripting puposes until after page load. But then your example code shouldn't be working, but it does seem to work?
    Indeed. I've not tested it recently on IE6 or below*, but it certainly appears to work as intended in all modern browsers (IE7, Safari, FF, Opera, ...).
    (*iirc, I used the method in a past project, which included support for IE6 and possibly IE5.5. I know the method doesn't work in IE5/Mac.)

    I'd appreciate some confirmation as to whether the DOM-based approach works for IE6 and IE5.5.
    Last edited by Bill Posters; 07-09-2007 at 08:34 AM.

  • #10
    Regular Coder
    Join Date
    Jun 2007
    Location
    N. Ireland
    Posts
    351
    Thanks
    16
    Thanked 4 Times in 4 Posts
    Quote Originally Posted by Bill Posters View Post
    (*iirc, I used the method in a past project, which included support for IE6 and possibly IE5.5. I know the method doesn't work in IE5/Mac.)
    Nothing works on IE5/Mac!
    Daemonkin.
    If this was helpful, please add to my reputation
    Thousand Sons - Freelance Web Developer - ninetyonedegrees.com

  • #11
    Senior Coder
    Join Date
    Feb 2003
    Posts
    1,665
    Thanks
    0
    Thanked 27 Times in 25 Posts
    Quote Originally Posted by daemonkin View Post
    Nothing works on IE5/Mac!
    Now, now. Let's not jump on the IE5/Mac is completely sh*t bandwagon.

    It's tired and half of it is based on ignorance promoted by those who either haven't really experienced it (e.g. Windows-based developers) and those who never took the time to familiarise themselves with the handful of bugs (and their solutions) which represent the few major issues that IE5/Mac has.

    No, of course it doesn't perform as well as more modern UAs, but it still puts in a pretty decent performance considering its age. However, when the need arises, it's usually possible to get IE5/Mac playing reasonably well without too much extra work

    In this instance, it's only the timing that's an issue. IE5/Mac supports the getElementsByTagName and appendChild DOM methods used in the js which I posted. It would take no more than 60 seconds to tweak the script to improve backwards compatibility - if the need arose.

    It would certainly play perfectly well with the document.write method originally put forward. The main technical reason to avoid document.write comes up if you're serving up the js for a document being served as XML - and that's rarely done.
    Last edited by Bill Posters; 07-09-2007 at 09:45 AM.

  • #12
    Senior Coder ahallicks's Avatar
    Join Date
    May 2006
    Location
    Lancaster, UK
    Posts
    1,134
    Thanks
    1
    Thanked 57 Times in 55 Posts
    Couldn't this just be done with pure CSS rollovers? That way you don't need any noscript:

    http://psacake.com/web/jl.asp
    "write it for FireFox then hack it for IE."
    Quote Originally Posted by Mhtml View Post
    Domains are like women - all the good ones are taken unless you want one from some foreign country.
    Reputation is your friend

    Development & SEO Tools

  • #13
    Senior Coder
    Join Date
    Feb 2003
    Posts
    1,665
    Thanks
    0
    Thanked 27 Times in 25 Posts
    Quote Originally Posted by ahallicks View Post
    Couldn't this just be done with pure CSS rollovers? That way you don't need any noscript:

    http://psacake.com/web/jl.asp
    Using CSS alone requires making significant compromises to the natural readability of the underlying markup (as demonstrated throughout your demo) or the (arguable) (mis)appropriation of anchor elements simply to facilitate the desired behaviour.

    None of the options are ideal, but imho, the progressively enhanced js approach may be the best of those available which support a desirable set of UAs.

    The anchorless CSS :hover approach could possibly be the best, were it not for the gaping hole of IE6 support.

    e.g.
    Code:
    <!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-GB" lang="en-GB">
    <head>
    	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
    	<title>test</title>
    	<style type="text/css">
    
    	ul, li {
    		margin: 0;
    		padding: 0;
    		list-style-type: none;
    	}
    
    	li {
    		height: 3em;
    	}
    
    	li li {
    		height: 1em;
    		display: none;
    	}
    
    	li:hover li {
    		display: block;
    	}
    
    	</style>
    </head>
    <body>
    
    <ul>
    	<li>Question 1: ...
    		<ul>
    			<li>Answer 1: ...</li>
    		</ul>
    	</li>
    	<li>Question 2: ...
    		<ul>
    			<li>Answer 2: ...</li>
    		</ul>
    	</li>
    	<li>Question 3: ...
    		<ul>
    			<li>Answer 3: ...</li>
    		</ul>
    	</li>
    	<li>Question 4: ...
    		<ul>
    			<li>Answer 4: ...</li>
    		</ul>
    	</li>
    </ul>
    
    </body>
    </html>
    It could certainly be achieved if you were willing to use an anchor.

    e.g.
    Code:
    <!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-GB" lang="en-GB">
    <head>
    	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
    	<title>test</title>
    	<style type="text/css">
    
    	ul, li {
    		list-style-type: none;
    		padding: 0;
    		margin: 0;
    	}
    
    	a {
    		display: block;
    		height: 3em;
    		text-decoration: none;
    	}
    
    	a span {
    		display: none;
    	}
    
    	a:hover span {
    		display: block;
    	}
    
    	</style>
    </head>
    <body>
    
    <ul>
    	<li><a href="#">Question 1: ... <span>Answer 1: ...</span></a></li>
    	<li><a href="#">Question 2: ... <span>Answer 2: ...</span></a></li>
    	<li><a href="#">Question 3: ... <span>Answer 3: ...</span></a></li>
    	<li><a href="#">Question 4: ... <span>Answer 4: ...</span></a></li>
    </ul>
    
    </body>
    </html>
    I personally would probably avoid such a solution as I don't think turning non-link text into a link is justified by the needs of the behaviour.

    Still, it's there as an option to consider (if you're not as fussy as me).

  • #14
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,302
    Thanks
    28
    Thanked 276 Times in 270 Posts
    Quote Originally Posted by diafygi View Post
    The reason this doesn't work very well is because this technique is going onto a fairly large page with a lot of these questions. So when the page is loading, all of the answers are visible. Then, suddenly, they disappear. This really annoys me and (I bet) the user, too.
    You can manipulate style sheets directly via the DOM as shown in my example. This should work for your purposes if you create a rule that applies display: none to the answers.

    The code for my example is shown below for archival purposes.

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    
    <html lang="en-Latn-US">
    	<head>
    
    		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    		<title>Demo CF118276</title>
    		<meta name="Author" content="Patrick Garies">
    		<meta name="Created" content="2007-07-09">
    		<meta name="Revised" content="2007-07-09">
    		<style type="text/css" media="all">
    			* { margin: 0; padding: 0; }
    			html { background: white; color: black; font: 16px/1.2 sans-serif; }
    			p { margin: 1em; padding: 1em; text-align: center; }
    		</style>
    		<!--[if !IE]>-->
    		<script type="application/ecmascript">
    			if (document.implementation.hasFeature("CSS", "2.0")) {
    				var sheets = document.styleSheets;
    				sheets[0].insertRule("p { background: black; color: lime; }", sheets[0].cssRules.length);
    			}
    		</script>
    		<!--<![endif]-->
    		<!--[if IE]>
    			<script type="text/javascript">
    				var sheets = document.styleSheets;
    				sheets[0].addRule("p", "background: black; color: lime;");
    			</script>
    		<![endif]-->
    	</head>
    	<body>
    	
    		<p>This text should be <code>lime</code> on a <code>black</code> background.</p>
    	
    	</body>
    </html>
    Quote Originally Posted by koyama View Post
    This is a classic problem. Maybe this article by Peter-Paul Koch will interest you. Read the section “The single correct use of document.write”.

    Basically, the solutions is to use this in the head section:
    Code:
    <script type="text/javascript">
    document.write('<link rel="stylesheet" href="advanced.css" />');
    </script>
    There is no “single correct use” of document.write() in an XHTML document. That method is incompatible with XML.

    Quote Originally Posted by BWiz View Post
    3) No, the onload property is for the <body> tag.
    In the context of the body tag, onload is an attribute, not a property.

    Quote Originally Posted by BWiz View Post
    But I myself don't use <body onload="someFunction()">. I use something similiar to this:
    Code:
    <script type="text/javascript">
    <!--
    window.onload = function someFunction()
    {
     alert("Some Function.");
    }
    -->
    </script>
    As I said before, don’t put <!-- or --> (SGML comment tags) around scripts or style sheets unless you want them to be ignored. In real XHTML, they will cause scripts and style sheets to be ignored. You shouldn’t suggest them for HTML authors either since they’re virtually useless.
    For every complex problem, there is an answer that is clear, simple, and wrong.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •