I want to change 2 images at once - javascript

I have images in imageBox1 and imageBox2 and when I click button, is there any way that I can change images in both boxes at the same time? with JS?
For instance, I when I click "hello", I want to make image1-1 and image2-1 display together, and when I click "world", they image1-2 and image2-2 should display together.
<div class = "Button">
<button type="button">hello</button>
<button type="button">world</button>
</div>
<div class = "imageBox1">
<img src="image1-1.jpg">
<img src="image1-2.jpg">
</div>
<div class = "imageBox2>
<img src="image2-1.jpg">
<img src="image2-2.jpg">
</div>

You can add an event listener to each button that gets the index of the button relative to the other buttons, loops through each child in each div and shows the img whose index is the same as the button's.
const divs = document.querySelectorAll('.image');
const buttons = document.querySelectorAll('button')
buttons.forEach((e, i) => e.addEventListener('click', function() {
divs.forEach((f) => [...f.children].forEach((g, i1) => g.style.display = i == i1 ? "block" : "none"))
}))
img {
display: none;
}
<div class="Button">
<button type="button">hello</button>
<button type="button">world</button>
</div>
<div class="imageBox1 image">
<img src="https://www.gravatar.com/avatar/0fdacb141bca7fa57c392b5f03872176?s=48&d=identicon&r=PG&f=1">
<!-- image1-1.jpg -->
<img src="https://www.gravatar.com/avatar/0fdacb141bca7fa57c392b5f03872176?s=96">
<!-- image1-2.jpg -->
</div>
<div class="imageBox2 image">
<img src="https://www.gravatar.com/avatar/0fdacb141bca7fa57c392b5f03872176?s=96">
<!-- image2-1.jpg -->
<img src="https://www.gravatar.com/avatar/0fdacb141bca7fa57c392b5f03872176?s=48&d=identicon&r=PG&f=1">
<!-- image2-2.jpg -->
</div>

It sounds like what you're asking for is a way to show or hide specific images depending on which button the user clicks. If so, you can definitely do this with JavaScript.
Here's a beginner-friendly example using your HTML.
// set up some variables to make the code easier to read
const helloBtn = document.getElementById("hello-button")
const worldBtn = document.getElementById("world-button")
const img1 = document.getElementById("image1")
const img2 = document.getElementById("image2")
const img3 = document.getElementById("image3")
const img4 = document.getElementById("image4")
// When the user clicks the "hello" button, run a function named handleHelloClick
helloBtn.addEventListener("click", handleHelloClick);
// When the user clicks the "world" button, run a function named handleWorldClick
worldBtn.addEventListener("click", handleWorldClick);
// this function handles the "hello" click
function handleHelloClick() {
img1.style.display = "none";
img2.style.display = "block";
img3.style.display = "block";
img4.style.display = "none";
}
// this function handles the "world" click
function handleWorldClick() {
img1.style.display = "block";
img2.style.display = "none";
img3.style.display = "none";
img4.style.display = "block";
}
<div class="buttons">
<button id="hello-button" type="button">hello</button>
<button id="world-button" type="button">world</button>
</div>
<div class="imageBox1">
<img id="image1" src="https://randomuser.me/api/portraits/women/75.jpg">
<img id="image2" src="https://randomuser.me/api/portraits/men/76.jpg">
</div>
<div class="imageBox2">
<img id="image3" src="https://randomuser.me/api/portraits/women/78.jpg">
<img id="image4" src="https://randomuser.me/api/portraits/men/80.jpg">
</div>

first hide them with css
then show them when clicking by js
const hello = document.getElementById("hello")
const world = document.getElementById("world")
hello.onclick= () => {
document.querySelectorAll(".first").forEach(el=> el.style.display = "block")
}
world.onclick= () => {
document.querySelectorAll(".second").forEach(el=> el.style.display = "block")
}
.first, .second {
display : none
}
<div class = "Button">
<button id="hello" type="button">hello</button>
<button id="world" type="button">world</button>
</div>
<div class = "imageBox1">
<img class="first" src="https://dummyimage.com/200x100/000/fff&text=first">
<img class="second" src="https://dummyimage.com/200x100/000/fff&text=second">
</div>
<div class = "imageBox2">
<img class="first" src="https://dummyimage.com/200x100/000/fff&text=first">
<img class="second" src="https://dummyimage.com/200x100/000/fff&text=second">
</div>

Related

Adding div container with class name and html content with JavaScript

I'm looking for a way to add a div container using template literals. for example.
I have a div in my index.html
<div class="bag">
</div>
Every time the user adds a new item to the bag the following divs' get added inside the bag like so...
<div class="bag">
<div class="bag__item"> // <--- added here
<div class="wrapper--within">
<img src="./assets/images/cookie5-small.jpg" alt="" />
<h3 class="bag__unit-price">$5</h3>
<div class="bag__quantity-container">
<div class="bag__minus-sign"></div>
<h3 class="bag__quantity-container__quantity">2</h3>
<div class="bag__plus-sign-middle"></div>
<div class="bag__plus-sign-center"></div>
</div>
<div class="bag__total-price-container">
<img
class="bag__trash-icon"
src="./assets/images/trash-small.png"
alt=""
/>
<h2 class="bag__total-price">$10</h2>
</div>
</div>
</div> // <-- to here
</div>
In my javascript I target my bag container
class Cart {
constructor() {
this.cartContainer = document.querySelector(".bag");
this.events();
}
events() {
this.updateCart();
}
updateCart() {
let newItemDiv = document.createElement("div")
newItemDiv.className = "bag__item"
newItemDiv.createElement("div")
}
}
export default Cart;
I was originally planning to add each div individually but i would like a way where i can do something like..
updateCart() {
let newItemDiv = document.createElement("div")
add `<div class="bag__item"> // <--- added here
<div class="wrapper--within">
<img src="./assets/images/cookie5-small.jpg" alt="" /> // <---image will change depending on item added
<h3 class="bag__unit-price">$5</h3> // price will change depending on item added..
<div class="bag__quantity-container">
<div class="bag__minus-sign"></div>
<h3 class="bag__quantity-container__quantity">2</h3>
<div class="bag__plus-sign-middle"></div>
<div class="bag__plus-sign-center"></div>
</div>
<div class="bag__total-price-container">
<img
class="bag__trash-icon"
src="./assets/images/trash-small.png"
alt=""
/>
<h2 class="bag__total-price">$10</h2>
</div>
</div>
</div> `
}
Is this something that can be done?
In your updateCart() method you can write
updateCart() {
let newItemDiv = document.createElement("div")
newItemDiv.className = "bag__item"
newItemDiv.innerHTML = `your markup here with the whole div hierarchy`;
}
You can do this.
If you already added the div.bad
document.getElementsByClassName("bag").innerHTML = `<div> </div>`
or
var elemt = document.createElement("div")
elemt.innerHTML = `<div> </div>`
You can do it like this: (I implemented below example by Cart class because in your question you've been using Cart class to create new Item and I consider that using this class is mandatory, there are other ways to acheive below result with less lines of code)
class Cart {
constructor(img, price) {
this.img = img;
this.price = price;
this.cartContainer = document.querySelector('.bag');
this.events();
}
getTemplate() {
const template = `<div class="bag__item">
<div class="wrapper--within">
<img src="${this.img}" alt="" />
<h3 class="bag__unit-price">${this.price}</h3>
<div class="bag__quantity-container">
<div class="bag__minus-sign"></div>
<h3 class="bag__quantity-container__quantity">2</h3>
<div class="bag__plus-sign-middle"></div>
<div class="bag__plus-sign-center"></div>
</div>
<div class="bag__total-price-container">
<img
class="bag__trash-icon"
src="./assets/images/trash-small.png"
alt=""
/>
<h2 class="bag__total-price">$10</h2>
</div>
</div>
</div> `;
return template;
}
events() {
this.updateCart();
}
updateCart() {
const template = this.getTemplate();
let newItemDiv = document.createElement('div');
this.cartContainer.append(newItemDiv);
newItemDiv.outerHTML = template;
}
}
// sample img, price (You can set different values for img, price when you want to create new one, this static content is just for example)
const img = 'https://fakeimg.pl/350x200/000000/?text=Image1';
const price = '100$';
function addBag(){
new Cart(img, price);
}
<button onClick="addBag()">click me</button>
<div class="bag">ba continaer:</div>

Changing innerHTML

I am trying to change the innerHTML of a page twice, more explanation, I am trying to make a single page like app. I'm a newbie. I want to change the inner HTML content of the section after one click then get the classList of the changed inner HTML then change it again, but it does not seem to work, I don't know what I am doing wrong.
my thought process for the code is below
select the whole container which is the features container
on click, change the container innerHTML
on click of the changed container innerHTML, change the inner HTML again but It doesn't work, it keeps giving me the first innerHTML but when i do not display the main container that works, how can i solve this?
const hold = document.querySelector('#features');
const holds = document.querySelector('.features');
let hel;
hold.addEventListener('click', function() {
holds.innerHTML = `<div class="ddd">h is here </div>`;
// const self = this;
hel = document.querySelector('.ddd');
// console.log(hel.innerText);
hel.addEventListener('click', function() {
// holds.style.display = 'none';
// this.style.display = 'none';
holds.innerHTML = '<div class="q">mess</div>';
console.log(this);
});
});
<section id="features" class="features section-hidden">
<div class="container container-pal1">
<h2 class="features-description highlight">Features</h2>
<div class="features-contain">
<div class="features-text">
<h3 class="features-header">
We are here to provide you with the
<span class="features-highlight">Best</span> services
</h3>
<p class="features-title">
Everything you need in a modern bank and more, get on our waiting list today by clicking the button below
</p>
<a href="" class="hero-cta-1 features-button">View our services <img src="./assets/arrow-right.svg" alt="" />
</a>
</div>
<div class="features-props">
<div class="features-list">
<div class="features-item">
<img src="./assets/fast-delivery.svg" alt="" />
<h5>Swift Delivery 🚀</h5>
<p>No late transfer, get it instantly</p>
</div>
<div class="features-item">
<img src="./assets/0-fees.svg" alt="" />
<h5>$0 Fee's</h5>
<p>No fees on your account like the other banks</p>
</div>
<div class="features-item">
<img src="./assets//0-interest.svg" alt="" />
<h5>Interest &percnt;</h5>
<p>
Interest when applying for loans depends on your agreement from the bank
</p>
</div>
<div class="features-item">
<img src="./assets/no-credit-check.svg" alt="" />
<h5>Credit Card</h5>
<p>Credit cards available at your demand</p>
</div>
<div class="features-item">
<img src="./assets/chat-support.svg" alt="" />
<h5>Chat Support</h5>
<p>Chat with a company representative anytime</p>
</div>
<div class="features-item">
<img src="./assets/fixed-payment-option.svg" alt="" />
<h5>Fixed Payment Option</h5>
<p>Payment Options will be provided</p>
</div>
</div>
</div>
</div>
</div>
</section>
Here's a simple example how to switch elements that already exist in the DOM.
Use a data-* attribute to reference the desired ID element to show.
Use classList.toggle to switch the Elements.
const ELS_pages = document.querySelectorAll(".page");
const ELS_buttons = document.querySelectorAll("[data-page]");
const goToPage = (id) => {
ELS_pages.forEach(EL => EL.classList.toggle("u-none", EL.id !== id));
};
ELS_buttons.forEach(EL => EL.addEventListener("click", () => {
goToPage(EL.dataset.page);
}));
nav {display: flex;} nav a {color: #00f; padding: 5px 10px; cursor: pointer; }
/* Utility classes */
.u-none {display: none;}
<div class="page" id="page-login">
<h1>Welcome</h1>
<button type="button" data-page="page-main">ENTER</button>
</div>
<div class="page u-none" id="page-main">
<nav>
<a data-page="page-settings">User Settings</a>
<a data-page="page-login">Logout</a>
</nav>
<h1>MAIN PAGE</h1>
</div>
<div class="page u-none" id="page-settings">
<nav>
<a data-page="page-main">Back to Main</a>
<a data-page="page-login">Logout</a>
</nav>
<h1>SETTINGS PAGE</h1>
</div>
This is basic, and does not change the URI address in the browser. To achieve that some more code should be added to handle such case.
Try keeping a flag(if there are only two different data you want to show) and based on the flag show data or a counter
const hold = document.querySelector('#features');
let count = 0;
hold.addEventListener('click', function() {
switch (count){
case 0:
holds.innerHTML = `<div class="ddd">h is here </div>`;
case 1:
holds.innerHTML = `<div class="ddd">now some other is here </div>`
};
});
and please provide more info for the remaining answer
Simply run your second innerHTML code after the next repaint using requestAnimationFrame and it will work.
const hold = document.querySelector("#features");
const holds = document.querySelector(".features");
let hel;
hold.addEventListener("click", function (e) {
e.preventDefault();
holds.innerHTML = `<div class="ddd">h is here </div>`;
// const self = this;
hel = document.querySelector(".ddd");
// console.log(hel.innerText);
hel.addEventListener("click", function () {
// holds.style.display = 'none';
// this.style.display = 'none';
requestAnimationFrame(() => {
holds.innerHTML = '<div class="q">mess</div>';
});
console.log(this);
});
});
if you need further information about why it's happening read this article.

Remove appended element

When I type something in the first box, and click Next, the word I typed is inserted on my page. However, if I click Back and then click Next again, it is printed a second time.
I want the keyword appended after I've clicked Next to be deleted if I click Back so that if I click Next again it is printed only once (and updated if I have made any edit).
document.addEventListener("DOMContentLoaded", function() {
var stepOne = document.getElementsByClassName("step-1");
var stepTwo = document.getElementsByClassName("step-2");
var nextButton = document.getElementsByClassName("next");
var backButton = document.getElementsByClassName("back");
nextButton[0].onclick = function() {
stepOne[0].style.display = "none";
stepTwo[0].style.display = "block";
var inputKeyword = document.getElementById("inputJobTitle").value;
var newKeyword = document.createElement("p");
newKeyword.setAttribute("id", "retrievedField-1");
newKeyword.setAttribute("class", "retrievedFieldName");
newKeyword.innerText = inputKeyword;
newKeyword.setAttribute("id", "retrievedField-1");
newKeyword.setAttribute("class", "retrievedFieldName");
document.getElementById("retrievedFields").appendChild(newKeyword);
}
backButton[0].onclick = function() {
stepOne[0].style.display = "block";
stepTwo[0].style.display = "none";
}
})
.step-1 {
display: block;
}
.step-2 {
display: none;
}
<!--STEP 1-->
<div class="main step-1">
<div class="tab" id="tab-1">
<div class="inputFields">
<p id="jobtitle" class="inputFieldName">Job title</p>
<input type="search" id="inputJobTitle" class="inputBar" />
<p class="and">AND</p>
</div>
<div class="button">
<button class="next">Next ></button>
</div>
</div>
</div>
<!--STEP 2-->
<div class="main step-2">
<div class="tab" id="tab-1">
<div class="inputFields">
<div id="retrievedFields"></div>
<input type="search" class="inputBarAlternative" />
<div class="add">
<button class="addButton">+ Add Keyword</button>
<p id="addKeyword">
Add a skill or keyword that must be in your search results
</p>
</div>
</div>
<div class="buttons">
<button class="back">Back</button>
<button class="next">Next</button>
</div>
</div>
</div>
</body>
Each new click on the next button will trigger an append. So you just have to do the opposite of an append on the click on back. Just add this line in your onclick:
document.getElementById("retrievedFields").removeChild(document.getElementById("retrievedFields").lastElementChild);
You could also check to see if the element exists before you create it..
nextButton[0].onclick = function() {
stepOne[0].style.display = "none";
stepTwo[0].style.display = "block";
var inputKeyword = document.getElementById("inputJobTitle").value;
var newKeyword = document.getElementById("retrievedField-1")
if (!newKeyword) {
newKeyword = document.createElement("p");
newKeyword.setAttribute("id", "retrievedField-1");
newKeyword.setAttribute("class", "retrievedFieldName");
document.getElementById("retrievedFields").appendChild(newKeyword);
}
newKeyword.innerText = inputKeyword;
}

Is there a simpler way to write this code?

This code is designed to make the sections display = none/block onclick, is there an easier way to write it so it is simpler and less lines of code.
I feel like I shouldn't need to rewrite it each time per every link and there should be a way to have 1 script that will work with the whole navbar.
HTML
<header>
<img onclick="video()" id="logo" src="https://res.cloudinary.com/dnrojsaks/image/upload/v1587122319/Icons/logo-no-text_yyug8o.svg" alt="Mac Logo" style="width: 10vw;" />
<nav>
<a onclick="contact()">Contact</a>
<a onclick="work()">Work</a>
<a onclick="blog()">Blog</a>
</nav>
</header>
<main>
<section id="main" style="display: block;">
<h1>Mac Hooper</h1>
<p><strong>Developer.</strong><br> Progressive, modern web development.</p>
</section>
<section id="contact" style="display: none;">
macdevh#gmail.com
<div id="social">
<img src="https://res.cloudinary.com/dnrojsaks/image/upload/v1587129314/Icons/insta_maq9f2.svg" alt="Instagram Logo">
<img src="https://res.cloudinary.com/dnrojsaks/image/upload/v1587129314/Icons/glab_jumort.svg" alt="Twitter Logo">
<img src="https://res.cloudinary.com/dnrojsaks/image/upload/v1587129314/Icons/twit_t57gos.svg" alt="Gitlab Logo">
</div>
</section>
<section id="work" style="display: none;">
<div class="container">
<a href="https://lucycull.design" target="_blank" rel="noopener"><div class="card">
<img id="work-img" src="https://res.cloudinary.com/dnrojsaks/image/upload/v1587134668/Portfolio/lucy_ijnjoq.jpg" />
<h2>Lucy Cull</p>
</div></a>
</div>
</section>
<section id="blog" style="display: none;">
<div class="container">
<a href="https://medium.com/#machooper_69036/make-vscode-yours-e362dab48ff6" target="_blank" rel="noopener"><div class="card">
<img src="https://miro.medium.com/max/600/0*ZdpEvxpU6_SFxDzT.gif" />
<h2>Make VSCode Yours</p>
</div></a>
<a href="https://medium.com/#machooper_69036/my-setup-the-desk-5f4ed6824192" target="_blank" rel="noopener"><div class="card">
<img src="https://miro.medium.com/max/700/1*PFXyIbHjkQE-tGzlj6xMEA#2x.jpeg" />
<h2>My Desk</p>
</div></a>
<div class="card">
<img src="https://miro.medium.com/max/1400/1*qXN9PuwTmiHueFoeskJZnw.jpeg" />
<h2>My Tech Stack</p>
</a></div>
<div class="card">
<img src="https://miro.medium.com/max/700/1*PFXyIbHjkQE-tGzlj6xMEA#2x.jpeg" />
<h2>My Computer</p>
</div></a>
</div>
</section>
<section id="video" style="display:none;">
<video autoplay loop muted src="https://res.cloudinary.com/dnrojsaks/video/upload/v1587133353/Video/assets_img_header_bxtgiz.mp4"></video>
</section>
</main>
js
<script>
function video() {
var main = document.getElementById("main");
var video = document.getElementById("video");
var contact = document.getElementById("contact");
var work = document.getElementById("work");
var blog = document.getElementById("blog");
if (
video.style.display === "none") {
main.style.display = "none";
video.style.display = "block";
contact.style.display = "none";
work.style.display = "none";
blog.style.display = "none";
} else {
video.style.display = "none";
}
}
function contact() {
var main = document.getElementById("main");
var video = document.getElementById("video");
var contact = document.getElementById("contact");
var work = document.getElementById("work");
var blog = document.getElementById("blog");
if (
contact.style.display === "none") {
main.style.display = "none";
video.style.display = "none";
contact.style.display = "block";
work.style.display = "none";
blog.style.display = "none";
} else {
contact.style.display = "none";
}
}
function work() {
var main = document.getElementById("main");
var video = document.getElementById("video");
var contact = document.getElementById("contact");
var work = document.getElementById("work");
var blog = document.getElementById("blog");
if (
work.style.display === "none") {
main.style.display = "none";
video.style.display = "none";
contact.style.display = "none";
work.style.display = "block";
blog.style.display = "none";
} else {
work.style.display = "none";
}
}
function blog() {
var main = document.getElementById("main");
var video = document.getElementById("video");
var contact = document.getElementById("contact");
var work = document.getElementById("work");
var blog = document.getElementById("blog");
if (
blog.style.display === "none") {
main.style.display = "none";
video.style.display = "none";
contact.style.display = "none";
work.style.display = "none";
blog.style.display = "block";
} else {
blog.style.display = "none";
}
}
Just write a generic function that takes the section-name as parameter and then compute your style.display.
In such cases, I would always make use of combining classes and Id. Yes I know maybe someone has a better approach but this for me always is easier.
NB: I just wrote this here I didn't test it if it has bugs comment I will check it but it should work 100%.
Your style
<style>
.item
{
display: none;
}
</style
Your HTML
<nav>
<a class="link-item" id="contact">Contact</a>
<a class="link-item" id="work">Work</a>
<a class="link-item" id="blog">Blog</a>
</nav>
<span class="contact item">Put your video here</span>
<span class="work item">Your work content here</span>
<span class="blog item">Your blog content here</span>
Jquery
$(function()
{
$(".link-item").click(function(e)
{
var targetClassName = $(this).attr('id') //get the id of the clicked item so that you can
//display it later
$(".item").hide(function(e) //hide all item
{
$("."+targetClassName).show() //on callback display the item which was clicked using its classname
}
}
}
Disclaimer: I have done it with JQuery, you can convert this Jquery to Javascript. Your question was on Javascript so you might want JQuery or just do it with you Javascript but it should give you same results
I prefer JQuery(Javascript library) it's smaller and thus easily debugable. But if you want JS comment I can do it with Javascript

Pure Javascript display div based on Menu Item Clicked?

I just need some advice with my current code. I am trying to display a different div depending on the menu item clicked. I was thinking theoretically using some kind of indexing method. i think the if statement i am using for once does not work but also seems a little horrible in terms of coding.
anyway what do you think?
/**
* Lets get Menu container
*/
var menu = document.getElementById("configurator-menu");
/**
* Set Current Tab and Store which tab is Active
*/
var navitem = menu.querySelector(".configurator-menuitems div");
navitem.className += " " + "activeTab";
/**
* Add click events to Menu Tabs
*/
var tabs = menu.querySelectorAll(".configurator-menuitems div");
for (var i = 0; i < tabs.length; i++) {
tabs[i].onclick=displayPage;
}
/**
* Tabs Logic
*/
function displayPage() {
var items = menu.querySelectorAll(".configurator-menuitems div");
for (var i = 0; i < items.length; i++) {
items[i].classList.remove("activeTab");
}
this.className += " " + "activeTab";
if (this.classList.contains("mainMenu1")) {
var item = document.getElementByClassName("appCanvas1");
item.style.display = "block";
}
else if (this.classList.contains("mainMenu2")) {
var item = document.getElementByClassName("appCanvas2");
item.style.display = "block";
}
else if (this.classList.contains("mainMenu3")) {
var item = document.getElementByClassName("appCanvas3");
item.style.display = "block";
}
}
<div id="configurator-menu" class="appMenu" style="background-color:#001A35;">
<div class="appLogo">
Logo Here
</div>
<hr class="no-margin" />
<div class="configurator-menuitems">
<div class="mainMenu-btn mainMenu1">Shape</div><hr class="no-margin" />
<div class="mainMenu-btn mainMenu2">Size</div><hr class="no-margin" />
<div class="mainMenu-btn mainMenu3">Color</div><hr class="no-margin" />
</div>
<div class="menuspacer"></div><hr class="no-margin" />
<div class="currentSettings">
<p class="settings-title">Your Selection</p>
<p class="variant-config">Shape: </p>
<p class="variant-config">Colors: </p>
<p class="variant-config">Size: </p>
<p class="variant-config">Quantity: </p>
<p class="variant-config">Total Price: </p>
</div>
</div>
<div class="canvas-wrapper">
<div class="appCanvas1" style="background-color:#e7e7e7;">
<div class="shape-selection-bar">
<div class="shape-selector"><img src="'.plugins_url("pentant_conical.png", __FILE__).'" alt="" /></div>
<div class="shape-selector"><img src="'.plugins_url("pendant_cyl.png", __FILE__).'" alt="" /></div>
<div class="shape-selector"><img src="'.plugins_url("standing_lamp_conical.png", __FILE__).'" alt="" /></div>
<div class="shape-selector"><img src="'.plugins_url("standing_lamp_cyl.png", __FILE__).'" alt="" /></div>
</div>
<div class="configurator-progressBtn"> Move On</div>
</div>
<div class="appCanvas2" style="background-color:#e7e7e7;">
<div class="configurator-progressBtn"> Move On</div>
</div>
<div class="appCanvas3" style="background-color:#e7e7e7;">
<div class="configurator-progressBtn"> Move On</div>
</div>
</div>

Categories

Resources