0

How can I add a Hide/Show (Collapse/Expand) feature to images on a page, based on class?

I want images with a particular class to be collapsed on load, and be prepended with some arbitrary markup defined in the JS (Let's say, <span>Show</span>), and then have different arbitrary markup (<span>Hide</span>) in the expanded state,

The content is generated from markdown, so I cannot add additional HTML, other than adding a class to the image.

I would prefer a solution that does not require an entire JS library be added to the site. This is a document-focused site with very little dynamic functionality.

(I have no "what I tried" code because I don't know what to try. Googling solutions comes up with lots of tutorials on how to write a single function to toggle a single element with lots of extraneous markup. I do not know how to use a class to simply attach this feature to an element, but I know it can be done and that is what I need.)

EDIT for clarification

  • This needs to work on an arbitrary number of elements on a page --- all the ones with the specific class.
  • The class can only be added to the element which is to be hidden/shown --- not to a containing element.
  • The problem I am specifically having in figuring out how to do this is: programmatically add Hide/show "buttons" that only affect the element that created them.
Adam Michael Wood
  • 1,730
  • 16
  • 23

4 Answers4

1

I found an answer in another question that is pure HTML. If you're not worried about browser support it seems super simple.

<details>
    <summary>text before expanding</summary>
    <p>Show when open</p>
</details>
<span>Show when closed</span>

As for styling the "Show when closed" span, you can accomplish this with CSS. One approach is to hide it when details element is open.

details[open] + span {
   display: none;
}
Matthew Thurston
  • 720
  • 5
  • 22
  • Thanks. I'm familiar with the `
    ` element. It isn't a good solution because of browser support and also our html generation from plain text content.
    – Adam Michael Wood Nov 30 '17 at 19:07
0

Could it be ok with a hover action?

.expand {
  opacity: .5;
  height: 20px;
  transition: all 1s;
}

.expand:hover {
  opacity: 1;
  height: 100px;
}
<img src="https://www.google.fr/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png" class="expand" />
<img src="https://www.google.fr/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png" class="expand" />
Valentin
  • 76
  • 4
0

I would use JQuery (if you are not already using it), since it will be easier for you to work with the dom (easier than raw javascript). You can add it from the cdn for not adding files and stuffs on your site:

<script
  src="https://code.jquery.com/jquery-3.2.1.min.js"
  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
  crossorigin="anonymous"></script>

After having Jquery you can:

$(function(){
   // Do something on load
   $('img.classHidenOnLoad').hide();

   $("span:contains('Hide')").click(function(){
    alert("hide");   
   });
   $("span:contains('Show')").click(function(){
    alert("show");
   });
});

EDIT

If you don't want to use jquery, you can translate it with this reference:

http://youmightnotneedjquery.com/

  • I'm more concerned with adding load time, as the site is used by a lot of people in places with very slow internet. (Third world countries, for example.) – Adam Michael Wood Nov 30 '17 at 19:05
  • Ok. You can use the site I posted on my edited answer to translate the easier jquery code that fits your needs. – Alejandro Techera Nov 30 '17 at 19:15
  • I appreciate your trying to help. And I'm not completely opposed to using JQuery. But your code (as you know) doesn't do what I am attempting to do. The difficulty I am having is: how do I append show/hide buttons to each element in the class, so that they show or hide thtat specific element. – Adam Michael Wood Nov 30 '17 at 19:34
  • Sorry, I still don't understand what you are trying to do. I'll take a better look tomorrow and try to give you a better answer. If you could however explain a little bit more what you are trying to accomplish, I'll apreciate it. – Alejandro Techera Nov 30 '17 at 21:54
0

function uniqId() {
  return Math.round(new Date().getTime() + (Math.random() * 100));
}

$(function(){
   // Do something on load
   $(".details").each(function(index){
    $(this).attr('id', uniqId());
    togl = "<span class='toggler' data-toggle='" + $(this).attr('id') + "'>Show</span><br>";
    $(this).before(togl);
    $(this).addClass('hidden');
   });
   
   $(".toggler").each(function(index){
     $(this).click(function(e){
       toggle_image = $('#' + $(this).attr('data-toggle'));
       if ($(this).text() == "Show") {
         $(this).text("Hide");
         toggle_image.removeClass("hidden");
       } else {
         $(this).text("Show");
         toggle_image.addClass("hidden");
       }
     })
   });
});
.hidden {
  display:none;
}
<script
  src="https://code.jquery.com/jquery-3.2.1.min.js"
  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
  crossorigin="anonymous"></script>

<img class="details" src="http://via.placeholder.com/200x200">
<br>
<img class="" src="http://via.placeholder.com/100x200">
<br>
<img class="details" src="http://via.placeholder.com/200x100">

Here's what it does:

  • To every element of class details:
    • adds an ID attribute
    • appends a <span>Show</span> element, with a data-toggle attribute referencing the image's ID and a class of toggler
  • To every toggler:
    • Add a click function that toggles the text (show/hide) and the visibility of the element with the id referenced in its data-toggle attribute
Adam Michael Wood
  • 1,730
  • 16
  • 23