Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Erik Nuber
Erik Nuber
20,629 Points

Get image tag info in one window and use in another with JS.

I have been trying to figure this out...here it is step by step....

1) when an image is clicked, grab the image tag in full and store it in a variable. 2) new window opens up blank as display is set to none on all images. 3) compare the image tag from part one to an array of the images. 3) when the comparison finds a match change the display to block so it appears.

I have been testing and, if I preventDefault on the href so that nothing happens, I know the image tag is being grabbed as I want. However, if the window reloads to another page that information disappears. So I'm wondering if this is even possible at all.

My goal...I have a series of 17 images and, would like to create a single .html page with a tag that hides the images unless they were clicked. If they were click, I change the tag from hidden to block so that it displays.

I know I can simply add 17 .html files with the correct image but, wondering if there is a better way to do this.

4 Answers

Kevin Korte
Kevin Korte
28,148 Points

so you're just trying to show the clicked on image fullscreen in another tab?

Erik Nuber
Erik Nuber
20,629 Points

Yes, I realize I can have each image set to a specific .html file that can display the image in full. I am trying to figure out if rather than have a whole bunch of .html files, I can just have one .html file that I can manipulate showing the correct image.

So, I have all the images listed on the page that the image will be clicked to. I want only the correct image to pop up. I have all the images with a class that has the display set to none.

I have figured part of this out now.

I used JSON to stringify the image so that I could pass the info to the correct .html file. I then used the JSON.parse method to recreate the image tag.

That is now as far as I am. I am trying to figure out what to do with that image tag now. I can append it to whereever I want but, I want it in a variable which I can't seem to be able to do. So I'm now trying to append it to the document and then remove it and store it that way.

Steven Parker
Steven Parker
229,732 Points

What if you opened a new, empty, window and then wrote the HTML into it to display the single image that was clicked? Wouldn't that do what you want?

Something like this:

script.js
function myFunction(img) {
  var imageHTML = img.outerHTML;
  var myWindow = window.open("", "_blank", "width=400,height=300"); // substitute real dimensions
  myWindow.document.write(imageHTML);
}
code.html
<img ... onclick="myFunction(this)">  <!-- add handler to each image -->
Erik Nuber
Erik Nuber
20,629 Points

That could work. I will give it a try.

Erik Nuber
Erik Nuber
20,629 Points

I finally did it. Just putting up the code as it took me hours to figure it out and, if someone else may find it useful passing it on...

File 1: This is the file that shows a bunch of images formatted however you like. For me, this was a browser screen that can be accessed from the nav menu and shows some of my portfolio. I added this script to the head. The script creates a JSON string from the clicked image. It stores the src and alt text. Easily can add whatever else you would like to pass on from that tag.

    <script>
        (function(mark){
             function init(){
              mark.document.getElementById('miscWork').addEventListener('click',sendImage,false);
             }

             function sendImage(e){
                  var a=e.target;

                  if(a.parentNode.className=='miscImage'){
                   mark.localStorage['imginfo']=JSON.stringify({src:a.src,alt:a.alt});
                   mark.location.href="miscFiles/acupractice.html";
                  }

             }

             mark.addEventListener('load',init,false)
        })(window)
    </script>

File 2: Here is a second file which has all the images listed again but, much more simplified and formatted in a completely different way. This file can not be accessed by the navigation screen, only by clicking on images within a specific page. The script here parses out the JSON, makes it an image tag again, and appends it to the end of an Id tag which contains all the images. Again, this can easily be edited to append wherever you like as well as being able to parse out additional information within the Image tag.

        <script>
            window.onload=function(){
             var img=document.createElement('img');
             var info=JSON.parse(window.localStorage['imginfo']);
             delete window.localStorage['imginfo'];
             img.src=info.src;
             img.alt=info.alt; 
             var placeToAppend = document.getElementById('marbleCircle');    
             placeToAppend.appendChild(img);
            }
        </script>

finally the JavaScript...

I needed the entire script above to run first so that the image was properly appended before anything happened, I created the window.load function to call after the window is loaded completely.

$(window).load(function () {
    "use strict";
    getClickedImage();
});

Created the variables miscImageHolder contains a list of the images with the given class and is an object

List is an object containing section tags that have all the information about the images including header and text info along with the image tags themselves. Appended on this list is the image that was clicked on and appended from the script above.

item is the last item in the List which is set to the only tag that is just an image and again is the image that was appended earlier.

var miscImageHolder = document.querySelectorAll("#marbleCircle img"),
    mIC, //short for miscImageCounter
    list,
    item;

The ClickedImage function checks to verify that it is on the correct page by checking the Id, and if it is it then assigns the variables listed above. I then check to see if the last item is in fact just an image tag and if it is, I remove it. I don't need it and, if left in, it appears in the window as it was appended. If I don't check for this than the image I do want to appear for also gets removed so I had to create something to check. As the list is comprised of sections and one image tag it was made easy this way. Also item is already defined so holds the image tag I want.

function getClickedImage() {
    "use strict";
    if (document.getElementById("marbleCircle")) {
        list = document.getElementById("marbleCircle");
        item = $(list.lastChild);

        if ($(item).is('img')) {
            $(list.lastChild).remove();
        }

Next, I run a loop on the length of the object list containing just the images. Item, which holds the clicked on image is then checked to see if both the alt attribute texts match. I had to do this as the actual images themselves were different files because of how I did my CSS. This could be altered again to check for the src tag though. If the alt tags match, I assign a class called reveal so that the image displays and, every other image in the list gets a class hide to make it disappear.

        for (mIC = 0; mIC < miscImageHolder.length; mIC++) {
            if ($(miscImageHolder[mIC]).attr("alt") === $(item).attr("alt")) {
                $(miscImageHolder[mIC]).parent().parent().addClass("reveal");
            } else {
                $(miscImageHolder[mIC]).parent().parent().addClass("hide");
            }
        }
    }

}

From here I still need to add buttons for prev and next but, that should be fairly quick and, as this was just for the small screen I will redesign for various browser widths...