# Simple JavaScript hide/show

I am working towards a script that will show a set small thumbnail images on one side of the page, that when clicked will show a larger version of the same image, plus related text content on the other side of the page. I am not very good with JavaScript yet and wonder if the <script> section here is fussier than necessary to accomplish this. It does seem to work. But can the script/code be simpler to accomplish this? Should I use "id" or "class" for each item?

<html>
<script>
$(document).ready(function() {$("p").hide();
$("p.default").show(); /*$("p.one").show();*/ /*this would probably be default*/
$(".btn1").click(function() {$("p").hide();
$(".one").show(); });$(".btn2").click(function() {
$("p").hide();$(".two").show();
});
$(".btn3").click(function() {$("p").hide();
$(".three").show(); }); }); </script> </head> <body> <div class="btn1">Show1</div> <div class="btn2">Show2</div> <div class="btn3">Show3</div> <p class="default">This is default content.</p> <p class="one">This is content 1.</p> <p class="two">This is content 2.</p> <p class="three">This is content 3.</p> </body> </html>  Also, my overall goal is to use this with a page that shows, say 20-30 clickable thumbnails/small images, that when clicked will reveal a couple of text paragraphs and multiple (maybe 25) larger images that relate to the clicked thumbnail. I believe I understand that all of that will be loaded/hidden when the page first loads. Does that sound like too much? Is it likely to be a slow page? (I posted this exact same thing at phpbuilders...but it looks like a lot more JavaScript stuff goes on here.) • you can do all the click handlers in one function using a table like {btn1:"one", btn3:"three"} – dandavis Sep 10 '14 at 1:53 • A little indentation could help – Bergi Sep 10 '14 at 1:54 ## 3 Answers Yes, it's too complex. Make the elements relate to each other, so that you can use a single event handler. This is the typical pattern used to link two DOM elements together, so that one can hide/show/otherwise interact with the other. <a href="#one">Show1</a> <a href="#two">Show2</a> <a href="#three">Show3</a> <p class="default">This is default content.</p> <p id="one">This is content 1.</p> <p id="two">This is content 2.</p> <p id="three">This is content 3.</p>  And: $('a').click(function (event) {
event.preventDefault();
$('p').hide();$($(this).attr('href')).show(); });  • Thank you! There are a few concepts in your$ section that I don't know yet. Will try to have a go at using them tomorrow. – phc_joe Sep 10 '14 at 2:03
• I am not understanding this line: "<p id="one" lass="one">This is content 1.</p>" Did you mean "class" and can/should I use both id and class at the same place? – phc_joe Sep 10 '14 at 2:05
• That was a typo. – user229044 Sep 10 '14 at 2:07
• Thanks for getting back to me about that. I am so green in javascript, I'll believe anything. Even typos! – phc_joe Sep 10 '14 at 2:17
• How about just $(this.href).show(); – Derek 朕會功夫 Sep 10 '14 at 2:56 You can have the div classes to be the same and having an attribute that contains the class to show like this: <div class="btn" data-show="one">Show1</div> <div class="btn" data-show="two">Show2</div> <div class="btn" data-show = "three">Show3</div>  And now can have only one function to achieve the goal. Something like this: $(document).on('click','.btn',function() {
var show = $(this).attr('data-show');$("p").hide();
$("."+show).show(); });  Ooooooo....K! Now I get it! $(document).ready(function () {
$(document).on('click','.btn',function() { var show =$(this).attr('data-show');
$("p").hide();$("."+show).show();
});
$("p").hide();$(".default").show();
});


...then do the buttons and content paragraphs like this...

<div class="btn" data-show="one">Show1</div>
<div class="btn" data-show="two">Show2</div>
<div class="btn" data-show="three">Show3</div>

<p class="default">Content default.</p>
<p class="one">Content 1.</p>
<p class="two">Content 2.</p>
<p class="three">Content 3.</p>


BUT Now I would rather have the content in divs rather than paragraphs (so I can format the display and include images, etc.) how would I change $("p").hide(); to$("div").hide(); that would not make all my other divs disappear?

• Don't invent attributes, use existing ones, or use data- attriutes. – user229044 Sep 10 '14 at 1:57
• Wow. I was thinking there must be a way to eliminate all the redundancies in the code. I will give this a try. Thanks! – phc_joe Sep 10 '14 at 1:59
• instead of $(this).attr('data-show') you can go $(this).data('show') – jasonscript Sep 10 '14 at 2:42
• Okay! I have been making some progress with these suggestions. But I have one more: How do I make the FIRST (default) element visible when the page loads? What do I need to add to the following script to make that happen? $(document).on('click','.btn',function() { var show =$(this).data('show'); $("p").hide();$("."+show).show(); }); – phc_joe Sep 10 '14 at 15:58
• You can do a .show() on the $(document).ready function for the default element that you want to make visible – V31 Sep 10 '14 at 18:05 Someone at phpbuilder.com also responded to my original question (posted there) and came up with a somewhat different method. I worked with it a bit this morning (and messed with it a bit for my own edification).   <style type="text/css"> /* SYNTAX NOTE: there must be a space between "#displays" and ".hidden" */ #displays .hidden { /* if any of the items in the id group "displays" group has the class "hidden", it will not be displayed*/ display: none; } #buttons{width: 50%; float: left;} #displays{width: 50%; float: left;} </style> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script>$(document).ready(function () {
window.$ViewItem =$('#displays .default'); //displays the div <p class="default">This is default content.</p>
$('#buttons').on('click', 'div', function (e) { var$el = $('#displays .' + e.target.className); // .children looks for direct descendants only /*$el.removeClass('hidden');  ERROR: THIS LINE SHOULD BE MOVED ONE LOWER*/
window.$ViewItem.addClass('hidden'); /* whatever WAS being shown gets the "hidden" put back on so that it will disapear*/$el.removeClass('hidden');   /*click button & "hidden" class is taken off of any display items, so that they will be displayed*/
window.$ViewItem =$el;
}); /*closes the #buttons function*/
}); /*closes $(document).ready*/ </script>    <div id="displays"> <p class="default">This is default content. in a p</p> <div class="default">This is default content. in a div</div> <p class="one hidden">This is content 1.</p> <p class="one hidden">This is more of content 1.</p> <p class="two hidden">This is content 2.</p> <p class="two hidden">This is more of content 2.</p> <p class="three hidden">This is content 3.</p> <div class="three hidden">This is content 3. in a div<div>content in a nested div within 3<br /><img src="archive/imapic.png" /></div></div> </div> <div id="buttons"> <div class="one">Show 1</div> <div class="two">Show 2</div> <div class="three">Show 3</div> </div>   This does work and accomplishes everything (and then some) noted in the original question. But I would have never come up with any of it myself. Perhaps it will be of use to someone else. • I think I am going to go with this solution simply because it is more flexible and I seem to be able to understand it conceptually: it seems easier to display multiple contents of different types (ie a mix of things like Ps and DIVs, etc. that can simply be given the same class name (ie. class="X hidden") which should help me with the overall page layout I am trying for at this point. The other solutions also work and would probably be better choices in other contexts. Thanks to everyone who has helped me here. I learned a lot! – phc_joe Sep 12 '14 at 16:17 • Ooops! Found a problem, the following lines in the script should be reversed: if not re-clicking the same button will make the display disappear...which will be confusing for visitors /* .children looks for direct descendants only */ window.$ViewItem.addClass('hidden'); \$el.removeClass('hidden'); – phc_joe Sep 15 '14 at 19:41