How to move the ID of one element to another using JS - javascript

I am trying to create a slide show of icons. All the icons are in one class. Another style class called "active" will have an ID and represents the current picture. Clicking the left or right button should change the style of the active class.
const leftArrow = document.getElementById('left-arrow');
const activeImg = document.getElementById('active') const nextImg = activeImg.nextElementSibling; // Handle left click leftArrow.addEventListener('click', function(){ activeImg.classList.remove('active');
nextImg.classList.add('active');
return nextImg
});
.icon-container i {
font-size: 150px;
position: relative;
left: 12rem;
top: 12rem;
z-index: -10;
display: none;
}
#active {
z-index: 10;
display: flex;
}
.left-arrow,
.right-arrow {
width: 50px;
height: 50px;
transition: .5s;
float: left;
box-shadow: -2px 2px 0 rgba(238, 0, 0, 0.5);
cursor: pointer;
}
<div class="object-container">
<div class="icon-container">
<i class="fa fa-car" id="active"></i>
<i class="fa fa-bicycle"></i>
<i class="fa fa-plane"></i>
<i class="fa fa-ship"></i>
<i class="fa fa-fighter-jet"></i>
<i class="fa fa-space-shuttle"></i>
</div>
<div class="arrow-buttons">
</div>
</div>
The problem is that when I click the left arrow, nothing happens. I've also tried with the right arrow but that doesnt even show the cursor pointer so I don't know where I went wrong there. I've played around with z-index and display types but the buttons don't seem to be working?
Thanks

I recommend using a class name and not an id. Here's how you can do that:
https://jsfiddle.net/sauz07d5/1
<div class="object-container">
<div class="icon-container">
<i class="fa fa-car active"></i>
<i class="fa fa-bicycle"></i>
<i class="fa fa-plane"></i>
<i class="fa fa-ship"></i>
<i class="fa fa-fighter-jet"></i>
<i class="fa fa-space-shuttle"></i>
</div>
<div class="arrow-buttons">
<button class="right-arrow" id="right-arrow"></button>
<button class="left-arrow" id="left-arrow"></button>
</div>
</div>
.icon-container i{
font-size: 150px;
position: relative;
left: 12rem;
top: 12rem;
z-index: -10;
display: none;
}
.left-arrow, .right-arrow{
width: 50px;
height: 50px;
transition: .5s;
float: left;
box-shadow: -2px 2px 0 rgba(238, 0, 0, 0.5);
cursor: pointer;
}
.active {
z-index: 10 !important;
display: flex !important;
}
const leftArrow = document.getElementById('left-arrow');
const rightArrow = document.getElementById('right-arrow');
// Handle left click
var element = document.querySelector(".icon-container")
function slideNext() {
let currentImg = document.querySelector(".active");
let nextImg = currentImg.nextElementSibling ? currentImg.nextElementSibling : element.children[0];
currentImg.classList.remove("active");
nextImg.classList.add("active");
}
function slidePrevious() {
let currentImg = document.querySelector(".active");
let previousImg = currentImg.previousElementSibling ? currentImg.previousElementSibling : element.children[element.children.length - 1];
currentImg.classList.remove("active");
previousImg.classList.add("active");
}
leftArrow.addEventListener('click', slideNext);
leftArrow.addEventListener('touch', slideNext);
rightArrow.addEventListener('click', slidePrevious);
rightArrow.addEventListener('touch', slidePrevious);

var icons = [...document.querySelectorAll('.icon-container .fa')];
function adjustActive (adjustment) {
var current = icons.find(it => it.id === 'active');
var currentIndex = icons.indexOf(current);
var nextIndex = (currentIndex + adjustment) % icons.length;
if (nextIndex < 0) nextIndex = icons.length - 1;
current.removeAttribute('id');
icons[nextIndex].id = 'active';
}
document.querySelector('#left-arrow').addEventListener('click', e => adjustActive(-1));
document.querySelector('#right-arrow').addEventListener('click', e => adjustActive(1));
#active {
color: red;
}
<div class="object-container">
<div class="icon-container">
<i class="fa fa-car" id="active">Car</i>
<i class="fa fa-bicycle">Bike</i>
<i class="fa fa-plane">Plane</i>
<i class="fa fa-ship">Ship</i>
<i class="fa fa-fighter-jet">Jet</i>
<i class="fa fa-space-shuttle">Shuttle</i>
</div>
<div class="arrow-buttons">
Prev
Next
</div>
</div>
While it is typically preferable to move classes around, you can (if you must) move ids around. The example above uses the id to find the active element, and using the position of the active element in the array of elements, it finds the next element by adjusting the current index. Then it is a simple matter of removing the id from the old current and putting it on the new current.

Instead of using active as an ID, you should use it as a class, like so:
<div class="icon-container">
<i class="fa fa-car active"></i>
<i class="fa fa-bicycle"></i>
<i class="fa fa-plane"></i>
<i class="fa fa-ship"></i>
<i class="fa fa-fighter-jet"></i>
<i class="fa fa-space-shuttle"></i>
</div>
Just create click listeners for the left and right buttons and remove the active class from the current item and add it to its previous or next sibling.
Or, if you consider its not worth the time to create your own implementation you can also use an already available one like Owl Carousel

Related

How to add Eventlisteners to all elements of a class but execute it only for a particular element during mouseover?

I've been trying to write a javascript code in which the user will be displayed three options (Purchase, Add to cart, Add to wishlists), whenever they will hover above an image of a book. The problem is that all the options for all the books are shown simultaneously when I hover above any image. Is there any way to display options only for the particular book on which the cursor is over.
let images = document.getElementsByClassName('images');
let options = document.getElementsByClassName('options');
for (const index of options)
{index.style.display = 'none';}
for (index = 0; index < images.length; index++) {
images[index].addEventListener('mouseover', () => {
for (const iterator of options) {
iterator.style.display = 'inline-block';
}
});
}
for (index = 0; index < images.length; index++) {
images[index].addEventListener('mouseout', () => {
for (const iterator of options) {
iterator.style.display = 'none';
}
});
}
.slider {
display: flex;
justify-content: space-between;
margin: 25px 0px;
}
.book {display: inline-block; position: relative;}
.book a {display: block; width: 20vw;}
.info {
display: block;
text-align: center;
text-decoration: none;
color: rgb(90, 90, 90);
font-size: 17px;
font-weight: 500;
transition: color 250ms;
}
.info:hover {color: rgb(255, 0, 0);}
.book a:hover {color: rgb(255, 0, 0);}
.book .info:last-of-type {margin-top: 5px;}
.book_price {text-align: center; margin: 10px 0px;}
.book_price p {
display: inline;
color: rgb(90, 90, 90);
font-size: 17px;
font-weight: 500;
margin: 10px 5px;
}
.book_price span:last-of-type p {color: rgb(255, 0, 0);}
.options {
background-color: rgba(255, 255, 255, 0.7);
display: inline-block;
position: absolute;
bottom: 250px;
right: 62px;
padding: 10px;
}
.options a {
display: inline-block;
color: rgb(90, 90, 90);
font-size: 22px;
padding: 5px 10px;
width: auto;
transition: color 250ms;
}
.options a:nth-of-type(2) {border-right: 1px solid rgb(50, 50, 50); border-left: 1px solid rgb(50, 50, 50);}
<link rel="stylesheet" href="https://kit-pro.fontawesome.com/releases/v5.15.1/css/pro.min.css">
<div class="slider">
<div class="book" class="book_1">
<img src="http://www.cliometrics.com/bbw/images/product/1.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
$10,000,000 Marraige Proposal
-James Patterson
<div class="book_price">
<span><del><p>₹200.00</p></del></span>
<span><p>₹160.00</p></span>
</div>
</div>
<div class="book" id="book_2">
<img src="http://www.cliometrics.com/bbw/images/product/2.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
How to write your first Book
-Reader's Digest
<div class="book_price">
<span><del><p>₹400.00</p></del></span>
<span><p>₹260.00</p></span>
</div>
</div>
<div class="book" class="book_3">
<img src="http://www.cliometrics.com/bbw/images/product/3.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
10,000 Time saving Ideas
-G.H. Miller
<div class="book_price">
<span><del><p>₹300.00</p></del></span>
<span><p>₹150.00</p></span>
</div>
</div>
<div class="book" class="book_4">
<img src="http://www.cliometrics.com/bbw/images/product/4.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
10,000 Time saving Ideas
-G.H. Miller
<div class="book_price">
<span><del><p>₹300.00</p></del></span>
<span><p>₹150.00</p></span>
</div>
</div>
<div class="book" class="book_5">
<img src="http://www.cliometrics.com/bbw/images/product/5.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
10,000 Time saving Ideas
-G.H. Miller
<div class="book_price">
<span><del><p>₹300.00</p></del></span>
<span><p>₹150.00</p></span>
</div>
</div>
<div class="book" class="book_6">
<img src="http://www.cliometrics.com/bbw/images/product/6.png" class="images">
<div class="options">
<i class="fal fa-plus"></i>
<i class="fal fa-shopping-cart"></i>
<i class="fal fa-heart"></i>
</div>
10,000 Time saving Ideas
-G.H. Miller
<div class="book_price">
<span><del><p>₹300.00</p></del></span>
<span><p>₹150.00</p></span>
</div>
</div>
</div>
You have to use the event object and the attribute target:
for (index = 0; index < images.length; index++) {
images[index].addEventListener('mouseover', (event) => {
for (const iterator of options) {
event.target.style.display = 'inline-block'; // Use event.target
}
});
}

how to close an element upon the click of another element

I want each element to close upon the click of the "x" icon using pure javascript. i'm actually new to javascript so i am trying some stuffs out. Below is my code and what i have been able to do.
I want each element to close upon the click of the "x" icon.
var closeBtnTask = document.querySelectorAll(".times");
for (var i = 0; i < closeBtnTask.length; i++) {
closeBtnTask[i].addEventListener("click", function() {
var panel = document.querySelectorAll(".taskpanel");
for (var x = 0; x < taskpanel.length; x++) {
Things[x].style.display = "none";
}
});
}
.task-box {
float: left;
width: 100%;
}
.task-wrapper {
width: 400px;
background: #f5f5f5;
}
ul.mytask {
padding: 0px;
margin: 0px;
padding-left: 5px;
}
ul.mytask li {
list-style: none;
line-height: 34px;
border-bottom: 1px solid #ddd;
}
.mytask span {
float: right;
padding-right: 10px;
cursor: pointer;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<div class="task-box">
<div class="task-wrapper">
<ul class="mytask">
<li class="taskpanel">First Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Second Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Third Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Fourth Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Fifth Task <span><i class="fa fa-close times"></i></span></li>
</ul>
</div>
</div>
You can delegate in plain JS too
document.querySelector(".mytask").addEventListener("click",function(e) {
let tgt = e.target;
if (tgt.matches(".fa-close")) tgt.closest("li").style.display="none";
})
.task-box {
float: left;
width: 100%;
}
.task-wrapper {
width: 400px;
background: #f5f5f5;
}
ul.mytask {
padding: 0px;
margin: 0px;
padding-left: 5px;
}
ul.mytask li {
list-style: none;
line-height: 34px;
border-bottom: 1px solid #ddd;
}
.mytask span {
float: right;
padding-right: 10px;
cursor: pointer;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<div class="task-box">
<div class="task-wrapper">
<ul class="mytask">
<li class="taskpanel">First Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Second Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Third Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Fourth Task <span><i class="fa fa-close times"></i></span></li>
<li class="taskpanel">Fifth Task <span><i class="fa fa-close times"></i></span></li>
</ul>
</div>
</div>
Your code was just a bit wrong, I fixed it here
https://jsfiddle.net/L81t9ym6/
var closeBtnTask = document.querySelectorAll(".times");
for (var i = 0; i < closeBtnTask.length; i++) {
closeBtnTask[i].addEventListener("click", function() {
var panel = document.querySelectorAll(".taskpanel");
for (var x = 0; x < panel.length; x++) {
panel[x].style.display = "none";
}
});
}
Note: this closes EVERY element when you click ANY x, rather than just the element that the click happened on.
edit
here's the code for closing JUST the panel you clicked
var closeBtnTask = document.querySelectorAll(".times");
for (var i = 0; i < closeBtnTask.length; i++) {
closeBtnTask[i].addEventListener("click", function(ev) {
var tp = ev.target.closest('.taskpanel');
tp.style.display = "none";
});
}
I didn't know that javascript has a native .closest method now, that's useful! https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
use this Javascript
working demo is here https://jsfiddle.net/Lg7bjr3k/
$('.times').click(function(){
$(this).parent().parent().hide();
})

Javascript toggle working but shows unstyled menu

On my ruby on rails 5 app I have a menu button that uses javascript to toggle the menu, the toggle function is showing and hiding the menu but the menu is not styled with css anymore
onclick the menu toggles like it should but all the elements are not styled, I dont know if its related to rails or I am missing something here
//Toggle between adding and removing the "show_for_mobile" class to admin_side_bar when the user clicks on the icon
function toggleNav() {
var x = document.getElementById("admin_side_bar");
console.log(x.className)
if (x.className === "admin_side_bar") {
x.className += "show_for_mobile";
} else {
x.className = "admin_side_bar";
}
}
.admin_side_bar {
width: 70%;
height: 50vh;
background-color: #e2e6e8;
position: absolute;
left: 0;
top: 60px;
padding: 20px 10px;
display: none;
}
//show side bar on click
.show_for_mobile {
display: block;
}
.admin_side_bar>ul {
list-style-type: none;
padding: 0;
margin: 0;
}
.admin_side_bar>ul>a {
color: #3d3d3d;
font-size: 19px;
text-decoration: none;
}
.admin_side_bar>ul>a:hover {
color: #06bed3;
}
.admin_side_bar .fas {
margin-right: 20px;
color: #afaeae;
}
.admin_side_bar .fas:hover {
color: #7a7a7a;
}
.admin_side_bar>ul>a>li {
margin-bottom: 20px;
}
<!--Admin side bar-->
<div class="admin_side_bar" id="admin_side_bar">
<ul>
<a href="#">
<li><i class="fas fa-home fa-fw fa-lg"></i>Home</li>
</a>
<a href="#">
<li><i class="fas fa-tshirt fa-fw fa-lg"></i>Items</li>
</a>
<a href="#">
<li><i class="fas fa-gift fa-fw fa-lg"></i>Orders</li>
</a>
<a href="#">
<li><i class="fas fa-chart-line fa-fw fa-lg"></i>Stats</li>
</a>
<a href="#">
<li><i class="fas fa-newspaper fa-fw fa-lg"></i>Blog</li>
</a>
</ul>
</div>
When you add the .show_for_mobile class the original display:none from .admin_side_bar still takes precedence. If all you really want to do is show the nav then you can use x.style.display = "block"; to overwrite display:none from the admin_side_bar class
x.style.display="block" works because it adds inline style which is the highest CSS specificity (it overwrites all other css rules).
From CSS specificity
Inline styles added to an element (e.g., style="font-weight:bold") always overwrite any styles in external stylesheets, and thus can be thought of as having the highest specificity.
document.getElementById("toggleButton").addEventListener("click", toggleNav);
//Toggle between adding and removing the "responsive" class to topnav when the user clicks on the icon
function toggleNav() {
var x = document.getElementById("admin_side_bar");
if (x.className === "admin_side_bar") {
x.className += " show_for_mobile";
x.style.display = "block";
} else {
x.className = "admin_side_bar";
x.style.display = "none";
}
}
.admin_side_bar {
width: 70%;
height: 50vh;
background-color: #e2e6e8;
position: absolute;
left: 0;
top: 60px;
padding: 20px 10px;
display: none;
}
//show side bar on click
.show_for_mobile {
display: block !important;
}
.admin_side_bar>ul {
list-style-type: none;
padding: 0;
margin: 0;
}
.admin_side_bar>ul>a {
color: #3d3d3d;
font-size: 19px;
text-decoration: none;
}
.admin_side_bar>ul>a:hover {
color: #06bed3;
}
.admin_side_bar .fas {
margin-right: 20px;
color: #afaeae;
}
.admin_side_bar .fas:hover {
color: #7a7a7a;
}
.admin_side_bar>ul>a>li {
margin-bottom: 20px;
}
<button id="toggleButton">Toggle Nav</button>
<!--Admin side bar-->
<div class="admin_side_bar" id="admin_side_bar">
<ul>
<a href="#">
<li><i class="fas fa-home fa-fw fa-lg"></i>Home</li>
</a>
<a href="#">
<li><i class="fas fa-tshirt fa-fw fa-lg"></i>Items</li>
</a>
<a href="#">
<li><i class="fas fa-gift fa-fw fa-lg"></i>Orders</li>
</a>
<a href="#">
<li><i class="fas fa-chart-line fa-fw fa-lg"></i>Stats</li>
</a>
<a href="#">
<li><i class="fas fa-newspaper fa-fw fa-lg"></i>Blog</li>
</a>
</ul>
</div>

How to make star rating based on percentage shown in image?

Im trying to create star rating based on score or percentage. I have created codepen for inline stars. But don't understand how to do for stars shown in image. Stars should not be inline, they should formed a triangle.
Will you please help me with that.
and my codepen link
/*---------- general ----------*/
body {
background: #ff7070;
color: #F3FCF0;
font-family: sans-serif;
text-align: center;
}
/*---------- star rating ----------*/
%flex-display {
display: flex;
}
.star-rating {
#extend %flex-display;
align-items: center;
font-size: 3em;
justify-content: center;
margin-top: 50px;
}
.back-stars {
#extend %flex-display;
color: #bb5252;
position: relative;
text-shadow: 4px 4px 10px #843a3a;
}
.front-stars {
#extend %flex-display;
color: #FFBC0B;
overflow: hidden;
position: absolute;
text-shadow: 2px 2px 5px #d29b09;
top: 0;
}
<script src="https://use.fontawesome.com/f4e64b7c17.js"></script>
<div class="star-rating">
<div class="back-stars">
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>>
<div class="front-stars" style="width: 70%">
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
</div>
</div>
</div>
Thanks in advance.
You are missing left:0 in .front-stars class
Sometime browsers render absolute element using left 0 some time not, So we should always mention combination of two at least( from left right top bottom)
Thanks

jQuery .each() span.Title get .text() connect with "/"

Live Snippet
$(document).ready(function() {
"use strict";
var PushState, Current;
$(document).on('click', function(e) {
if ($(e.target).closest($('.page-breadcrumb')).length) {
$(e.target).closest('li').nextAll().remove();
PushState = $('.page-breadcrumb').children('li').each(function() {
return $(this).children().find('span.Title').text();
}).get().join("/");
console.log(PushState);
Current = $(e.target).closest('a').html();
$(e.target).closest('li').remove();
$('.page-breadcrumb').append(Current);
}
});
});
.page-bar {
box-sizing:border-box;
position: relative;
width:100%;
height:61px;
padding: 0 20px;
}
.page-bar .page-breadcrumb {
display: inline-block;
float: left;
padding: 20px 0;
margin: 0;
list-style: none;
}
.page-bar .page-breadcrumb>li {
display: inline-block;
}
.page-bar .page-breadcrumb>li,
.page-bar .page-breadcrumb>li a {
font-size: 14px;
color: #A3A3A3;
text-decoration: none;
}
.page-bar .page-breadcrumb>li a:hover {
text-decoration: underline;
}
.page-bar .page-breadcrumb>li>i.fa-arrow-right {
font-size: 12px;
margin: 0 5px;
position: relative;
opacity: .4;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<div class="page-bar">
<div class="page-breadcrumb">
<li>
<i class="fa fa-home"></i> <span class="Title">Dashboard</span>
</li>
<li><i class="fa fa-arrow-right"></i></li>
<li>
<a href="javascript:;">
<i class="fa fa-user"></i>
<span class="Title">Account</span>
</a>
</li>
<li><i class="fa fa-arrow-right"></i></li>
<li>
<a href="javascript:;">
<i class="fa fa-envelope"></i>
<span class="Title">Messages</span>
</a>
</li>
<li><i class="fa fa-arrow-right"></i></li>
<li></li>
<i class="fa fa-plus"></i>
<span class="Title">Compose</span>
</div>
</div>
Outcome
Dependant on where you click, the outcome is as follows (I clicked on 'Account'):
[object HTMLLIElement]/[object HTMLLIElement]/[object HTMLLIElement]
What I'm Trying To Achieve
If $(e.target) is $('.page-breadcrumb li a')
Initiate everything the script currently does
PushState should return (clicking on Messages example):
Dashboard/Account/Messages
Questions
How do I return the text only of each span.Title connectings all with '/'?
Using return in each callback is causing you to loose the data .If you even have this
PushState = $('.page-breadcrumb').children('li').each(function() {
return 0;
}).get().join("/");
you would still be getting the same results because what you are getting is just the outer <li> elements .So instead of returning use some variable in which you can store the individual results of eachs callback
Make some global like variable var v =[]; outside each and use below modification
$('.page-breadcrumb').children('li').each(function() {
var txt = $(this).children().find('span.Title').text();
if(txt != '')
v.push(txt);
});
PushState = v.join('/');
Target the selector you want in the event listener:
Change
$(document).on('click', function(e) {
To
$(document).on('click','.page-breadcrumb a' function(e) {
// "this" will be instance of .page-breadcrumb a
var spanText = $(this).find('.Title').text()
.....

Categories

Resources