Click to change image across multiple items - javascript

I'm trying to set up a javascript function that will take a down arrow image and swap it with an up arrow image when clicked. It worked when the image had an id, but because I have a couple menu items that uses the arrow image, I wanted to try to get it to work as a class name or just regular name, but I can't get the function to change the source of the image when it's not an id. Can anyone help?
Here is my current HTML markup:
<div class="header__links hide-for-mobile" >
<a id="subMenu" href="#">Features <img class="downArrow" src="/assets/images/icon-arrow-down.svg"></a>
Company
Careers
About
</div>
And here is my JS
const subMenu = document.querySelector('#subMenu');
subMenu.addEventListener('click', function() {
if(subMenu.classList.contains('subOpen')) {
subMenu.classList.remove('subOpen');
document.getElementsByClassName('downArrow').src="/assets/images/icon-arrow-down.svg";
}
else {
subMenu.classList.add('subOpen');
document.getElementsByClassName('downArrow').src="/assets/images/icon-arrow-up.svg";
}
})

Right now since your markup only contains a single element with the downArrow class you could update your code to:
const subMenu = document.querySelector('#subMenu');
subMenu.addEventListener('click', function() {
if(subMenu.classList.contains('subOpen')) {
subMenu.classList.remove('subOpen');
document.getElementsByClassName('downArrow')[0].src="/assets/images/icon-arrow-down.svg";
}
else {
subMenu.classList.add('subOpen');
document.getElementsByClassName('downArrow')[0].src="/assets/images/icon-arrow-up.svg";
}
})
But a better way to do this would be to loop through the results of the getELementsByClassName method. You could do that with something like:
const subMenu = document.querySelector('#subMenu');
subMenu.addEventListener('click', function() {
if(subMenu.classList.contains('subOpen')) {
subMenu.classList.remove('subOpen');
Array.from(document.getElementsByClassName("downArrow")).forEach(
function(element, index, array) {
element.src="/assets/images/icon-arrow-down.svg";
}
);
}
else {
subMenu.classList.add('subOpen');
Array.from(document.getElementsByClassName("downArrow")).forEach(
function(element, index, array) {
element.src="/assets/images/icon-arrow-up.svg";
}
);
}
})

Related

view all products with the replicate of the list of products presented in html in un click JQuery

I've this code https://jsfiddle.net/oj20rwk3/
The goal is to create a 'View all' button under the product sheets which, when clicked, adds clones of the latter at the bottom of the page, filling all available spaces (in this case replicate the products).
When I click a button "view all", I want to see all products with the replicate of the list of products presented in html in alphabetical order. Can you help me to move on?
ACC.plp = {
_autoload: [
["hideLinkOnSearchBox", $('.js-hide').length > 0],
"viewAll"
],
hideLinkOnSearchBox: function () {
$(window).on('scroll', function() {
scroll_top = $(this).scrollTop();
if(scroll_top <=1000) {
$('.js-hide').removeClass("d-none");
}
else if( scroll_top >1000){
$('.js-hide').addClass("d-none");
}
});
},
viewAll: function() {
$(".plp-products-container").ready(function(){
$(".button-row [name=viewALL]").click(function(){
$(".product-item").show();
});
$(".button-row [name=viewALL]").click(function(){
$(".product-item").hide();
});
});
},
}
Thank you for helping
You would need a wrapped element for all your product-item so that we can easily clone its children with matching class name and append to the wrapper.
let cloned = false;
$('button[name=viewALL]').click(function(){
/* Below check is to prevent cloning more than once */
if (cloned === false ) {
cloned = true;
$(".product-wrapper").children('.product-item').clone().appendTo(".product-wrapper");
}
});
<div class="product-wrapper">
<div class="product-item">.A.</div>
<div class="product-item">.B.</div>
<div class="product-item">.C.</div>
</div>
Jsfiddle - https://jsfiddle.net/kaop69zg/

Change icon with javascript

In my foray into web development I have found a new problem, I need to change the icon for another one when I click on it. I have an idea of a function in javascript that sends the id of the icon and with the obtain the element, after obtaining element I hope to change keyboard_arrow_up by keyboard_arrow_down. However that is the part that is not performed, how do I get the value keyboard_arrow_up?
function change(iconID) {
var item = document.getElementById(iconID);
if (item) {}
}
<i id="icon1" onclick="change('icon1')" class="material-icons">keyboard_arrow_up</i>
This is the temporary solution, I had to change the icons of google design material by the fontawesome icons. However, I will continue investigating.
function change (iconID){
if(document.getElementById(iconID).className=="fa fa-chevron-up"){
document.getElementById(iconID).className = "fa fa-chevron-down";
}else{
document.getElementById(iconID).className = "fa fa-chevron-up";
}
}
<i id="icon1" onclick="change('icon1')" class="fa fa-chevron-up" aria hidden="true">
Sounds like , you need this kind of function
function changeIcon(classname or id) {
$("i", this).toggleClass("icon-circle-arrow-up icon-circle-arrow-down");
}
Note : the icons in above solution are copied from internet , please use your desire icons in there.
Remember Icons are just CSS class, so the function should change the class for another on the javascript function.
function change(iconID) {
var element = document.getElementById(iconID);
if (element.classList.contains("keyboard_arrow_up")) {
element.classList.add("keyboard_arrow_down")
} else {
element.classList.add("keyboard_arrow_up")
}
}
You can change innerText as follows:
document.addEventListener("DOMContentLoaded", function() {
let change = document.querySelector("#icon");
change.addEventListener('click' ,function () {
let item = document.querySelector("#icon");
if(this.innerText == 'keyboard_arrow_down'){
item.innerText = "keyboard_arrow_up";
}else{
item.innerText = "keyboard_arrow_down";
}
})
});
and the html:
<i id="icon" class="material-icons">keyboard_arrow_up</i>
function change(iconID) {
var item = document.getElementById(iconID);
if (item) {}
}
<i id="icon1" onclick="change('icon1')" class="material-icons">keyboard_arrow_up</i>
snap pans

Loop through element and change based on link attribute

Trying to figure this out. I am inexperienced at jQuery, and not understanding how to loop through elements and match one.
I have 3 divs:
<div class="first-image">
<img src="images/first.png">
</div>
<div class="second-image">
<img src="images/second.png">
</div>
<div class="third-image">
<img src="images/third.png">
</div>
And off to the side, links in a div named 'copy' with rel = first-image, etc.:
...
Clicking the link will fade up the image in the associated div (using GSAP TweenMax)
Here is the function I've been working on to do this... but I am not fully understanding how to loop through all the "rel" elements, and make a match to the one that has been clicked on.
<script>
//pause slideshow on members to ledger when text is clicked, and show associated image
$(function() {
$('.copy').on('click','a',function(e) {
e.preventDefault();
var slideName = $(this).attr('rel');
$("rel").each(function(i){
if (this.rel == slideName) {
console.log(this);
}
});
//var change_screens_tween = TweenMax.to('.'+slideName+'', 1, {
//autoAlpha:1
//});
});
});
</script>
What am I doing wrong? I don't even get an error in my browser. :-(
Thanks to the answer below, I got farther. Here is my revised code.
$('[rel]').each(function(k, v){
if (v == slideName) {
var change_screens_tween = TweenMax.to('.'+slideName+'', 1, {
autoAlpha:1
});
} else {
var change_screens_tween = TweenMax.to('.'+slideName+'', 1, {
autoAlpha:0
});
}
});
});
This is starting to work, but makes the screenshots appear and then instantly fade out. And it only works once. Any thoughts?
Add brackets around rel, like so:
$('[rel]').each(function() {
if ($(this).attr('rel') == slideName) {
console.log(this);
}
});

jQuery - Variable selectors in ForEach loop

I've written a forEach loop which goes through an array of divs (by ID), selects child elements with a certain class and removes another class from them. I'm having a few issues turning the variable back into a selector and joining it to the other ones. As a result, my forEach loop doesn't work.
http://jsfiddle.net/NWmB5/7/ (Try clicking one of the links, the third item should turn black again if the code works)
var toDoCategories;
$(document).ready(function() {
toDoCategories = [$("#testDiv"),$("#anotherDiv"),$("thirdDiv")];
setTimelinePosition($('#thirdDiv'));
$('#targetFirstDiv').click(function() {
setTimelinePosition($('#anotherDiv'));
});
$('#targetSecondDiv').click(function() {
setTimelinePosition($('#testDiv'));
});
});
/* Show current position on timeline */
function setTimelinePosition($position) {
var $theTimelineTrigger = $('span.timelineTrigger');
toDoCategories.forEach(function(currentCategory) {
var $deselectTimelinePositionElement = $(currentCategory, $theTimelineTrigger);
$($deselectTimelinePositionElement).removeClass('currentPosition');
});
It should be as simple as
$(document).ready(function () {
var $toDoCategories = $("#testDiv, #anotherDiv, #thirdDiv"); //NOTE HERE
setTimelinePosition('#thirdDiv');
$('#targetFirstDiv').click(function () {
setTimelinePosition('#anotherDiv');
});
$('#targetSecondDiv').click(function () {
setTimelinePosition('#testDiv');
});
/* Show current position on timeline */
function setTimelinePosition(position) {
$toDoCategories.find('.currentPosition').removeClass('currentPosition')
$(position).find('.timelineTrigger').addClass('currentPosition');
}
});
Demo: Fiddle
Another approach: Fiddle

Get numerical value from parent with id like 'post-1' and use it in jQuery function

I'm trying to figure out the following.
I have following jQuery code:
var as = "";
var bPlay = 0;
audiojs.events.ready(function() {
as = audiojs.createAll();
$(".audiojs .play-pause").click(function() {
var e = $(this).parents(".audiojs").index(".audiojs");
$.each(as, function(t, n) {
if (t != e && as[t].playing) {
as[t].pause()
}
})
bPlay = !bPlay;
if (bPlay == 1) {
$(".bar").each(function(i) {
fluctuate($(this));
});
} else {
$(".bar").stop();
}
})
});
In a nutshell it preforms list of things when someone clicks particular .audiojs instance on a page. 1) checks if there is any other instance playing, if there is pauses it. And if it is playing applies fluctuate function to elements on a page that have class="bar". This is the issue! I don't want to apply it to all .bar's on a page, but only to a specific group that is associated with particular .audiojs instance (the one that is being clicked and is playing).
I thought of the following solution. Each .audiojs instance is inside a div tag that has id like "post-1", "post-2" etc.. where numerical value is post id from database. I can add this numerical id to bar, so it would be like bar-1, bar-2 etc... However after this I'm having issues.
For javascript to work I need to retrieve numerical value from "post-[id]" associated with audiojs instance that is being clicked and than store it somehow, so I can use it like this afterwards
bPlay = !bPlay;
if (bPlay == 1) {
$(".bar-[value retrieved from post-...]").each(function(i) {
fluctuate($(this));
});
} else {
$(".bar-[value retrieved from post...]").stop();
}
Could someone explain to me how it can be achieved?
Honestly, the easiest way would be to stick it in a custom data-* attribute on the <div id="post-X"> element, like so:
<div id="post-1" data-bar="bar-1">...</div>
Then, you said your .audiojs element is inside that <div>, so just go from this inside the event handler to that <div> element (using .closest()) and get the value of it:
var barId = $(this).closest('[id^="post-"]').attr('data-bar');
Then when you need to use it:
$("." + barId).each(function(i) {
fluctuate($(this));
});
Instead of embedding the value in a class or ID, use a data-* attribute:
<div class="audiojs" data-fluctuate-target="bar-1">
<button type="button" class="play-pause">
<!-- ... -->
</button>
</div>
<div class="bar-1">
<!-- ... -->
</div>
In your click event handler, use the following to fluctuate or stop the correct elements:
var fluctuateClass = $(this).closest('.audiojs').attr('data-fluctuate-target');
$('.' + fluctuateClass).each(function () {
if (bPlay == 1) {
fluctuate($(this));
} else {
$(this).stop();
}
});

Categories

Resources