I have problem that I need help with
I put a simple exemple of my code from w3schools to make it more simple.
I have a tab gallary with 4 images, that you can click on an image so it will get viewed bigger under.
This thing is working with onclick function.
What I want is to make the onclick= none until a condition happened (if text is contains something in this exemple.
I made the image onclick = none and the condition to be true so the myFunction(this). In other word to make the image clickable to get viewed under, but this is not working.
Sorry for my bad explanation,check the code and you will get it fast.
I just want to be able to activate the clicking on the image when a condition is true.
function myFunction(imgs) {
var expandImg = document.getElementById("expandedImg");
var imgText = document.getElementById("imgtext");
expandImg.src = imgs.src;
imgText.innerHTML = imgs.alt;
expandImg.parentElement.style.display = "block";
}
var mytextvar= document.getElementById("mytext").textContent
if(mytextvar == "keyboard"){
document.getElementById("mytext").onclick = "myFunction(this);"
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial;
}
/* The grid: Four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
padding: 10px;
}
/* Style the images inside the grid */
.column img {
opacity: 0.8;
cursor: pointer;
}
.column img:hover {
opacity: 1;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* The expanding image container */
.container {
position: relative;
display: none;
}
/* Expanding image text */
#imgtext {
position: absolute;
bottom: 15px;
left: 15px;
color: white;
font-size: 20px;
}
/* Closable button inside the expanded image */
.closebtn {
position: absolute;
top: 10px;
right: 15px;
color: white;
font-size: 35px;
cursor: pointer;
}
<!-- The four columns -->
<p id="mytext">keyboard</p>
<div class="row">
<div class="column">
<img src="https://picsum.photos/200" alt="Nature" style="width:100%" onclick="myFunction(this);">
</div>
<div class="column">
<img src="https://picsum.photos/201" alt="Snow" style="width:100%" onclick="">
</div>
<div class="column">
<img src="https://picsum.photos/202" alt="Mountains" style="width:100%" onclick="myFunction(this);">
</div>
<div class="column">
<img src="https://picsum.photos/204" alt="Lights" style="width:100%" onclick="myFunction(this);">
</div>
</div>
<div class="container">
<span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
<img id="expandedImg" style="width:100%">
<div id="imgtext"></div>
</div>
function showImage(sourceImg) {
var expandImg = document.getElementById("expandedImg");
var imgText = document.getElementById("imgtext");
expandImg.src = sourceImg.src;
imgText.innerHTML = sourceImg.alt;
expandImg.parentElement.style.display = "block";
}
var imgs = document.querySelectorAll(".img-cls");
imgs.forEach((img) => {
img.addEventListener('click', function(event) {
checkStatus(this);
});
});
function doImgAction(source, type) {
if (source.classList.contains(type)) {
showImage(source);
} else {
alert("You don't have enough credits to perform this action!");
}
}
function checkStatus(source) {
var mytextvar = document.getElementById("mytext");
var myText = mytextvar.textContent.toLowerCase();
switch (myText) {
case "sliver":
{
doImgAction(source, 'sliver');
break;
}
case "gold":
{
doImgAction(source, 'gold');
break;
}
case "diamond":
{
doImgAction(source, 'diamond');
break;
}
default:
{
return;
}
}
}
You are using a conditional for adding an onclick event:
if(mytextvar == "keyboard"){
document.getElementById("mytext").onclick = "myFunction(this);"
}
However, when the condition mytextvar == "keyboard" is true, the event will be added and then it would never be deactivated, because you never deactivate it in the code.
What you can do is to move the conditional inside the function, so js would check the conditional every time an image is clicked, and then the code would be executed or not depending on the condition
function myFunction(imgs) {
var mytextvar= document.getElementById("mytext").textContent
// If condition is false, return of the function
if(mytextvar != "keyboard")
return;
var expandImg = document.getElementById("expandedImg");
var imgText = document.getElementById("imgtext");
expandImg.src = imgs.src;
imgText.innerHTML = imgs.alt;
expandImg.parentElement.style.display = "block";
}
document.getElementById("mytext").onclick = "myFunction(this);"
Note: the event would always be executed, but you return early if the condition is false
Related
I want to add recursive filters using simple HTML buttons/javascript. Till now, i have only been able to add one level of filter. What i want to do is - allow the user to select the filter in 2 stages. For example, user should be able to filter on experience range "10+" and then further filter on next stage such as "Operations". So this way only profiles that fit 10+ experience and Operations are shown.
I have been able to add filter and logic for one stage. That is, the code works and filters on experience range (5-8, 8-10, 10+), but unable to implement the second stage of filter (IT, Operations etc.)
filterSelection("all")
function filterSelection(c) {
var x, i;
x = document.getElementsByClassName("column");
if (c == "all") c = "";
for (i = 0; i < x.length; i++) {
w3RemoveClass(x[i], "show");
if (x[i].className.indexOf(c) > -1) w3AddClass(x[i], "show");
}
}
function w3AddClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {
element.className += " " + arr2[i];
}
}
}
function w3RemoveClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
}
// Add active class to the current button (highlight it)
var btnContainer = document.getElementById("myBtnContainer");
var btns = btnContainer.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
var current = document.getElementsByClassName("active");
current[0].className = current[0].className.replace(" active", "");
this.className += " active";
});
}
* {
box-sizing: border-box;
}
body {
background-color: #f1f1f1;
padding: 20px;
font-family: Arial;
}
/* Center website */
.main {
max-width: 1000px;
margin: auto;
}
h1 {
font-size: 50px;
word-break: break-all;
}
.row {
margin: 8px -16px;
}
/* Add padding BETWEEN each column */
.row,
.row>.column {
padding: 8px;
}
/* Create four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
display: none;
/* Hide all elements by default */
}
/* Clear floats after rows */
.row:after {
content: "";
display: table;
clear: both;
}
/* Content */
.content {
background-color: white;
padding: 10px;
}
/* The "show" class is added to the filtered elements */
.show {
display: block;
}
/* Style the buttons */
.btn {
border: none;
outline: none;
padding: 12px 16px;
background-color: white;
cursor: pointer;
}
.btn:hover {
background-color: #ddd;
}
.btn.active {
background-color: #666;
color: white;
}
/* Responsive layout - makes a two column-layout instead of four columns */
#media screen and (max-width: 900px) {
.column {
width: 50%;
}
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 600px) {
.column {
width: 100%;
}
}
<!-- MAIN (Center website) -->
<div class="main">
<div id="myBtnContainer">
<button class="btn active" onclick="filterSelection('all')"> Show all</button>
<button class="btn" onclick="filterSelection('5-8')"> 5-8</button>
<button class="btn" onclick="filterSelection('8-10')"> 8-10</button>
<button class="btn" onclick="filterSelection('10+')"> 10+</button>
</div>
<div id="myBtnContainer">
<button class="btn" onclick="filterSelection('Operations')"> Operations</button>
<button class="btn" onclick="filterSelection('Manufacturing')"> Manufacturing</button>
</div>
<!-- Portfolio Gallery Grid -->
<div class="row">
<div class="column 8-10">
<div class="content">
<a href="https://xxx" target="_blank">
<img src="https:xxx" alt="Bagish" style="width:100%" ;height:auto;>
<h4>abc</h4>
<p>8+ Experience in Oil&Gas, Manufacturing</p>
</div>
</div>
<div class="column 10+">
<div class="content">
<a href="https://xxx">
<img src="xxx" alt="def" style="width:100%" ;height:auto;>
<h4>def</h4>
<p>10+ Experience in Oil&Gas, Manufacturing</p>
</div>
</div>
<div class="column 10+">
<div class="content">
<a href="https://abc">
<img src="abc" ;height:auto;>
<h4>ghi</h4>
<p>13+ Experience in IT Program Management</p>
</div>
</div>
<!-- END GRID -->
</div>
<!-- END MAIN -->
</div>
Please help me add another level of filter for IT/Operations etc.
A bit adjusted and simplified, but suppose works as you wanted ;-)
In case you are happy, mind pressing accept button (under voting).
var filtersList = {};
filterSelection(document.getElementsByName("myBtnContainer")[0].children[0]);
function renameAll(i) {
return i.replace('Show all', 'all');
}
function filterSelection(current) {
var x, i;
var c = renameAll(current.innerText.trim());
var buttons = document.getElementsByName("myBtnContainer");
var group = current;
do {
group = group.parentElement;
if (group.getAttribute("name") == "myBtnContainer") {
for (i = 0;i<buttons.length;i++) {
if (buttons[i] === group) {
group = i + 1;
break;
}
}
break;
}
} while (true);
var has = filtersList[c];
if (!has) {
if (filtersList.all && group == 1) filtersList = {};
if (c == 'all') filtersList = { all:1 }
else filtersList[c] = group;
} else {
delete filtersList[c];
if (c == 'all') filtersList = {};
}
var records = document.getElementsByClassName("column");
var matched = 0, filtersNo = [null,null];
updateButtons(buttons, filtersNo);
for (i = 0; i < records.length; i++) {
w3RemoveClass(records[i], "show");
var matchedFilters = [0,0];
for(var c1 in filtersList) {
var group = filtersList[c1]-1;
if (c1 == "all") c1 = "";
if (records[i].className.indexOf(c1) > -1) {
matchedFilters[group]++;
}
}
// Display trick here 2 binary numbers or logic table - each bit means non-zero number in group (matched > 0 / selected filter > 0) - hope works properly ;-)
var matched = (!!matchedFilters[0]) + (!!matchedFilters[1])*2;
var filters = (!!filtersNo[0]) + (!!filtersNo[1])*2;
if ((matched & filters) == filters && (filters != 0)) {
w3AddClass(records[i], "show");
}
}
updateButtons(buttons, filtersNo);
}
function updateButtons(buttons, filtersNo) {
filtersNo[0] = 0;
filtersNo[1] = 0;
for (i = 0;i<buttons.length;i++) {
if (i && !filtersNo[0]) filtersList = {};
for (var j = 0;j<buttons[i].children.length;j++) {
var el = buttons[i].children[j];
c = renameAll(el.innerHTML.trim());
if (filtersList[c]) {
filtersNo[i]++;
if (el.className.indexOf("active") < 0) el.className += " active";
} else {
el.className = el.className.replace(/[ ]*active[ ]*/,'');
}
}
}
if (filtersNo[0]) {
buttons[1].style.display = "";
} else {
buttons[1].style.display = "none";
}
}
function w3AddClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {
element.className += " " + arr2[i];
}
}
}
function w3RemoveClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
}
* {
box-sizing: border-box;
}
body {
background-color: #f1f1f1;
padding: 20px;
font-family: Arial;
}
/* Center website */
.main {
max-width: 1000px;
margin: auto;
}
h1 {
font-size: 50px;
word-break: break-all;
}
.row {
margin: 8px -16px;
}
/* Add padding BETWEEN each column */
.row,
.row>.column {
padding: 8px;
}
/* Create four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
display: none;
/* Hide all elements by default */
}
/* Clear floats after rows */
.row:after {
content: "";
display: table;
clear: both;
}
/* Content */
.content {
background-color: white;
padding: 10px;
}
/* The "show" class is added to the filtered elements */
.show {
display: block;
}
/* Style the buttons */
.btn {
border: none;
outline: none;
padding: 12px 16px;
background-color: white;
cursor: pointer;
}
.btn:hover {
background-color: #ddd;
}
.btn.active {
background-color: #666;
color: white;
}
/* Responsive layout - makes a two column-layout instead of four columns */
#media screen and (max-width: 900px) {
.column {
width: 50%;
}
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 600px) {
.column {
width: 100%;
}
}
<div class="main">
<div name="myBtnContainer">
<button class="btn" onclick="filterSelection(this)"> Show all</button>
<button class="btn" onclick="filterSelection(this)"> 5-8</button>
<button class="btn" onclick="filterSelection(this)"> 8-10</button>
<button class="btn" onclick="filterSelection(this)"> 10+</button>
</div>
<div name="myBtnContainer" style="display: none">
<button class="btn" onclick="filterSelection(this)"> Operations</button>
<button class="btn" onclick="filterSelection(this)"> Manufacturing</button>
</div>
<!-- Portfolio Gallery Grid -->
<div class="row">
<div class="column 8-10 Operations">
<div class="content">
<a href="https://mbaex2020.co/batchprofiledetails#7839de77-db6d-4c0e-9072-d60fb35d09c9" target="_blank">
<img src="https://img1.wsimg.com/isteam/ip/97d4b213-5779-4c13-95cf-100a6b778fe3/Bagish.jpg/:/rs=w:600,h:750,cg:true,m/cr=w:1200,h:750,a:cc" alt="Bagish" style="width:100%" ;height:auto;>
<h4>Bagish</h4>
<p>8+ Experience in Oil&Gas, Manufacturing</p>
</div>
</div>
<div class="column 10+ Operations">
<div class="content">
<a href="https://mbaex2020.co/batchprofiledetails#c55a69ed-2170-41cf-b71d-e6546bb77c14" target="_blank">
<img src="https://img1.wsimg.com/isteam/ip/97d4b213-5779-4c13-95cf-100a6b778fe3/Rahul.jpg/:/rs=w:600,h:750,cg:true,m/cr=w:1200,h:750,a:cc" alt="Rahul" style="width:100%" ;height:auto;>
<h4>Rahul</h4>
<p>10+ Experience in Oil&Gas, Manufacturing</p>
</div>
</div>
<div class="column 10+">
<div class="content">
<a href="https://mbaex2020.co/batchprofiledetails#c26922ff-3ee8-4d1e-92bf-974f46061d40" target="_blank">
<img src="https://img1.wsimg.com/isteam/ip/97d4b213-5779-4c13-95cf-100a6b778fe3/Nikhil.jpg/:/rs=w:600,h:750,cg:true,m/cr=w:1200,h:750,a:cc" alt="Nikhil" style="width:100%" ;height:auto;>
<h4>Nikhil</h4>
<p>13+ Experience in IT Program Management</p>
</div>
</div>
<!-- END GRID -->
</div>
<!-- END MAIN -->
</div>
Hey I'm trying to make a function that fills an empty container of a slideshow with images, with each image being contained in it's own div.
My webpage have an undetermined amount of modal images which , when clicked, open a slideshow album of images. I got this working for 1 image then realized that to have it work for an undetermined amount of slideshows of undetermined size I should make a function that fills the slideshow div. I planned to have each modal image to have a data attribute of "1,2,3...etc" and have a bunch an array with multiple objects each named similarly "1,2,3...etc" then I'd use this information to create and append the correct divs and images to the slideshow container. I will post what I want the slideshow container div to look like, my existing code, and a fiddle of what is supposed to happen. I am new to javascript and appreciate the help. I'm not certain what I've done incorrectly here, and If I haven't explained well enough then I will add more.
Edit:
I have noticed that in my modal image, if in the onClick I put fillSlides first, the other two functions won't work (or won't be called), but if I put it at the end it opens an empty slideshow. I don't get why.
https://jsfiddle.net/nhk3o0m1/26/
Current HTML:
<body >
<h2 id="title" style="text-align:center">hellkkko</h2>
<div class="row">
<div class="column">
<img id="modal-1" src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg" style="max-width:100%" data-modal="1" onclick="openModal();currentSlide(1); fillSlides(this);" class="hover-shadow cursor">
</div>
</div>
<div id="myModal" class="modal">
<span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content">
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
</div>
What I want my .modal-content div to look like after the function runs:
<div class="modal-content">
<div class="mySlides">
<img src="Images/LS_01.jpg" class="img">
</div>
<div class="mySlides">
<img src="Images/LS_02.jpg" class="img">
</div>
<div class="mySlides">
<img src="Images/LS_03.jpg" class="img">
</div>
<div class="mySlides">
<img src="Images/LS_04.jpg" class="img">
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
Javascript:
function fillSlides(modalID) {
var container = document.getElementsByClassName("modal-content");
var slides = {
"1": ["Images/LS_01.jpg", "Images/LS_02.jpg", "Images/LS_03.jpg", "Images/LS_04.jpg"],
"2": ["Images/LS_05.jpg", "Images/LS_06.jpg", "Images/LS_07.jpg", "Images/LS_08.jpg"],
"3": ["Images/LS_09.jpg", "Images/LS_10.jpg", "Images/LS_11.jpg", "Images/LS_12.jpg"]
};
var modal_num = modalID.getAttribute('data-modal');
for (var i = slides[modal_num].length; i > 0; i--) {
var the_divs = document.createElement('div');
var s_img = document.createElement('img');
the_divs.className = 'mySlides';
s_img.src = slides[modal_num][i];
the_divs.appendChild(s_img);
container.appendChild(the_divs);
}
}
<h2 id="title" style="text-align:center">hellkkko</h2>
<div class="row">
<div class="column">
<img id="modal-1" src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg" style="max-width:100%" data-modal="1" onclick="openModal();currentSlide(1); fillSlides(this);" class="hover-shadow cursor">
</div>
</div>
<div id="myModal" class="modal">
<span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content">
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
</div>
Added a function that generates slides on the fly. There are no slides in HTML and arrow controls are in #content. You gave no details on how album exists so I made a thumbnail for 2 extra albums. Also, there's a solution to your problem concerning the removal of everything with the arrows being the exception. The CSS is a little wonky but I'm sure you can rectify it easily enough.
Details commented in demo
Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
<title></title>
<style>
html,
body {
height: 100%;
width: 100%
}
body {
font-family: Verdana, sans-serif;
margin: 0;
}
* {
box-sizing: border-box;
}
.img {
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
object-fit: contain;
}
.row {
display:flex;
justify-content:space-between;
}
.column {
width: 25%;
padding: 0 8px;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: scroll;
background: rgba(0, 0, 0, 0.9);
}
/* Modal Content */
.modal-content {
position: relative;
background-color: rgba(0, 0, 0, 0.9);
margin: auto;
padding: 0;
width: 100%;
max-width: 1200px;
}
/* The Close Button */
.close {
color: white;
position: absolute;
top: 10px;
right: 25px;
font-size: 35px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #999;
text-decoration: none;
cursor: pointer;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -50px;
color: white;
font-weight: bold;
font-size: 20px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
text-decoration: none;
}
/* Number text (1/3 etc) */
.nth {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
right: 0;
}
img {
margin-bottom: -4px;
cursor: pointer
}
img.hover-shadow {
transition: all .2s ease-in-out;
}
.hover-shadow:hover {
transform: scale(1.1);
}
.modal-content {
-webkit-animation-name: zoom;
-webkit-animation-duration: 0.6s;
animation-name: zoom;
animation-duration: 0.6s;
}
#-webkit-keyframes zoom {
from {
-webkit-transform: scale(0)
}
to {
-webkit-transform: scale(1)
}
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
.slide img {
display: block;
height: 100%;
margin: 0 auto;
margin-bottom: 50px;
}
.slide {
text-align: center;
height: 80vh;
display: none;
}
.cap {
font-size: 1.5em;
background: rgba(0, 0, 0, .4);
position: absolute;
z-index: 2;
left: 0;
top: 0;
right: 0;
text-align: center;
color: #fff
}
.act {
display: block
}
</style>
</head>
<body>
<header>
<div class="row">
<div class="column"> <img src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg"
style="max-width:100%" onclick="album(img0, cap0);openModal();"
class="hover-shadow"> </div>
<div class="column"> <img src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg"
style="max-width:100%" onclick="album(img1, cap1);openModal();"
class="hover-shadow"> </div>
<div class="column"> <img src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg"
style="max-width:100%" onclick="album(img2, cap2);openModal();"
class="hover-shadow"> </div>
</div>
</header>
<section id="box">
<div id="xModal" class="modal"> <span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content" id='content'> <a class="prev" onclick="plusSlides(-1)">❮</a> <a class="next"
onclick="plusSlides(1)">❯</a> </div>
</div>
</section>
<footer> </footer>
<script>
/* 3 arrays are required:
|= 1. An array of strings.
|| Each represents a src of an image
|= 2. An array of strings. Each represents the
|| text of a figcaption
|= 3. An empty array
|| For each additional album add #1 and #2, #3
|| is emptied and reused at the beginning of
|| a new cycle.
*/
// Album 0
var img0 = [
"http://www.catholicevangelism.org/wp-content/uploads/2013/06/1200x800.gif",
"http://chasingseals.com/wp-content/uploads/2014/02/greenlandBanner2000x800.jpg",
"http://www.a1carpet-to.com/wp-content/uploads/2015/08/600x400.png",
"https://support.kickofflabs.com/wp-content/uploads/2016/06/800x1200.png"
];
var cap0 = ['caption1', 'caption2', 'caption3', 'caption4'];
// Album 1
var img1 = [
'https://d3i6fh83elv35t.cloudfront.net/newshour/app/uploads/2016/05/729665main_A-BlackHoleArt-pia16695_full-1024x576.jpg',
'http://cdn.newsapi.com.au/image/v1/85fb305132eb20ebbb01af386983c8a1',
'http://science.nationalgeographic.com/staticfiles/NGS/Shared/StaticFiles/Science/Images/Content/neptune-pia01492-ga.jpg',
'https://cdn.spacetelescope.org/archives/images/wallpaper1/heic1509a.jpg',
'https://i.giphy.com/media/JCUyexH8Zaf8k/giphy.webp'
];
var cap1 = ['Title I', 'Title II', 'Title III', 'Title IV',
'Title V'
];
// Album 2
var img2 = [
'https://i.ytimg.com/vi/YeQnLnRvZ9Y/maxresdefault.jpg',
'https://www.thesun.co.uk/wp-content/uploads/2017/08/nintchdbpict000319076839.jpg?strip=all&w=960',
'https://i0.wp.com/www.sketchysloth.com/wp-content/uploads/2016/07/Legendary-Hanging-Garden-Of-Babylon.jpg?fit=710%2C495&ssl=1',
'https://i.ytimg.com/vi/YoRvJcgSDE4/maxresdefault.jpg',
'https://www.realmofhistory.com/wp-content/uploads/2017/01/mausoleum-at-halicarnassus-restored_1.jpg',
'http://www.ancient-origins.net/sites/default/files/field/image/statue-of-Zeus-Olympia.jpg',
'https://i.ytimg.com/vi/F2yYkbinGnc/maxresdefault.jpg'
];
var cap2 = ['Colossus of Rhodes', 'Great Pyramid of Giza',
'Hanging Gardens of Babylon', 'Lighthouse of Alexandria',
'Mausoleum at Halicarnassus', 'Statue of Zeus at Olympia',
'Temple of Artemis at Ephesus'
];
// Declare a empty array
var data = [];
// Declare some counters outside of loop (or inside of loop using let)
var i, b, x;
// Reference the node that will contain the slides
var con = document.getElementById('content');
/* On each iteration...
|= Empty the data array
|= Create an object...
|| add a value from img[] to the src property
|| add a value from cap[] to the cap property
|| add the current value of index +1 to pos property
|| push the object into data array
*/
// Get the total length of data array
// Call genSlides()
function album(img, cap) {
data.length = 0;
for (i = 0; i < img.length; i++) {
var ele = new Object;
ele.src = img[i];
ele.cap = cap[i];
ele.pos = i + 1;
data.push(ele);
}
var qty = data.length;
genSlides(qty)
}
console.log(data);
/* Pass qty through...
|= On each iteration...
|= Create a documentFragment
|| it will allow us to append new elements to
|| it while still not in the DOM
|| which is faster because tasks within the DOM
|| are slow for the browser in comparison.
|= Notice that the data array is being used
|| to assign unique values.
*/
function genSlides(qty) {
for (b = 0; b < qty; b++) {
var frag = document.createDocumentFragment();
var slide = document.createElement('figure');
slide.id = 's' + b;
slide.className = 'slide';
var cap = document.createElement('figcaption');
cap.className = 'cap';
cap.textContent = data[b].cap;
var img = document.createElement('img');
img.classsName = 'img';
img.src = data[b].src;
var nth = document.createElement('b');
nth.className = 'nth';
nth.textContent = data[b].pos + '/' + data.length;
slide.appendChild(cap);
cap.appendChild(nth);
slide.appendChild(img);
frag.appendChild(slide);
con.appendChild(frag);
}
return false;
}
/* To avoid redundancy call sub functions within an initiating function
|| currentSlide() should start at 0, remember that all indexes by
|| default start at 0 and that the last index is .length - 1
|| showSlides() has ben corrected.
*/
function openModal() {
document.getElementById('xModal').style.display = "block";
showSlides(slideIndex);
currentSlide(0);
}
/* To remove what's in #content with the exception of the arrows we
|| gather all .slides in a NodeList and use a loop to remove them.
*/
function closeModal() {
document.getElementById('xModal').style.display = "none";
var slides = document.querySelectorAll(".slide");
for (x = 0; x < slides.length; x++) {
con.removeChild(slides[x]);
}
}
var slideIndex = 0;
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.querySelectorAll(".slide");
if (n > slides.length - 1) {
slideIndex = 0
}
if (n < 0) {
slideIndex = slides.length - 1
}
// Flipping a class is much cleaner than relying on style
for (i = 0; i < slides.length; i++) {
slides[i].classList.remove('act');
}
slides[slideIndex].classList.add('act');
}
</script>
</body>
</html>
I don't know how to describe this without making it more complicated.
So look at the result of the code and click on the first link with "Show", then the second one and third one.
When the second link is clicked, first one closes but text remains "Hide" and i want it to change to "Show".
So, when clicking a link, detect if any other link has text "Hide" and change it to "Show".
And please no jQuery...
document.getElementsByClassName("show")[0].onclick = function() {
var x = document.getElementsByClassName("hide")[0];
var y = document.getElementsByClassName("show")[0];
if (x.classList.contains("visible")) {
x.classList.remove("visible");
y.textContent = "Show";
} else {
closeOther();
x.classList.add("visible");
y.textContent = "Hide";
}
};
document.getElementsByClassName("show")[1].onclick = function() {
var x = document.getElementsByClassName("hide")[1];
var y = document.getElementsByClassName("show")[1];
if (x.classList.contains("visible")) {
x.classList.remove("visible");
y.textContent = "Show";
} else {
closeOther();
x.classList.add("visible");
y.textContent = "Hide";
}
};
document.getElementsByClassName("show")[2].onclick = function() {
var x = document.getElementsByClassName("hide")[2];
var y = document.getElementsByClassName("show")[2];
if (x.classList.contains("visible")) {
x.classList.remove("visible");
y.textContent = "Show";
} else {
closeOther();
x.classList.add("visible");
y.textContent = "Hide";
}
};
function closeOther() {
var visible = document.querySelectorAll(".visible"),
i, l = visible.length;
for (i = 0; i < l; ++i) {
visible[i].classList.remove("visible");
}
}
.style {
background-color: yellow;
width: 200px;
height: 200px;
display: inline-block;
}
.hide {
background-color: red;
width: 50px;
height: 50px;
display: none;
position: relative;
top: 50px;
left: 50px;
}
.hide.visible {
display: block;
}
<div class="style">
Show
<div class="hide">
</div>
</div>
<div class="style">
Show
<div class="hide">
</div>
</div>
<div class="style">
Show
<div class="hide">
</div>
</div>
I tried to write a solution which didn't use any javascript at all and worked using CSS alone. I couldn't get it to work though - CSS can identify focus but it can't identify blur (ie. when focus has just been removed).
So here is a solution which uses javascript and the classList API, instead:
var divs = document.getElementsByTagName('div');
function toggleFocus() {
for (var i = 0; i < divs.length; i++) {
if (divs[i] === this) continue;
divs[i].classList.add('show');
divs[i].classList.remove('hide');
}
this.classList.toggle('show');
this.classList.toggle('hide');
}
for (let i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', toggleFocus, false);
}
div {
display: inline-block;
position: relative;
width: 140px;
height: 140px;
background-color: rgb(255,255,0);
}
.show::before {
content: 'show';
}
.hide::before {
content: 'hide';
}
div::before {
color: rgb(0,0,255);
text-decoration: underline;
cursor: pointer;
}
.hide::after {
content: '';
position: absolute;
top: 40px;
left: 40px;
width: 50px;
height: 50px;
background-color: rgb(255,0,0);
}
<div class="show"></div>
<div class="show"></div>
<div class="show"></div>
Like this?
Just added following to closeOther():
visible = document.querySelectorAll(".show"),
i, l = visible.length;
for (i = 0; i < l; ++i) {
visible[i].textContent="Show";
}
What I'm trying to accomplish is a java readmore/readless content toggle function that disable other content when one content's onclick triggers. I'm using getElementsByClassName, setTimeout, and transition.
The problem I'm having is that display: none is not responding to setTimeout. Any suggestion outside of javascript is welcome too.
Here is the Javascript:
function toggle(cont, tog, id) {
for (var i = 0; i < cont.length; i++) {
if (tog[id].innerHTML != "Click Here to Read Less!") {
/* Toggle On */
tog[id].innerHTML = "Click Here to Read Less!";
cont[id].style.height = "250px";
/* Disable other */
setTimeout(function () { cont[i].style.display = "none" }, 500);
setTimeout(function () { tog[i].style.display = "none" }, 500);
for (var x = 0; x < cont.length; x++) {
cont[x].style.opacity = "0";
tog[x].style.opacity = "0";
setTimeout(function () { cont[x].style.display = "none" }, 500);
setTimeout(function () { tog[x].style.display = "none" }, 500);
if (cont[id] == cont[x]) {
cont[id].style.opacity = "1";
tog[id].style.opacity = "1";
}
}
} else {
/* Toggle Off */
tog[id].innerHTML = "Click Here to Read More!";
cont[id].style.height = "100px";
/* Enable other */
for (var x = 0; x < cont.length; x++) {
cont[x].style.opacity = "1";
tog[x].style.opacity = "1";
cont[x].style.display = "block";
tog[x].style.display = "block";
}
}
}
}
Here is my HTML:
<div class="content">
<p>
Content Here!
</p>
</div>
Click Here to Read More!
<div class="content">
<p>
Content Here!
</p>
</div>
Click Here to Read More!
<div class="content">
<p>
Content Here!
</p>
</div>
Click Here to Read More!
And CSS for formatting sake:
/* Centering Content */
#wrapper {
margin: 0 auto;
height: auto;
width: 70%;
text-align: center;
font-family: Sans-Serif, Calibri;
}
/* Styling Content */
.content {
padding: 25px 50px;
margin: 0 auto;
height: 100px;
width: 500px;
display: block;
text-align: left;
overflow: hidden;
-webkit-transition: all 0.5s;
transition: all 0.5s;
}
Without using jQuery, i want to display a div (single) on open, then click on an image (plus) link to close "single" and open another div (multi). At the same time the image "plus" is to change (to minus). Clicking on the "minus" image will then close the "multi" div, open the "single" div and change the image to "plus".
I have found an example on the web that has got me half way there but i can't seem to figure out how to hide "multi" on open and then hide "single" on the image click. The "single" div toggles ok but i can't seem to integrate the "multi" into my code. I ether get the image showing up in the div where its not meant to be, or the "multi" div won't toggle.
<style type="text/css">
#headerDivImg, #contentDivImg, #contentDivImg_, #contentDivImg1, #contentDivImg1_ {
float: left;
width: 510px;
background-color: #FFE694;
text-align: center;
}
#titleTextImg {
float: left;
font-size: 1.2em;
font-weight: bold;
margin: 5px;
}
#imageDivLink {
float: right;
}
#headerDivImg {
background-color: #0037DB;
color: #9EB6FF;
}
#contentDivImg, #contentDivImg_, contentDivImg1, #contentDivImg1_ {
background-color: #FFE694;
text-align: center;
}
#headerDivImg img {
float: right;
margin: 10px 10px 5px 5px;
}
</style>
<script type="text/javascript">
function toggle5(showHideDiv, switchImgTag) {
var ele = document.getElementById(showHideDiv);
var imageEle = document.getElementById(switchImgTag);
if(ele.style.display == "block") {
ele.style.display = "none";
imageEle.innerHTML = '<img src="images/minus.png">';
}
else {
ele.style.display = "block";
imageEle.innerHTML = '<img src="images/plus.png">';
}
}
</script>
<div id="headerDivImg">
<div id="titleTextImg">Click to toggle</div>
<a id="imageDivLink" href="javascript:toggle5('contentDivImg', 'contentDivImg1', 'imageDivLink');"><img src="images/plus.png"></a>
</div>
<br />
<br />
<div id="contentDivImg" style="display: block;">single</div>
<br />
<div id="contentDivImg1" style="display: block;">multi</div>
I made a lot of changes if your code which you can see in JSFidle.
HTML:
<div id="headerDivImg">
<div id="titleTextImg">Click to toggle</div>
<a id="imageDivLink" href="#">
<img />
</a>
</div>
<br />
<br />
<div id="contentDivImg">single</div>
<br />
<div id="contentDivImg1">multi</div>
JS:
//Toggle button
var btnToggle = document.getElementById('imageDivLink');
//Container one
var divSingle = document.getElementById('contentDivImg');
//Container two
var divMultip = document.getElementById('contentDivImg1');
// Toggle button click event handler.
btnToggle.onclick = function(e){
//Check if open single
var showSingle = btnToggle.classList.contains('open');
if (showSingle){
divSingle.classList.add('open');
btnToggle.classList.remove('open');
divMultip.classList.remove('open');
}else{
divSingle.classList.remove('open');
btnToggle.classList.add('open');
divMultip.classList.add('open');
}
};
CSS:
#headerDivImg, #contentDivImg, #contentDivImg_, #contentDivImg1, #contentDivImg1_ {
float: left;
width: 510px;
background-color: #FFE694;
text-align: center;
}
#titleTextImg {
float: left;
font-size: 1.2em;
font-weight: bold;
margin: 5px;
}
#imageDivLink {
float: right;
}
#headerDivImg {
background-color: #0037DB;
color: #9EB6FF;
}
#contentDivImg, #contentDivImg_, contentDivImg1, #contentDivImg1_ {
background-color: #FFE694;
text-align: center;
}
#contentDivImg { display: none;}
#contentDivImg.open { display: block;}
#contentDivImg1 { display: none;}
#contentDivImg1.open { display: block;}
#imageDivLink img {
float: right;
margin: 10px 10px 5px 5px;
content:url("http://blendme.in/psds/brankic1979/plus%20transparent%20.png");
}
#imageDivLink.open img {
content:url("http://blendme.in/psds/brankic1979/minus%20transparent.png");
}
JSFiddle
Try this code....
var key = 0;
function toggle() {
if (key == 0) {
document.getElementById('imageDivLink').innerHTML = "<img src="images/minus.png">";
document.getElementById("contentDivImg").style.display = "none";
document.getElementById("contentDivImg1").style.display = "block";
key = 1;
} else {
document.getElementById('imageDivLink').innerHTML = "<img src="images/plus.png">";
document.getElementById("contentDivImg").style.display = "block";
document.getElementById("contentDivImg1").style.display = "none";
key = 0;
}
}
<div id="headerDivImg">
<div id="titleTextImg">Click to toggle</div>
<a id="imageDivLink" href="javascript:toggle();"><img src="images/plus.png"></a>
</div>
<br />
<br />
<div id="contentDivImg" style="display: block;">single</div>
<br />
<div id="contentDivImg1" style="display: none;">multi</div>