My aim is to do a thumbnail gallery which will enlarge thumbnail in a new row after the thumbnail has been clicked [Edited for clarity]:
I am not sure how to do it properly (if there is a proper way). How would you conceptually approach this task?
Flexbox seems to be nice for the first part, but then add cell on calculated position by JS OR split the flexbox into two? And in every case redo everything completely in there was a resize?
A help would be also to know how this kind of gallery is called, because I was unable to find any info on Google. Thank you!
This is an example showing how a container could use display:flex; to show a number of div.item as pictures in a gallery.
Each of such div.item gets attached an handler for the click event, that will clone, populate and attach to dom the template defined to represent a preview.
The preview will show a bigger picture of the thumbnail clicked and some further details that the demo just limits to the item index number. Such bigger picture must be defined in the attribute data-original-image-url of the img thumbnail.
I was inspired to this question Gallery with bigger previews "in place" to craft the trick needed to determine the last item of a given row in a flex container.
Consider that the pictures url are fake here so the demo won't show any picture but just broken urls. I faked the size of items setting a arbitrary different width for each of them and setting the height fixed in a css class.
//Add click event handler to every div.item in any .gallery
let items = document.querySelectorAll('.gallery > div.item');
for(let item of items){
item.addEventListener('click', onItemClick);
}
/*
When an item gets clicked,
It shows a preview, bound to the item clicked, on the next line
*/
function onItemClick(event){
//the clicked item
//(currentTarget retrieves the item that had the listener not the actual element clicked)
//so in this case it will be always the div.item (never the picture itself)
clickedItem = event.currentTarget;
//determines the index (1 based) of the clicked item relative to its container
const itemIndex
= Array.from(clickedItem.parentElement.querySelectorAll('.item')).indexOf(clickedItem) + 1;
//removes all .preview elements inside the parent of the clicked item
clickedItem.parentElement.querySelectorAll('.preview').forEach( (o, i) => {
o.remove();
});
//retrieves the url for the bigger picture of the item clicked
let urlBiggerImage = clickedItem.querySelector('img').getAttribute('data-original-image-url');
//retrieves the last item in the row where the item clicked lays
let lastItemOfRow = getLastItemOfRow(clickedItem);
//retrieves the html template for the preview
const template = document.getElementById("template_preview");
//clones the template to prepare the node as a concrete preview for the current item
const preview = template.content.cloneNode(true);
//sets the img src of the preview using the value of this item.data[original-image-url]
preview.querySelector('img').src = urlBiggerImage;
//sets the description of the preview
preview.querySelector('.col:nth-child(2) p').innerText = `You selected the item n.${itemIndex}`;
//appends the preview item after the last item in the row where item clicked lays
lastItemOfRow.after( preview );
}
/*
Retrieves the last item in the row (of the flexbox container)
given an item determining the row to examine
Inspired by:
https://stackoverflow.com/questions/72096795/gallery-with-bigger-previews-in-place/72096982
*/
const getLastItemOfRow = (item) => {
const grid = item.parentElement;
const gridItems = Array.from(grid.querySelectorAll('.item'));
const itemIndex = gridItems.indexOf(item);
const baseOffset = item.offsetTop;
let breakIndex = gridItems.findIndex(item => item.offsetTop > baseOffset) -1;
breakIndex = (breakIndex < 0) ? itemIndex : breakIndex;
return gridItems[breakIndex];
}
.gallery{
display: flex;
flex-wrap: wrap;
gap: 10px 10px;
padding: 10px;
border: solid 1px gray;
/*Here you can define an arbitrary width for the container*/
width: 430px;
}
.item{
display: block;
height: 50px;
background: red;
color: white;
font-weight: 700;
cursor: pointer;
}
.item > img{
height: 50px;
}
.preview{
border: solid 1px black;
flex: 0 0 100%;
}
.preview > .col{
display: inline-block;
padding: 5px;
vertical-align: middle;
}
.bigger {
width: 200px;
height: 100px;
}
<template id="template_preview">
<div class="preview">
<div class="col">
<img class="bigger" src=""/>
</div>
<div class="col">
<p>You selected the picture n:</p>
</div>
</div>
</template>
<!-- You can have many .gallery container -->
<div class="gallery">
<!-- Each .item will count as an item with preview -->
<div class="item">
<img src="/img/1.jpg" title="1" style="width: 100px;" data-original-image-url="/img/bigger/1.jpg"/>
</div>
<div class="item">
<img src="/img/2.jpg" title="2" style="width: 70px;" data-original-image-url="/img/bigger/2.jpg"/>
</div>
<div class="item">
<img src="/img/3.jpg" title="3" style="width: 180px;" data-original-image-url="/img/bigger/3.jpg"/>
</div>
<div class="item">
<img src="/img/4.jpg" title="4" style="width: 220px;" data-original-image-url="/img/bigger/4.jpg"/>
</div>
<div class="item">
<img src="/img/5.jpg" title="5" style="width: 40px;" data-original-image-url="/img/bigger/5.jpg"/>
</div>
<div class="item">
<img src="/img/6.jpg" title="6" style="width: 80px;" data-original-image-url="/img/bigger/6.jpg"/>
</div>
<div class="item">
<img src="/img/7.jpg" title="7" style="width: 50px;" data-original-image-url="/img/bigger/7.jpg"/>
</div>
<div class="item">
<img src="/img/8.jpg" title="8" style="width: 50px;" data-original-image-url="/img/bigger/8.jpg"/>
</div>
<div class="item">
<img src="/img/9.jpg" title="9" style="width: 50px;" data-original-image-url="/img/bigger/9.jpg"/>
</div>
<div class="item">
<img src="/img/10.jpg" title="10" style="width: 50px;" data-original-image-url="/img/bigger/10.jpg"/>
</div>
<div class="item">
<img src="/img/11.jpg" title="11" style="width: 50px;" data-original-image-url="/img/bigger/11.jpg"/>
</div>
<div class="item">
<img src="/img/12.jpg" title="12" style="width: 50px;" data-original-image-url="/img/bigger/12.jpg"/>
</div>
<div class="item">
<img src="/img/13.jpg" title="13" style="width: 80px;" data-original-image-url="/img/bigger/13.jpg"/>
</div>
<div class="item">
<img src="/img/14.jpg" title="14" style="width: 150px;" data-original-image-url="/img/bigger/14.jpg"/>
</div>
</div>
Related
I'm working on a website which have multiply images. The user can click on this images and then it will show a tiny text under this one. My idea was to get the ID of the images and then show the text who correspond to this one.
Let me show you my code
function SOE() {
let bSOE = document.getElementById("bSOE");
let Soe = document.getElementById("SOE");
if (getComputedStyle(Soe).display != "none") {
Soe.style.display = "none";
} else {
var elements = document.getElementsByClassName("secret");
for (var i = 0; i < elements.length; i++) {
if (elements[i].id != "SOE") {
elements[i].style.display = "none";
}
}
Soe.style.display = "block";
}
}
<div class="mn_bo3">
<div class="map" id="bSOE" onclick="SOE()" style="background-image: url('source/Soe.png')"></div>
<div class="map" id="bTG" style="background-image: url('source/tg.png')"></div>
<div class="map" id="bDER" style="background-image: url('source/Der.png')"></div>
<div class="map" id="bZNS" style="background-image: url('source/Zns.png')"></div>
<div class="map" id="bGK" style="background-image: url('source/Gk.png')"></div>
</div>
<!--Tiny hidden text -->
<div class="secret" id="SOE" style="display:none;">
<p>Here are the list of the easter eggs of Shadow of Evil map :</p>
</div>
So I created a function but it's working only for one and it's not using this ID. I need some help or this code will be very DRY.
Thanks a lot for read that!
Check up on this code to see if it solve your issue.
function SOE(selector) {
$('p').fadeOut(500)
$('#'+selector+' > p').fadeIn(500)
}
.mn_bo3 {
height: 100vh;
display: flex;
justify-content: space-between;
}
.map {
height: 100px;
width: 100px;
background-repeat: no-repeat;
background-size: contain;
position: relative;
}
p {
position: absolute;
bottom: -2em;
left: 0;
right: 0;
text-align: center;
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="mn_bo3">
<div class="map" id="bSOE" onclick="SOE('bSOE')" style="background-image: url('1.png')">
<p>Text image 1</p>
</div>
<div class="map" id="bTG" onclick="SOE('bTG')" style="background-image: url('2.png')">
<p>Text image 2</p>
</div>
<div class="map" id="bDER" onclick="SOE('bDER')" style="background-image: url('3.png')">
<p>Text image 3</p>
</div>
<div class="map" id="bZNS" onclick="SOE('bZNS')" style="background-image: url('4.png')">
<p>Text image 4</p>
</div>
<div class="map" id="bGK" onclick="SOE('bGK')" style="background-image: url('1.png')">
<p>Text image 5</p>
</div>
</div>
You could pass the id of each div in the onClick function call, like this:
JS:
function SOE(id){
let bSOE = document.getElementById(id);
...
}
HTML:
<div class="map" id="bSOE" onclick="SOE('bSOE')" style="background-image: url('source/Soe.png')" ></div>
Or if its guaranteed, that every object has an ID you could get the id via the 'this' object (js stays the same):
<div class="map" id="bSOE" onclick="SOE(this.id)" style="background-image: url('source/Soe.png')" ></div>
After that you can create a object, which saves the image id with the text id:
var elements = { "BSOE": "SOE" }
And then display the corresponding text for each image:
function SOE (id) {
var elem = document.getElementById(elements[id]);
elem.style.display = "block";
You can create a common click handler for all images and show hidden text with receptive image.
So in this case your code structure will be as below
<div class="map" id="bSOE" onclick="onElementClick(this)" style="background-image: url(https://picsum.photos/200)"></div>
<div class="secret" id="bSOE_text">
<p>Here are the list of the easter eggs of Shadow of Evil map :</p>
</div>
Working Code
function onElementClick(event){
//Before showing div hide other's one
[...document.querySelectorAll('div.secret')].forEach(el => el.style.display = 'none');
//To show the repective div
document.querySelector('div#' + event.id + '_text').style.display = 'block';
}
.map {
height: 100px;
width: 100px;
background-size: cover;
order: 1px solid;
margin: 10px;
}
.secret {
display: none;
}
<div class="mn_bo3">
<div class="map" id="bSOE" onclick="onElementClick(this)" style="background-image: url(https://picsum.photos/200)" ></div>
<div class="secret" id="bSOE_text">
<p>Here are the list of the easter eggs of Shadow of Evil map :</p>
</div>
<div class="map" id="bTG" style="background-image: url(https://picsum.photos/200
)" onclick="onElementClick(this)"></div>
<div class="secret" id="bTG_text">
<p>Here are the list of the easter eggs of Shadow of Evil map :</p>
</div>
<div class="map" id="bDER" style="background-image: url(https://picsum.photos/200)" onclick="onElementClick(this)"></div>
<div class="secret" id="bDER_text">
<p>Here are the list of the easter eggs of Shadow of Evil map :</p>
</div>
<div class="map" id="bZNS" style="background-image: url(https://picsum.photos/200)" onclick="onElementClick(this)"></div>
<div class="secret" id="bZNS_text">
<p>Here are the list of the easter eggs of Shadow of Evil map :</p>
</div>
<div class="map" id="bGK" style="background-image: url(https://picsum.photos/200)" onclick="onElementClick(this)"></div>
<div class="secret" id="bGK_text">
<p>Here are the list of the easter eggs of Shadow of Evil map :</p>
</div>
</div>
When you insist on using Javascript functionality for other purposes regarding users clicking on your images, I suggest you check the other answers and take your pick.
When you are looking for a straightforward solution, you might want to investigate using a <details><summary> construction as these elements by default incorporate a click-an-show mechanism without the need for Javascript.
Have a look at this simple snippet:
/* [OPTIONAL], but makes sense in this case */
summary { list-style-type: none }
/* just extra eye-candy */
body { padding: 1rem; margin: 0; cursor: default }
summary { cursor: pointer }
<details>
<summary><img src="https://picsum.photos/360?random=1"></summary>
<p>some tiny text when the image gets clicked</p>
</details>
File manager = html container that contains a table-like list of files.
I have made a drop zone as big as the file manager instead of making a designated drop-zone.
I got inspired by this design:
https://www.youtube.com/watch?v=seXXWRygRkY
I only took the drop zone highlight idea from this video.
If you watch the video you will see that at 0:15 he goes over an element and the drop-zone blinks. This happens with my drop zone in A LOT of places.
My current file manager with div hierarchy :
<template>
<section
#dragover.prevent="dragOk = true"
#drop.prevent="addFile"
#drop.stop.prevent="dragOk = false"
#dragleave="dragOk = false"
>
<div class="top_container">
<div :class="`mid_container ${dragOk ? 'drag-ok' : ''}`">
<div class="title">
<h1>
File
<span>Manager</span>
</h1>
</div>
<!-- TODO: File Manager Component -->
<div v-cloak class="file-manager-container">
<div class="file-line header">
<div class="file-name">File name:</div>
<div class="file-size">Size:</div>
<div class="action-buttons">Actions:</div>
</div>
<div
:class="`file-line ${file.status ? 'wrong-file' : ''}`"
v-for="(file, index) in currentFiles"
:key="index"
>
<!-- left -->
<div class="file-name">
{{ file.name }}
<span v-if="file.status"> - {{ file.status }}</span>
</div>
<!-- middle -->
<div class="file-size">{{ file.size }} kb</div>
<!-- right -->
<div class="action-buttons">
<span>
<i class="far fa-edit"></i>
</span>
<span #click.prevent="currentFiles.splice(index, 1)">
<i class="fa fa-trash" aria-hidden="true"></i>
</span>
</div>
</div>
</div>
<!-- <span v-if="uploading" class="progress-bar">
<progress :value="progress" max="100">{{progress}}%</progress>
</span>-->
<div class="upload-message" v-if="message">
<div>{{ message }}</div>
</div>
</div>
</div>
</section>
</template>
<style scoped>
.drag-ok {
background: pink;
opacity: 0.5;
z-index: 100;
}
</style>
Issue:
If I drag items over some borders or text the dropzone blinks from pink to the default color. If I drop files when the dropzone isn't pink, the browser will open said file.
Here is a fiddle to ilustrate the problem: http://jsfiddle.net/m3wzbyoL/23/
You will have to select a file from your OS, drag it over the area and move it around there and you will see crazy flashes.
Adding pointer-events: none; to the .drop container will cancel every event from the child element and I do not want this.
If I add pointer-events: none; to .drop .highlight will make the drag events to not work.
Two things:
Ensure you are only toggling the drag-ok class on the dragenter and dragleave events. dragover will fire every few hundred milliseconds and is only for capturing events as you are dragging.
Disable pointer-events on all the children of the drop-zone target in CSS when the drag-ok class is active (not the drop-zone target itself). This will ensure that no other events from children will interfere while dragging.
Note: code provided as a minimal example, doesn't match code in question exactly..
$('.drop').on('dragenter', function(e) {
$(this).addClass('drag-ok');
})
.on('dragleave', function(e) {
$(this).removeClass('drag-ok');
})
.drop {
height: auto;
width: 200px;
background: #aaa;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.drop.drag-ok {
border: 2px dashed black;
background: black;
opacity: 0.5;
}
/**
* The important bit:
* disable pointer events on all children elements of
* the drop zone element *only* when the dragenter
* event has fired (.drag-ok is active)
*/
.drop.drag-ok * {
pointer-events: none;
}
.img {
height: 100px;
width: 100px;
background: red;
margin: 5px 0;
}
.img:hover {
background: pink;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div draggable="true">drag me</div>
<div class="drop">
<span>Drop here</span>
<div class="img"></div>
<div class="img"></div>
<div class="img"></div>
<div class="img"></div>
</div>
I would like to make changes to some pictures of my website when certain text is hovered. Specifically, when h6 inside section, inside a parent row class is hovered, I want the images inside a, inside section, inside parent with row class to get greyscaled.
I read in other threads that you could affect siblings and parents in different ways and I tried the suggested approaches but none of them worked (it may be because I am not fully understanding how it is done).
Here is some pseudo-code that explains what I want to do. Of course, it is not working because such nesting is impossible.
.row > section > h6:hover {
.row > section > a > img {
filter: grayscale(100%);
}
}
I would like to ask if what I am trying to do is possible and if so, how? A solution using JavaScript would also be accepted, but preferably only using CSS if possible.
Edit: Here is a quick fiddle: https://jsfiddle.net/pjo4yxLk/2/
I want that when I hover Field1 and Field 2, both pictures to get greyscaled.
For a pure CSS solution it can be done for each image by switching the place of the h6 and a in the html and putting them back in place visualy with display: flex; flex-direction: row-reverse;.
This way your code work.
section {
display: flex;
flex-direction: column-reverse;
}
.row > section > h6:hover + a > img {
filter: grayscale(100%);
}
.row {
/* just to align them in a row */
display: flex;
}
h6 {
font-size: 16px;
}
section {
display: flex;
flex-direction: column-reverse;
}
.row>section>h6:hover+a>img {
filter: grayscale(100%);
}
<div class="row container">
<section>
<h6>
Field 1
</h6>
<a href="https://www.google.com/">
<img src="https://helpx.adobe.com/content/dam/help/en/stock/how-to/visual-reverse-image-search/jcr_content/main-pars/image/visual-reverse-image-search-v2_intro.jpg" style="width: 150px;">
</a>
</section>
<section>
<h6>
Field 2
</h6>
<a href="https://www.google.com/">
<img src="https://helpx.adobe.com/content/dam/help/en/stock/how-to/visual-reverse-image-search/jcr_content/main-pars/image/visual-reverse-image-search-v2_intro.jpg" style="width: 150px;">
</a>
</section>
</div>
But if you want both images to get grayscaled when one h6 is hovered then I think you will need JS.
CSS
.row {
display: flex;
}
.grayScaler {
filter: grayscale(100%);
}
JS
var theH6s = document.querySelectorAll(".row > section > h6");
var theImages = document.querySelectorAll("section > a > img");
function grayScaler () {
for(let i = 0; i < theImages.length ; i++) {
theImages[i].classList.toggle("grayScaler");
}
}
for(let i = 0; i < theH6s.length ; i++) {
theH6s[i].addEventListener("mouseenter",grayScaler);
theH6s[i].addEventListener("mouseleave",grayScaler);
}
var theH6s = document.querySelectorAll(".row > section > h6");
var theImages = document.querySelectorAll("section > a > img");
function grayScaler() {
for (let i = 0; i < theImages.length; i++) {
theImages[i].classList.toggle("grayScaler");
}
}
for (let i = 0; i < theH6s.length; i++) {
theH6s[i].addEventListener("mouseenter", grayScaler);
theH6s[i].addEventListener("mouseleave", grayScaler);
}
h6 {
font-size: 20px;
}
.row {
display: flex;
}
.grayScaler {
filter: grayscale(100%);
}
<!--
Bootstrap docs: https://getbootstrap.com/docs
-->
<div class="row container">
<section>
<a href="https://www.google.com/">
<img src="https://helpx.adobe.com/content/dam/help/en/stock/how-to/visual-reverse-image-search/jcr_content/main-pars/image/visual-reverse-image-search-v2_intro.jpg" style="width: 150px;">
</a>
<h6>
Field 1
</h6>
</section>
<section>
<a href="https://www.google.com/">
<img src="https://helpx.adobe.com/content/dam/help/en/stock/how-to/visual-reverse-image-search/jcr_content/main-pars/image/visual-reverse-image-search-v2_intro.jpg" style="width: 150px;">
</a>
<h6>
Field 2
</h6>
</section>
</div>
That's not the proper syntax. If H6 and A tag are inside section tag, it would be like this:
.row > section > h6:hover + a > img { filter: grayscale(100%); }
Since A tag is H6 tag's next sibling, you have to use + selector to call it.
You cannot do this unless your :hover element comes before your modified element.
It can be achieved with pure CSS if you use CSS to position the text below the image but I wouldn't advise it. You can alternatively use javascript to achieve this.
Refer to this answer: On a CSS hover event, can I change another div's styling?
I have attached code to show you what I mean
.row > section > h6:hover + a > img{
filter: grayscale(100%);
}
<!--
Bootstrap docs: https://getbootstrap.com/docs
-->
<div class="row container">
<section>
<h6>
Field 1
</h6>
<a href="https://www.google.com/">
<img src="https://helpx.adobe.com/content/dam/help/en/stock/how-to/visual-reverse-image-search/jcr_content/main-pars/image/visual-reverse-image-search-v2_intro.jpg" style="width: 150px;">
</a>
</section>
<section>
<a href="https://www.google.com/">
<img src="https://helpx.adobe.com/content/dam/help/en/stock/how-to/visual-reverse-image-search/jcr_content/main-pars/image/visual-reverse-image-search-v2_intro.jpg" style="width: 150px;">
</a>
<h6>
Field 2
</h6>
</section>
</div>
I am new to stackoverflow and can't seem to find an answer to my issue - please put link to similar question if I missed it, but I have gave it a strong gander already.
I am making a portfolio site and when a user clicks a project, the clicked div slides out and the bottom div is revealed with the project case study.
The problem: When user scrolls down to project thumbs on sliding div, the lower div scrolls with it - therefore when the user clicks the project, the case study is already scrolled down. I need it to reveal with the case study at scrolltop(0)
Here is a simplified version of what I have so you can get an idea:
// View Project Details (user clicks thumbnail from LP) CTA function
$(".projThumb").click(function()
{
$("#nav-icon3").toggleClass('open');
$(".projDetails").fadeIn( 500 );
// $('.lowerContainer').css('position','absolute');
$('.mainContentWrap').openSlide();
var id = $(this).attr('id');
if(id == 'Proj1')
{
$("#Proj1_Details").fadeIn( 500 );
//get persona image height so background shape is proportional
var personaImgHeight = parseInt($("#personaImg1").height());
$(".containImg").css("height", personaImgHeight + "px");
$(".personaImgWrap").css("height", personaImgHeight + "px");
} else if (id == 'Proj2') {
$("#Proj2_Details").fadeIn( 500 );
//get persona image height so background shape is proportional
var personaImgHeight = parseInt($("#personaImg2").height());
$(".containImg").css("height", personaImgHeight + "px");
$(".personaImgWrap").css("height", personaImgHeight + "px");
} else if (id == 'Proj3') {
$("#Proj3_Details").fadeIn( 500 );
//get persona image height so background shape is proportional
var personaImgHeight = parseInt($("#personaImg3").height());
$(".containImg").css("height", personaImgHeight + "px");
$(".personaImgWrap").css("height", personaImgHeight + "px");
} else if (id == 'Proj4') {
$("#Proj4_Details").fadeIn( 500 );
};
});
.lowerContainer
{
width:80%;
max-width: 2050px;
height: auto;
min-height:100vh;
margin:0 auto;
background:#f9f9f9;
position: relative;
/*left:10%;*/
}
.revealPanel
{
width: 100%;
min-height:100vh;
float: left;
margin-top:0;
overflow-y:scroll;
padding:0;
/*position: fixed;*/
}
.mainContent
{
width:80%;
max-width: 2050px;
height:auto;
top:0px;
left: 0px;
right: 0;
margin-top: 0;
margin-right:auto;
margin-bottom:0;
margin-left:auto;
position: absolute;
z-index: 1000;
overflow-x: hidden;
overflow-y: scroll;
opacity: 1;
}
.mainContentWrap
{
width:100%;
overflow:auto;
}
<div class="lowerContainer group">
<section class="revealPanel group">
<!-- ******************************
PROJECT CASE STUDY GOES HERE
******************************** -->
</section> <!-- /revealPanel -->
</div> <!-- /lowerContainer -->
<div class="mainContent">
<div class="mainContentWrap">
<!-- ******************************
MY WORK SECTION
******************************** -->
<div class="myWork group">
<!-- Project container (Contains project thumbnails ) -->
<div class="projContainer">
<h3 class="secTitle">Recent Work</h3>
<div class="projectsWrap">
<div class="row">
<!-- Project 1 -->
<div class="projects col-lg-6 col-md-12">
<div class="projThumb" id="Proj1">
<img src="assets/proj1.png" width="100%" alt="">
</div>
</div>
<!-- Project 2 -->
<div class="projects col-lg-6 col-md-12">
<div class="projThumb" id="Proj2">
<img src="assets/proj2.png" width="100%" alt="">
</div>
</div>
<!-- Project 3 -->
<div class="projects col-lg-6 col-md-12">
<div class="projThumb" id="Proj3">
<img src="assets/proj3.png" width="100%" alt="">
</div>
</div>
<!-- Project 4 -->
<div class="projects col-lg-6 col-md-12">
<div class="projThumb" id="Proj4">
<img src="assets/proj4.png" width="100%" alt="">
</div>
</div>
</div> <!-- /row -->
</div> <!-- /projectWrap -->
</div> <!-- projectsWrap -->
<!-- <div class="triBg" id="triBg-myWork"></div> -->
</div> <!-- /myWork -->
</div>
</div> <!-- /mainContent -->
Based on what you said you want to happen, without really looking at your massive amount of code, I think you are over complicating this.
You can make use of jQuery's .slideToggle() http://api.jquery.com/slidetoggle/
You can also utilize the fact that you can have multiple elements with the same class to help minimize the amount of repeated code.
$(document).on('click', '.projectButton', function(){
$(this).siblings('.projectInfo').slideToggle();
});
.projectInfo {
display: none;
}
.projectButton {
height: 25px;
background: gray;
cursor: pointer;
border: 1px solid white;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="projectsContainer">
<div class="project" id="project1">
<div class="projectButton">Project 1</div>
<div class="projectInfo">Project 1 information goes here</div>
</div>
<div class="project" id="project2">
<div class="projectButton">Project 2</div>
<div class="projectInfo">Project 2 information goes here</div>
</div>
<div class="project" id="project3">
<div class="projectButton">Project 3</div>
<div class="projectInfo">Project 3 information goes here</div>
</div>
<div class="project" id="project4">
<div class="projectButton">Project 4</div>
<div class="projectInfo">Project 4 information goes here</div>
</div>
</div>
I am currently working with jsPlumb & got stuck at saving & loading the containers. I figured out how to save the endpoints, connections & positions.
But I can't figure out, how to save the div containers, including their attributes, children & the children's attrubites.
Here's a snippet of the containers, any ideas how to stringify them?
<div class="window main node ui-draggable _jsPlumb_endpoint_anchor_" id="maincontainer1" data-nodetype="main" style="left: 663px; top: 200px; width: 230px; height: 200px;">
<div class="ctrl_container">
<div class="button_rm">x</div>
</div>
<div class="layer" id="layercontainer1_1" style="height: 80px; width: 100%; background: none repeat scroll 0% 0% transparent;">
<div class="window filter node" style="left:25px; top:5px;" name="3#2#ABC#" id="filtercontainer2_1_1">
<div class="ctrl_container">
<a class="filter_caption edit" href="#">Edit</a>
<div class="button_rm">x</div>
</div>
<div class="details_container">
<span id="filter_label" class="filter_label jtextfill" style="font-size: 22px;">PrimarySupportGrp = 123</span>
</div>
</div>
</div>
<div class="layer" id="layercontainer1_2" style="height: 90px; width: 100%; background: none repeat scroll 0% 0% rgba(0, 255, 255, 0.4);"><div class="line-separator"></div>
<div class="window filter node" style="left:25px; top:5px;" name="5#4#Yes#" id="filtercontainer2_2_1">
<div class="ctrl_container">
<a class="filter_caption edit" href="#">Edit</a>
<div class="button_rm">x</div>
</div>
<div style="" class="details_container">
<span id="filter_label" class="filter_label jtextfill" style="font-size: 14px;"> Site > Yes</span>
</div>
</div>
</div>
</div>
I don't suggest saving the complete children hierarchy, but if you want - why not use .html()
var data = [];
$(".layer").each(function(){
var html = $(this).html();
data.push(html);
});
OR
Just save what is required to re-render them at the correct position - left, top etc.
for(var i=0 ; i<length; i++){
var layerTemplate = "...div template html goes here";
var $layerTemplate = $(layerTemplate);
$layerTemplate.css({top : data[i].top , left : data[i].left});
$("#maincontainer1").append($layerTemplate);
}
Some time back I wrote a script for saving & re-rendering jsPlumb - https://github.com/nitinsurana/jsPlumb-Persistence