Cross Browser-Compatible Show/Hide Scripts

Discussion in 'JavaScript' started by Masterful, Mar 5, 2009.

  1. #1
    Can anyone point me in the direction of a cross browser-compatible script which will show/hide elements such as divs? Its button must change from 'Show' to 'Hide' when 'Show' is clicked, and, by default, the divs must be hidden when the page loads (unless Javascript is turned off, in which case the divs must show by default).

    There are many threads dedicated to this topic, but none of them seem to have what I'm looking for. I've also searched the web, but have so far been unable to find such a thing.
     
    Masterful, Mar 5, 2009 IP
  2. SEOVancouver

    SEOVancouver Peon

    Messages:
    35
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
  3. xlcho

    xlcho Guest

    Messages:
    532
    Likes Received:
    8
    Best Answers:
    0
    Trophy Points:
    0
    #3
    This is pretty simple, here's a short script i wrote in a minute:
    <script type='text/javascript'>
    function showElement(id, display)
    {
    	if(!display)
    		display = 'inline';
    	
    	if(document.getElementById(id).style.display != 'none')
    	{
    		document.getElementById(id).style.display = 'none';
    		
    		return 'Show';
    	}
    	else
    	{
    		document.getElementById(id).style.display = display;
    		
    		return 'Hide';
    	}
    }
    </script>
    
    <div id="myDiv" style="display: none";>test div</div><br />
    <input type="button" value="Show" onclick="this.value = showElement('myDiv')">
    Code (markup):
    The showElement function takes two parameters - the id of the element that it will show/hide and 'display' (by default = 'inline') which has to be set if the element is going to be shown. The second parameter might be needed when you want to show/hide different elements. If you want to hide an element all you have to do is set it's display property to 'none', but when you want to show it back you can use either 'inline' or 'block', depending on the element. Hope that's what you needed :)
     
    xlcho, Mar 5, 2009 IP
  4. Masterful

    Masterful Well-Known Member

    Messages:
    1,653
    Likes Received:
    28
    Best Answers:
    0
    Trophy Points:
    140
    #4
    SEOVancouver and Xlcho, thank you both for your responses. One rep point for each of you. :)

    SEOVancouver, that's an excellent script. It is, however, a little more than I asked for. It's a little too advanced for me.

    Xlcho, that's almost exactly what I'm looking for. A few quick questions about it, if I may . . .

    1. Is it compatible across all browsers?
    2. How can I change the button to an <a href> and still have the script work in the same way?
    3. What happens if Javascript is turned off?

    I appreciate your help very much.
     
    Masterful, Mar 6, 2009 IP
  5. Masterful

    Masterful Well-Known Member

    Messages:
    1,653
    Likes Received:
    28
    Best Answers:
    0
    Trophy Points:
    140
    #5
    I see that, if Javascript is turned off, the content remains hidden.

    When I think about it, this is fine. I would like it to remain closed and for a message to appear when someone clicks on the 'Show' button, saying: 'You must turn Javascript on for this function to work.'

    Is that possible?
     
    Masterful, Mar 6, 2009 IP
  6. Masterful

    Masterful Well-Known Member

    Messages:
    1,653
    Likes Received:
    28
    Best Answers:
    0
    Trophy Points:
    140
    #6
    Cool! I've just found this little script:

    <script type=text/javascript>
    window.onload = function hidemsg()
    {
     document.getElementById('jsmsg').style.display='none';
    }
    </script>
    
    
    <div id="jsmsg">NOTE: JavaScript has been disabled on your browser. Without Javascript, the 'Show/Hide' links on this page will not work. Please re-enable Javascript for full functionality.</div>
    Code (markup):
    * Note: I used DIV instead of NOSCRIPT because, apparently, NOSCRIPT is not properly supported by some browsers, including Opera.

    Now, if Javascript has been turned off, the message in the DIV will appear atop my page. Please, therefore, disregard my last post. However, I would still like a response to my other two questions:

    1. Is the code below compatible across all browsers?
    2. How can I change the button to an <a href> and still have the script work in the same way?
    Any help will be very much appreciated.

    <script type='text/javascript'>
    function showElement(id, display)
    {
    	if(!display)
    		display = 'inline';
    	
    	if(document.getElementById(id).style.display != 'none')
    	{
    		document.getElementById(id).style.display = 'none';
    		
    		return 'Show';
    	}
    	else
    	{
    		document.getElementById(id).style.display = display;
    		
    		return 'Hide';
    	}
    }
    </script>
    
    <div id="myDiv" style="display: none";>test div</div><br />
    <input type="button" value="Show" onclick="this.value = showElement('myDiv')">
    Code (markup):
     
    Masterful, Mar 6, 2009 IP
  7. dimitar christoff

    dimitar christoff Active Member

    Messages:
    882
    Likes Received:
    62
    Best Answers:
    0
    Trophy Points:
    90
    #7
    it will be compatible with all browsers that support DOM calls and getElementById(); - which is just about everything. off the top of my head, ie6,7,8, ff 1.5-3.5, opera (dont know since when, but early), safari 1.2+

    one thing i'd change in this script its the display to 'block' but it depends on your css needs anyway.
    here is a different and simpler / elegant take on this:
    
    <script>
    var toggleVis = function(triggerEl, targetEl) {
        targetEl.style.display = (targetEl.style.display == "none") ? "block" : "none";
        triggerEl.value = (triggerEl.value == "Show") ? "Hide" : "Show"; // change the button itself.
    };
    </script>
    <div id="myDiv" style="display: none";>test div</div><br />
    <input type="button" value="Show" onclick="toggleVis(this, document.getElementById('myDiv'));">
    </script>
    PHP:
    as for anchor link you can modify it like so:
    <script>
    var toggleVis = function(triggerEl, targetEl) {
        targetEl.style.display = (targetEl.style.display == "none") ? "block" : "none";
        triggerEl.innerHTML = (triggerEl.innerHTML == "Show") ? "Hide" : "Show"; // change the button itself.
    };
    </script>
    <div id="myDiv" style="display: none";>test div</div><br />
    <a href="#" onclick="toggleVis(this, document.getElementById('myDiv'));return false;">Show</a>
    </script>
    PHP:
    but i am not sure if its best practice to use innerHTML as a source of reading data and comparing it or how reliable this is. check google for cross browser functions compatibility tables. i've tested in gran paradiso and ie7
     
    dimitar christoff, Mar 6, 2009 IP
    Masterful likes this.
  8. Masterful

    Masterful Well-Known Member

    Messages:
    1,653
    Likes Received:
    28
    Best Answers:
    0
    Trophy Points:
    140
    #8
    Thanks, Dimitar! One rep point for you. :)

    However, I am now confused. :confused: Which one should I use? Which is the safest one when it comes to compatibility?

    You said that Xlcho's script will work on almost all browsers, as long as they support DOM calls and getElementById. But what about the scripts that you gave? Should I not use the innerHTML one with the anchor?

    I need the button to be an anchor, and I need the script to be as compatible as Xlcho's one.

    On another note, I wanted to correct this:

    Apparently, Opera only has a problem with <noscript> tags if the tags have been styled with CSS (source).
     
    Masterful, Mar 6, 2009 IP
  9. dimitar christoff

    dimitar christoff Active Member

    Messages:
    882
    Likes Received:
    62
    Best Answers:
    0
    Trophy Points:
    90
    #9
    same applies to the script i gave, i guess. http://www.quirksmode.org/dom/w3c_html.html#t03 - its supported from ie 5.5 onwards 'almost'. innerText is an alternative for ie anyway - and w/o the markup you may incur when using innerHTML. anyway i wouldnt worry about it, its good.
     
    dimitar christoff, Mar 7, 2009 IP
  10. dimitar christoff

    dimitar christoff Active Member

    Messages:
    882
    Likes Received:
    62
    Best Answers:
    0
    Trophy Points:
    90
    #10
    after checking some more, the only times IE would be funny about innerHTML is when you are trying to apply it on table elements like td or tr. so in our case here, safe as anything.
     
    dimitar christoff, Mar 8, 2009 IP
  11. midmood

    midmood Peon

    Messages:
    1
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #11
    Hi dimitar,
    I mean to use your code to show/hide a series of checkbox lists.
    I tried to customize it, but there is a conflict and I don't know how to solve it
    This is my code

    
    <script>
    var toggleVis = function(triggerEl, targetEl) {
        targetEl.style.display = (targetEl.style.display == "none") ? "block" : "none";
        triggerEl.innerHTML = (triggerEl.innerHTML == "Cerca tutti per colore") ? "Nascondi ricerca per colore" : "Cerca tutti per colore"; // change the button itself.
        triggerEl.innerHTML = (triggerEl.innerHTML == "Ricerca completa") ? "Nascondi ricerca completa" : "Ricerca completa"; // change the button itself.
    };
    </script>
    
    <div id="myDiv" style="display: none";>
    // here goes the checkbox list
    </div><br />
    <a href="#" onclick="toggleVis(this, document.getElementById('myDiv'));return false;">Cerca tutti per colore</a>
    
    <div id="myDiv2" style="display: none";>
    //here goes the checkbox list
    </div><br />
    <a href="#" onclick="toggleVis(this, document.getElementById('myDiv2'));return false;">Ricerca completa</a>
    
    PHP:
    The problem is: when I first load the page, the anchor for the hidden DIVs are correct, that is 1) Cerca tutti per colore 2) Ricerca completa.
    But... whichever anchor I click, the text become always "Ricerca completa".

    Can you help me?

    Thank you
    Simone (Italy)
     
    midmood, May 9, 2009 IP
  12. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #12
    This is off the topic but im fairly new to javascript and the following line:
    targetEl.style.display = (targetEl.style.display == "none") ? "block" : "none";

    Is that saying:
    if(display=="none") display="block"
    else display = "none"

    I'm unfamiliar with this syntax.

    ??
     
    camjohnson95, May 11, 2009 IP
  13. dimitar christoff

    dimitar christoff Active Member

    Messages:
    882
    Likes Received:
    62
    Best Answers:
    0
    Trophy Points:
    90
    #13
    it is exactly what it's saying :)

    it's a very nice construct that allows you to save space on assignment. the bit after ? is when condition is true, bit after : is when false.

    you can also nest this...
    
    targetEl.style.display = (targetEl.style.display == "none") ? (foo.cellDisplay == true) ? "block" : "inline" : "none"; 
    
    PHP:
    the same syntax is available in php:
    
    $scriptURL = (basename($_SERVER['PHP_SELF']) == "index.php") ? "http://mydomain.com/" : "http://mydomain.com/{$_SERVER['PHP_SELF']}";
    
    PHP:

    midmood: you can't use the same function to reference two target elements. it can be rewritten to use a set, perhaps as JSON like so:

    <html>
    <head>
    <script language="javascript">
    var toggleVis = function(data)  {
        /* toggles vis and updates trigger link text
        params: JSON with following properties:
        
        {
            triggerEl: object, // points to link itself that calls it
            targetEl: object, // points to the div whose visibility we toggle
            state1: text, // text state 1
            state2: text // text state 2
        }
        
        example use:
        
        toggleVis({
            triggerEl: document.getElementById("mylink"),
            targetEl: document.getElementById("mydiv"),
            state1: "show",
            state2: "hide"
        });
        */
        
        
        data.targetEl.style.display = (data.targetEl.style.display == "none") ? "block" : "none";
        data.triggerEl.innerHTML = (data.triggerEl.innerHTML == data.state1) ? data.state2 : data.state1; // change the button itself.
        return false;
    };
    </script>
    </head>
    <body>
    
    <div id="myDiv" style="display: none";>
    // here goes the checkbox list
    </div><br />
    <a href="#" onclick="return toggleVis({triggerEl:this,targetEl:document.getElementById('myDiv'),state1:'Cerca tutti per colore',state2:'Nascondi ricerca per colore'});">Cerca tutti per colore</a>
    
    <div id="myDiv2" style="display: none";>
    //here goes the checkbox list
    </div><br />
    <a href="#" onclick="return toggleVis({triggerEl:this,targetEl:document.getElementById('myDiv2'),state1:'Ricerca completa',state2:'Nascondi ricerca completa'});">Ricerca completa</a>
    </body>
    </html>
    
    PHP:
    note you need to construct the json and pass objects, not id references.

    p.s. it's a very bad practice to use onclick="" inline within elements like so, this ought to go in window.onload instead... but that's not the point of the exercise :)
     
    dimitar christoff, May 11, 2009 IP