div position relative to two other divs - javascript

I have a div composed of multiple divs that can collapse down, followed by another div under them.
Curently, as shown in the fiddle under, the bottom div only scrolls down upon clicking box 3 or box 1(the left column).
I would like the right column (boxes 2 and 4) to scroll down just like the left column, but I am failing so far.
Thanks for the help in advance.
var drop = document.getElementsByClassName("drop");
var i;
for (i = 0; i < drop.length; i++) {
drop[i].addEventListener("click", function() {
this.classList.toggle("active");
var collapse = this.previousElementSibling;
if (collapse.style.maxHeight) {
collapse.style.maxHeight = null;
} else {
collapse.style.maxHeight = collapse.scrollHeight + "px";
}
});
}
#panel {
background-color: white;
float: center;
position: relative;
width: 800px;
/* height: 500px; */
margin: 0 auto;
border-color: #B7B7B7;
border-width: 2px;
border-radius: 25px;
}
#box1 {
border: 2px solid #B7B7B7;
position: relative;
display: inline-block;
width: 250px;
top: 0;
left: 0;
border-radius: 5px;
transition: max-height 0.2s ease-out;
}
#box2 {
border: 2px solid #B7B7B7;
position: relative;
display: inline-block;
width: 525px;
top: 0;
float: right;
border-radius: 5px;
transition: max-height 0.2s ease-out;
}
#box3 {
border: 2px solid #B7B7B7;
display: inline-block;
top: 0;
left: 0;
width: 250px;
position: relative;
border-radius: 5px;
transition: max-height 0.2s ease-out;
}
#box4 {
border: 2px solid #B7B7B7;
display: inline-block;
position: relative;
top: 0;
float: right;
width: 525px;
border-radius: 5px;
transition: max-height 0.2s ease-out;
}
#travel {
margin: auto;
background-color: black;
border-style: solid;
border-color: #B7B7B7;
border-width: 2px;
border-radius: 5px;
position: relative;
margin-top: 15px;
width: 800px;
height: 300px;
}
.drop {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
border-radius: 5px;
bottom: 0;
}
.active, .drop:hover {
background-color: #ccc;
}
.collapse {
padding: 0 18px;
background-color: gray;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
<div id=panel>
<div id="box1">
<br>this is box 1<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div id="box2" style="margin-bottom: 15px;">
<br>this is box 2<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div id="box4">
<br>this is box 4<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div id="box3" style="margin-top: 15px;">
<br>this is box 3<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div id="travel">
</div>
</div>

As you made the box2 and box4 float on right, you will need a clearing element after all boxes to clear the effect of floating objects. I have added <div style="clear:both"></div> after boxes:
var drop = document.getElementsByClassName("drop");
var i;
for (i = 0; i < drop.length; i++) {
drop[i].addEventListener("click", function() {
this.classList.toggle("active");
var collapse = this.previousElementSibling;
if (collapse.style.maxHeight) {
collapse.style.maxHeight = null;
} else {
collapse.style.maxHeight = collapse.scrollHeight + "px";
}
});
}
#panel {
background-color: white;
float: center;
position: relative;
width: 800px;
/* height: 500px; */
margin: 0 auto;
border-color: #B7B7B7;
border-width: 2px;
border-radius: 25px;
}
#box1 {
border: 2px solid #B7B7B7;
position: relative;
display: inline-block;
width: 250px;
top: 0;
left: 0;
border-radius: 5px;
transition: max-height 0.2s ease-out;
}
#box2 {
border: 2px solid #B7B7B7;
position: relative;
display: inline-block;
width: 525px;
top: 0;
float: right;
border-radius: 5px;
transition: max-height 0.2s ease-out;
}
#box3 {
border: 2px solid #B7B7B7;
display: inline-block;
top: 0;
left: 0;
width: 250px;
position: relative;
border-radius: 5px;
transition: max-height 0.2s ease-out;
}
#box4 {
border: 2px solid #B7B7B7;
display: inline-block;
position: relative;
top: 0;
float: right;
width: 525px;
border-radius: 5px;
transition: max-height 0.2s ease-out;
}
#travel {
margin: auto;
background-color: black;
border-style: solid;
border-color: #B7B7B7;
border-width: 2px;
border-radius: 5px;
position: relative;
margin-top: 15px;
width: 800px;
height: 300px;
}
.drop {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
border-radius: 5px;
bottom: 0;
}
.active, .drop:hover {
background-color: #ccc;
}
.collapse {
padding: 0 18px;
background-color: gray;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
<div id=panel>
<div id="box1">
<br>this is box 1<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div id="box2" style="margin-bottom: 15px;">
<br>this is box 2<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div id="box4">
<br>this is box 4<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div id="box3" style="margin-top: 15px;">
<br>this is box 3<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div style="clear:both"></div>
<div id="travel">
</div>
</div>

Here's an approach using display: flex. I also moved the common styles of the boxes to a class .box.
var drop = document.getElementsByClassName("drop");
var i;
for (i = 0; i < drop.length; i++) {
drop[i].addEventListener("click", function() {
this.classList.toggle("active");
var collapse = this.previousElementSibling;
if (collapse.style.maxHeight) {
collapse.style.maxHeight = null;
} else {
collapse.style.maxHeight = collapse.scrollHeight + "px";
}
});
}
#panel {
background-color: white;
position: relative;
width: 800px;
/* height: 500px; */
margin: 0 auto;
border-color: #B7B7B7;
border-width: 2px;
border-radius: 25px;
display: flex;
flex-wrap: wrap;
align-items: flex-start;
}
.box {
border: 2px solid #B7B7B7;
position: relative;
transition: max-height 0.2s ease-out;
margin-bottom: 15px;
border-radius: 5px;
}
#box1 {
width: 250px;
}
#box2 {
width: 525px;
}
#box3 {
width: 250px;
}
#box4 {
width: 525px;
}
#travel {
margin: auto;
background-color: black;
border-style: solid;
border-color: #B7B7B7;
border-width: 2px;
border-radius: 5px;
position: relative;
width: 800px;
height: 300px;
}
.drop {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
border-radius: 5px;
bottom: 0;
}
.active, .drop:hover {
background-color: #ccc;
}
.collapse {
padding: 0 18px;
background-color: gray;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
<div id=panel>
<div id="box1" class="box">
<br>this is box 1<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div id="box2" class="box">
<br>this is box 2<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div id="box4" class="box">
<br>this is box 4<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div id="box3" class="box">
<br>this is box 3<br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div id="travel">
</div>
</div>

First, I can see that you styled these boxes separately even though they look basically the same. One problem with that method is that it becomes difficult to track which styles are peculiar to each box. (Just do some research on this)
In this your case, the major issue is the fact that you used the float property in box 2 and box 4.
When using float, you need another property overflow to manage the contents that are floating. If not, they might be treated as if they don't exist.
In your fiddle, you can make these changes:
First, clean up your html:
<div id=panel>
<div class="boxes">
<div class="left">
<div class="box" id="box1">
<br>this is box 1</br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div class="box" id="box3">
<br>this is box 3</br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
</div>
<div class="right">
<div class="box" id="box2">
<br>this is box 2</br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
<div class="box" id="box4">
<br>this is box 4</br>
<div class="collapse">
<p>a drop</p>
</div>
<button class="drop">view more</button>
</div>
</div>
</div>
<div id="travel">
</div>
</div>
Notice how I removed irrelevant inline styles. Too much of that can turn your markup into a mess when working with a bigger application. I also added classes - a cool way to prevent unnecessary repetition.
Now, your css would be cleaner this way:
.boxes {
overflow: auto;
margin-bottom: 10px;
}
.boxes .right {
width: 525px;
float: left;
padding-left: 10px;
}
.boxes .left {
width: 250px;
float: left;
padding-right: 10px;
}
.box {
border: 2px solid #B7B7B7;
position: relative;
display: inline-block;
border-radius: 5px;
transition: max-height 0.2s ease-out;
width: 100%;
margin-bottom: 10px;
}
Notice how I used overflow for any div whose child has a float property.

Related

How to place the top left of a div element to the top right of a button?

I am trying to place the top right of the div element friend_info to the top left of the button friend_button.
I have tried to use the code from https://javascript.info/coordinates#element-coordinates-getboundingclientrect but to no avail and I also tried to use this code:
var friend_button = document.getElementById("friend-button");
var friend_info = document.getElementById("friend_info");
friend_button.addEventListener("mouseover", function(){
var coords = friend_button.getBoundingClientRect();
var coordsOfInfo = $('.friend_info').width();
var subtractWidth = coords.left-coordsOfInfo;
friend_info.style.left = subtractWidth+"px";
friend_info.style.top = coords.top + "px";
friend_info.style.display = "block";
> });
friend_button.addEventListener("mouseout", function(){
friend_info.style.display = "none";
> });
but the div element disdplays in the middle of the button instead of the left hand side. Here is the html and css for the code I am working on.
HTML:
<html>
<head>
<title>Home</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<link rel="stylesheet" href="test.css">
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
</head>
<body>
<div class="header">
<h1 class="Search_Media">Search Media</h1>
<div class="navigationbar">
<form>
<input type="text" placeholder="Search...">
<input type="submit" value="Search">
</form>
</div>
</div>
<br />
<div class="middle">
<div class="headings">
<a class="active" href="Main_Page.html">Home</a>
Messages
Friends
User page
</div>
<div class="friends">
<h2>Friends</h2>
<button type="button" class="friend-button" id="friend-button">
<div class="media">
<img src="default-pic.png" class="mr-3" alt="Default Picture" width="50" height="50">
</div>
<div class="media-body">
<h5 class="mt-0">Friend1</h5>
<p>status: active</p>
</div>
</button>
<div class="friend_info" id="friend_info">
<video autoplay muted loop class="backgroundInfo">
<source src="Background.mp4" type="video/mp4">
</video>
<div class="d-flex">
<img src="default-pic.png" class="profile-picture" alt="Default Picture" width="200" height="200">
<div class="d-flex flex-column">
<div class="p-2">
<h1 class="Friend_Name">Friend1</h1>
</div>
<div class="p-1">
<h5>status: active</h5>
</div>
<div class="p-5">
<p class="info">Phone Number: 07914836605</p>
<p class="info">Name: Joe</p>
<p class="info">Surname: Smith</p>
<p class="info">Gender: Male</p>
<p class="info">Date of birth: 14/02/2003</p>
</div>
</div>
</div>
</div>
</div>
<div class="middle-grid">
<div class="user-post">
Create post:<br>
<form>
<textarea id="create_post" rows="10" cols = "50"></textarea><br>
<input type="submit" class="post-button" value="Post">
</form>
</div>
<div class="posts">
<div class="post">
<h3 id="existing_posts"><img src="default-pic.png" class="profile-pic" alt="Default Picture" width="50" height="50">Posts</h3>
<p>This is an example of a post. It will need to be boxed and made so that the name of the user goes above
the name of the likes and dislikes of the posts are to the left of the post and that the reply and report
functionalities are at the bottom right of the posts. It will also need a box around it to show where the post starts and ends.</p>
<div class="options">
Like
Comment
Report
</div>
</div>
</div>
</div>
</div>
<div class="bottom">
<button onclick="topFunction()" id="myBtn" title="Go To Top">Top</button>
</div>
<script src="Main_Page.js"></script>
</body>
</html>
CSS:
body{
background-color: black;
color: white;
}
.Search_Media{
position: fixed;
top: 0px;
left: 0%;
padding: 10px;
width: 100%;
background-color: aqua;
z-index: 0;
color: black;
margin-top: 0px;
}
.Search-media{
text-decoration: none;
color: black;
}
.Search-media:hover{
text-decoration: none;
color: black;
}
.navigationbar{
background-color: aqua;
width: auto;
position: fixed;
padding-top:15px;
left: 50%;
margin-left: -88.5px;
color: black;
}
.headings{
left:20.17%;
height: 100;
width: 200;
position: fixed;
margin-top: 40px;
background-color: black;
}
.headings a{
padding: 6px 0px 6px 0px;
text-decoration: none;
font-size: 20px;
color: white;
display: block;
}
.headings a:hover{
color: black;
background-color: aqua;
}
.headings a.active{
background-color: aqua;
color: black;
}
.friend-button{
width: 90%;
margin-bottom: 1px;
background-color: black;
color: white;
cursor: pointer;
border-radius: 5px;
}
.friend-button:hover{
background-color: aqua;
color: black;
}
.middle{
display: flex;
flex-direction: row;
justify-content: space-evenly;
padding: 10px;
margin: 0% auto;
width: 75%;
height: auto;
text-align: center;
}
.middle-grid{
border-right: 1px solid white;
border-left: 1px solid white;
padding-top: 37px;
width: 50%;
}
.user-post{
width: auto;
margin: 0% auto;
}
.post-button{
margin: 0% auto;
color: black;
padding-right: 50;
padding-left: 50;
padding-top: 5;
padding-bottom: 5;
}
textarea{
resize: none;
color: black;
}
h3{
margin-top: 5px;
margin-bottom: 1px;
}
.posts{
width:75%;
text-align: left;
padding:10px;
margin-left: auto;
margin-right:auto;
}
.post{
padding-bottom: 20px;
}
.post:nth-child(odd){
color: black;
background-color: lightblue;
z-index: 2;
}
.post p{
margin-top: 5px;
}
.options{
float: right;
}
.options .report{
color: red;
}
h2{
margin-top: auto;
margin-bottom: auto;
}
.friends{
position: fixed;
right: 10%;
margin-top: 70px;
padding: 0px;
margin-bottom: auto;
border: 1px solid white;
width: 15%;
overflow-y: scroll;
top: 0;
bottom: 0;
}
.media-body{
text-align: left;
}
h5{
font-size: 20;
margin-bottom: 2px;
}
#myBtn {
display: none;
position: fixed;
top: 95%;
left: 50%;
margin: 0% auto;
transform: translate(-50%, -50%);
z-index: 99;
border: none;
outline: none;
background-color: red;
color: white;
cursor: pointer;
padding: 15px;
border-radius: 10px;
font-size: 18px;
}
#myBtn:hover {
background-color: darkred;
}
.friend_info{
display: none;
position: fixed;
width: 20vw;
height: 20vh;
text-align: center;
left: 0px;
right:0px;
top: 0px;
}
.backgroundInfo{
position: inherit;
z-index: -99;
max-width: 800px;
max-height: 600px;
left: inherit;
top: inherit;
}
.d-flex{
color: white;
}
.Friend_Name{
padding: 0px;
margin: 0px;
font-size: 60px;
}
h5{
font-size: 30px;
}
.info{
font-size: 20px;
}
.p-5{
border: 0%;
width: auto;
height: 0px;
bottom: 0px;
left: 0px;
top: 0px;
border-width: 0px;
padding: 2rem !important;
}
I had the correct idea, but wrong execution. The correct javascript is the following:
var friend_button = document.getElementById("friend-button");
var friend_info = document.getElementById("friend_info");
friend_button.addEventListener("mouseover", function(){
var coords = friend_button.getBoundingClientRect();
var coordsOfInfo = $('.backgroundInfo').width();
var subtractWidth = coords.left-coordsOfInfo;
friend_info.style.left = subtractWidth+"px";
friend_info.style.top = coords.top + "px";
friend_info.style.display = "block";
});
friend_button.addEventListener("mouseout", function(){
friend_info.style.display = "none";
});
Notice how I changed which element I got the width off. I changed it to the backgroud width and now displays just how I want.

Create a new div on selecting the menu in javascript

I was working the project where there is two view and three view (or if possible multiple view). Here in my code selected option normal creates two div placed vertically and Three view creates three view vertically (i.e adding one more div in Normal option). Here default one is Normal
.header{
width:100%;
height:40px;
background:#f4f3f1;
border: 1px solid #dbdfe5;
text-align: center;
font-size: 20px;
padding-top:0px;
color: green;
font-weight:bold;
}
.container{
width: 100%;
min-height: 150px;
padding-top:2px;
display: flex;
}
.container .box1{
background: #ffffff;
border-radius: 3px;
border: 2px solid #dbdfe5;
flex: 1;
overflow: auto;
}
.container .box1 #inside{
width:100%;
height:35px;
border: 1px solid #dbdfe5;
padding-bottom:10px;
border-radius: 1px;
background:#f4f3f1;
}
.container .box1.box2{
background: #ffffff;
border-radius: 3px;
overflow: auto;
}
.container .box1.box2 #second{
width:100%;
height:35px;
border: 1px solid #dbdfe5;
border-radius: 5px;
padding-bottom:10px;
background:#f4f3f1;
}
.tabb{
float:left;
margin-left:10px;
margin:5px;
display: inline-block;
padding: 6px 12px;
border-radius: 5px;
}
<body>
<div class="header">
<select class="tabb" name="opt" id="opt" >
<option value="two">Normal </option>
<option value="three">Three view</option>
</select>
Demo </div>
<div class="container">
<div class="box1">
<div id="inside" >
<center>Inside Box1</center>
</div>
<center>Main Box1</center>
</div>
<div class="box1 box2">
<div id="second" >
<center>Inside Box2</center>
</div>
<center>Main Box2</center>
</div>
</div>
</body>
Currently by default two div is created, how can I create 3 div on selecting the Three view of selection menu, placed vetically. In code how to dynamically create <div class="box1 box2 box3"> .
You mean this?
Also IDs need to be unique
$(function() {
$("#opt").on("change", function() {
$(".box3").toggle(this.value == "three"); // toggle will show if true, hide if false
}).change()
})
.header {
width: 100%;
height: 40px;
background: #f4f3f1;
border: 1px solid #dbdfe5;
text-align: center;
font-size: 20px;
padding-top: 0px;
color: green;
font-weight: bold;
}
.container {
width: 100%;
min-height: 150px;
padding-top: 2px;
display: flex;
}
.container .box1 {
background: #ffffff;
border-radius: 3px;
border: 2px solid #dbdfe5;
flex: 1;
overflow: auto;
}
.container .box1 #first {
width: 100%;
height: 35px;
border: 1px solid #dbdfe5;
padding-bottom: 10px;
border-radius: 1px;
background: #f4f3f1;
}
.container .box1.box2 {
background: #ffffff;
border-radius: 3px;
overflow: auto;
}
.container .box1.box2 #second {
width: 100%;
height: 35px;
border: 1px solid #dbdfe5;
border-radius: 5px;
padding-bottom: 10px;
background: #f4f3f1;
}
.container .box1.box2.box3 #third {
width: 100%;
height: 35px;
border: 1px solid #dbdfe5;
border-radius: 5px;
padding-bottom: 10px;
background: #f4f3f1;
}
.tabb {
float: left;
margin-left: 10px;
margin: 5px;
display: inline-block;
padding: 6px 12px;
border-radius: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="header">
<select class="tabb" name="opt" id="opt">
<option value="two">Normal </option>
<option value="three">Three view</option>
</select>
Demo </div>
<div class="container">
<div class="box1">
<div id="first">
<center>Inside Box1</center>
</div>
<center>Main Box1</center>
</div>
<div class="box1 box2">
<div id="second">
<center>Inside Box2</center>
</div>
<center>Main Box2</center>
</div>
<div class="box1 box2 box3">
<div id="third">
<center>Inside Box3</center>
</div>
<center>Main Box3</center>
</div>
</div>
</body>
To add views, try this:
var views = {
"three": ".box3",
"four": ".box3,.box4"
}
$(function() {
$("#opt").on("change", function() {
var view = views[this.value]; // if three or four
$(".box3,.box4").hide(); // hide anyway
if (view) $(view).show(); // show box2 or box3 and box4
}).change()
})
.header {
width: 100%;
height: 40px;
background: #f4f3f1;
border: 1px solid #dbdfe5;
text-align: center;
font-size: 20px;
padding-top: 0px;
color: green;
font-weight: bold;
}
.container {
width: 100%;
min-height: 150px;
padding-top: 2px;
display: flex;
}
.container .box1 {
background: #ffffff;
border-radius: 3px;
border: 2px solid #dbdfe5;
flex: 1;
overflow: auto;
}
.container .box1 #first {
width: 100%;
height: 35px;
border: 1px solid #dbdfe5;
padding-bottom: 10px;
border-radius: 1px;
background: #f4f3f1;
}
.container .box1.box2 {
background: #ffffff;
border-radius: 3px;
overflow: auto;
}
.container .box1.box2 #second {
width: 100%;
height: 35px;
border: 1px solid #dbdfe5;
border-radius: 5px;
padding-bottom: 10px;
background: #f4f3f1;
}
.container .box1.box2.box3 #third {
width: 100%;
height: 35px;
border: 1px solid #dbdfe5;
border-radius: 5px;
padding-bottom: 10px;
background: #f4f3f1;
}
.container .box1.box2.box4 #fourth {
width: 100%;
height: 35px;
border: 1px solid #dbdfe5;
border-radius: 5px;
padding-bottom: 10px;
background: #f4f3f1;
}
.tabb {
float: left;
margin-left: 10px;
margin: 5px;
display: inline-block;
padding: 6px 12px;
border-radius: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="header">
<select class="tabb" name="opt" id="opt">
<option value="two">Normal </option>
<option value="three">Three view</option>
<option value="four">Four view</option>
</select>
Demo </div>
<div class="container">
<div class="box1">
<div id="first">
<center>Inside Box1</center>
</div>
<center>Main Box1</center>
</div>
<div class="box1 box2">
<div id="second">
<center>Inside Box2</center>
</div>
<center>Main Box2</center>
</div>
<div class="box1 box2 box3">
<div id="third">
<center>Inside Box3</center>
</div>
<center>Main Box3</center>
</div>
<div class="box1 box2 box4">
<div id="fourth">
<center>Inside Box4</center>
</div>
<center>Main Box4</center>
</div>
</div>
</body>
first you must addEventListener for your select input and when you chose Three View:
//create div element
const div = documnet.createElement('div');
// add class name
div.className = 'box1 box2 box3';
// get container
const container = document.getElementsByClassName('container')[0];
// add div to container
container.appendChild(div);

jQuery add class to one element instead of all with same class

I have multiple battery meters on a page that get their power bar width values dynamically and I'm trying to add a 'lowBatt' class with JS and jQuery to the existing 'bar' class when when the 'bar' class width is less than 2px and I have 2 issues:
It is only checking the first 'bar' class element width.
If the width of that first 'bar' class elements width is less than 2px it adds the 'lowBatt' class to all 'bar' class elements.
What I need to happen is check all 'bar' class elements widths and any that are less than 2px width add the class 'lowBatt' to only those 'bar' class elements, leaving the other 'bar' class elements with greater than 2px widths alone.
$('.bar').each(function(i, obj){
if ($('.bar').width() < 2) {
$(this).addClass('lowBatt')};
});
.progress {
height: 8px;
width: 16px;
background: #fff;
border-radius: 0;
border: 1px solid #fff;
float: left;
margin-bottom: 0;
}
.progress .bar {
background-color: #000;
background-image: none;
background-repeat: repeat-x;
box-shadow: none;
box-sizing: border-box;
color: #ffffff;
float: left;
font-size: 12px;
height: 100%;
text-align: center;
text-shadow: none;
transition: width 0.6s ease 0s;
}
.battTip {
height: 6px;
margin-top: 1px;
margin-right: -3px;
width: 2px;
float: right;
background: #fff;
border: 1px solid #000;
border-left: none;
}
.battIcnWrap {
width: 18px;
height: 10px;
margin: 0 auto;
float: left;
border: 1px solid #000;
margin-right: 10px;
}
.bar.lowBatt {
background: #ff0000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 1px;"></div>
</div>
<div class="battTip"></div>
</div>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 8px;"></div>
</div>
<div class="battTip"></div>
</div>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 1px;"></div>
</div>
<div class="battTip"></div>
</div>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 15px;"></div>
</div>
<div class="battTip"></div>
</div>
Thanks for any help.
Inside your loop you need to use this to refer to the element being looped on. So use:
if ($(this).width() < 2) {
$('.bar').each(function(i, obj){
if ($(this).width() < 2) {
$(this).addClass('lowBatt')};
});
.progress {
height: 8px;
width: 16px;
background: #fff;
border-radius: 0;
border: 1px solid #fff;
float: left;
margin-bottom: 0;
}
.progress .bar {
background-color: #000;
background-image: none;
background-repeat: repeat-x;
box-shadow: none;
box-sizing: border-box;
color: #ffffff;
float: left;
font-size: 12px;
height: 100%;
text-align: center;
text-shadow: none;
transition: width 0.6s ease 0s;
}
.battTip {
height: 6px;
margin-top: 1px;
margin-right: -3px;
width: 2px;
float: right;
background: #fff;
border: 1px solid #000;
border-left: none;
}
.battIcnWrap {
width: 18px;
height: 10px;
margin: 0 auto;
float: left;
border: 1px solid #000;
margin-right: 10px;
}
.bar.lowBatt {
background: #ff0000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 1px;"></div>
</div>
<div class="battTip"></div>
</div>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 8px;"></div>
</div>
<div class="battTip"></div>
</div>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 1px;"></div>
</div>
<div class="battTip"></div>
</div>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 15px;"></div>
</div>
<div class="battTip"></div>
</div>
Just replace $(.bar) with the .each loop with $(this).
$('.bar').each(function(i, obj) {
if ($(this).width() < 2) {
$(this).addClass('lowBatt')
};
});
.progress {
height: 8px;
width: 16px;
background: #fff;
border-radius: 0;
border: 1px solid #fff;
float: left;
margin-bottom: 0;
}
.progress .bar {
background-color: #000;
background-image: none;
background-repeat: repeat-x;
box-shadow: none;
box-sizing: border-box;
color: #ffffff;
float: left;
font-size: 12px;
height: 100%;
text-align: center;
text-shadow: none;
transition: width 0.6s ease 0s;
}
.battTip {
height: 6px;
margin-top: 1px;
margin-right: -3px;
width: 2px;
float: right;
background: #fff;
border: 1px solid #000;
border-left: none;
}
.battIcnWrap {
width: 18px;
height: 10px;
margin: 0 auto;
float: left;
border: 1px solid #000;
margin-right: 10px;
}
.bar.lowBatt {
background: #ff0000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 1px;"></div>
</div>
<div class="battTip"></div>
</div>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 8px;"></div>
</div>
<div class="battTip"></div>
</div>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 1px;"></div>
</div>
<div class="battTip"></div>
</div>
<div class="battIcnWrap">
<div class="progress">
<div class="bar" style="width: 15px;"></div>
</div>
<div class="battTip"></div>
</div>

Go to accordion tab when click button Vanilla JavaScript

Right now I have an accordion and interactive cycle I made using pure CSS. When a user clicks on a certain box on the cycle it opens up that specific accordion tab. Is it possible using vanilla JavaScript (no JQuery) to have it also scroll down to the specific tab when a user clicks a box on the cycle? Anything helps, cheers.
.container1 {
width: 250px;
height: 250px;
position: absolute;
left: 0px;
right: 0px;
margin: auto;
transform: scale(0.85);
}
.ele,
.arrow,
.circle {
position: absolute;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
margin: auto;
}
#one {
transform: rotate(0deg) translateY(-130px) rotate(0deg);
}
#two {
transform: rotate(60deg) translateY(-130px) rotate(-60deg);
}
#three {
transform: rotate(120deg) translateY(-130px) rotate(-120deg);
}
#four {
transform: rotate(180deg) translateY(-130px) rotate(-180deg);
}
#five {
transform: rotate(240deg) translateY(-130px) rotate(-240deg);
}
#six {
transform: rotate(300deg) translateY(-130px) rotate(-300deg);
}
.ele {
display: inline-block;
background-color: #1f497d;
width: 105px;
height: 50px;
border-width: 2px;
border-style: solid;
border-color: #ededed;
border-radius: 7px;
box-shadow: 0px 1px 5px #888888;
z-index: 3;
}
.ele:hover {
cursor: pointer;
transform: scale(1.019);
border-color: f4f4f4;
background-color: #214d84;
box-shadow: 0px 2px 9px #888888;
zoom: 1.02;
}
.circle {
background-color: #006850;
width: 85px;
height: 85px;
border-width: 3px;
border-style: solid;
border-color: #fefefe;
border-radius: 50%;
box-shadow: 0px 1px 5px #888888;
}
.arrow {
color: #cccfd7;
width: 250px;
height: 250px;
border: 17px solid;
border-radius: 50%;
position: absolute;
z-index: 1;
left: -17px;
}
#two:hover ~ .arrow {
border-top-color: #006850;
transform: rotate(24deg);
}
#three:hover ~ .arrow {
border-top-color: #006850;
transform: rotate(66deg);
}
#four:hover ~ .arrow {
border-top-color: #006850;
border-right-color: #006850;
transform: rotate(25deg);
}
#five:hover ~ .arrow {
border-top-color: #006850;
border-right-color: #006850;
border-bottom-color: #006850;
transform: rotate(26deg);
}
#six:hover ~ .arrow {
border-top-color: #006850;
border-right-color: #006850;
border-bottom-color: #006850;
transform: rotate(66deg);
}
#one:hover ~ .arrow {
border-color: #006850;
}
#one:hover ~ .circle:after {
border-top-color: #006850;
}
.circle:before {
content: "";
display: block;
width: 30px;
height: 30px;
position: absolute;
bottom: 0;
top: -96px;
left: -36px;
background: #fff;
background-color: white;
transform: rotate(-120deg);
z-index: 1;
}
.circle:after {
content: "";
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid #d0d3d8;
position: absolute;
top: -83px;
left: -44px;
transform: rotate(-120deg);
z-index: 2;
}
.text1line {
font-size: 13px;
margin-top: 14%;
display: block;
color: white;
text-decoration: none;
text-align: center;
}
.text1line:hover {
text-decoration: none;
}
.text2line {
font-size: 13px;
margin-top: 6%;
display: block;
color: white;
text-decoration: none;
text-align: center;
}
.text2line:hover {
text-decoration: none;
}
.textcircle {
font-size: 15px;
margin-top: 37.5%;
display: block;
color: white;
text-decoration: none;
text-align: center;
}
.textcircle:hover {
text-decoration: none;
}
.wrapper {
max-width: 960px;
margin: 0 auto;
}
/* Acordeon styles */
.tab {
position: relative;
margin-bottom: 1px;
width: 100%;
overflow: hidden;
}
.bold {
font-weight: bold;
color: #005bab;
}
.top {
margin-top: -20px;
text-align: center;
font-size: 13px;
}
.input {
position: absolute;
opacity: 0;
z-index: -1;
}
.label {
position: relative;
text-align: center;
display: block;
padding: 0 0 0 1em;
color: #005bab;
background: #e2ecf6;
font-size: 14px;
font-family: Verdana;
font-weight: bold;
line-height: 6;
cursor: pointer;
}
.label:hover {
background-color: #d2e2ef;
}
.tab-content {
max-height: 0;
overflow: hidden;
padding: 0px;
-webkit-transition: max-height .5s;
-o-transition: max-height .5s;
transition: max-height .5s;
padding-left: 35px;
background: #dce7f2;
}
.tab-content .container {
padding: 1em;
margin: 0;
opacity: 0;
transform: scale(0.75);
-webkit-transition: transform 0.75s, opacity .75s;
-o-transition: transform 0.75s, opacity .75s;
transition: transform 0.75s, opacity .75s;
background: #f4f8fc;
}
/* :checked */
.input:checked~.tab-content {
max-height: 35em;
}
.input:checked~.tab-content .container {
transform: scale(1);
opacity: 1;
}
/* Icon */
.label::after {
position: absolute;
left: 0;
top: 0;
display: block;
width: 3em;
height: 3em;
line-height: 3;
text-align: center;
-webkit-transition: all .35s;
-o-transition: all .35s;
transition: all .35s;
}
.input[type=checkbox]+.label::after {
content: "+";
}
.input[type=radio]+.label::after {
content: "";
}
.input[type=checkbox]:checked+.label::after {
transform: rotate(315deg);
}
.input[type=radio]:checked+.label::after {
transform: rotateX(180deg);
}
.bottombar {
content: "";
display: block;
height: 1em;
width: 100%;
background-color: #00688B;
}
<div class="container1">
<div class="ele" id="one"><label style="color:#fff;" class="text2line" for="tab-one">Select A Top Team</label></div>
<div class="ele" id="two"><label style="color:#fff;" class="text2line" for="tab-two">Get Off To A Great Start</label></div>
<div class="ele" id="three"><label style="color:#fff;" class="text2line" for="tab-train">Train For Success</label></div>
<div class="ele" id="four"><label style="color:#fff;" class="text2line" for="tab-manage">Manage Work For Results</label></div>
<div class="ele" id="five"><label style="color:#fff;" class="text1line" for="tab-grow">Grow Careers</label></div>
<div class="ele" id="six"><label style="color:#fff;" class="text2line" for="tab-build">Build A Deep Bench</label></div>
<div class="arrow"></div>
<div class="circle"><a style="color:#fff;" class="textcircle">Manager</a></div>
</div>
<br style="line-height:400px;"/>
<div class="top">
<p>
<span style="font-family: verdana;"><strong>Click the "</strong><span class="ms-rteThemeForeColor-5-0"><strong>+</strong></span><strong>" to expand and the "</strong><span class="ms-rteThemeForeColor-5-0"><strong>x</strong></span><strong>" to collapse</strong></span>
</p>
</div>
<div class="wrapper">
<div class="tab">
<input name="tabs" class="input" id="tab-one" type="checkbox"/>
<label class="label" for="tab-one">Select A Top Team</label>
<div class="tab-content">
<div class="container">
<p>Content goes here</p>
</div>
</div>
</div>
<div class="tab">
<input name="tabs" class="input" id="tab-two" type="checkbox" />
<label class="label" for="tab-two">Get Off To A Great Start</label>
<div class="tab-content">
<div class="container">
<p>Content goes here</p>
</div>
</div>
</div>
<div class="tab">
<input name="tabs" class="input" id="tab-train" type="checkbox"/>
<label class="label" for="tab-train">Train For Success</label>
<div class="tab-content">
<div class="container">
<p>Content goes here</p>
</div>
</div>
</div>
<div class="tab">
<input name="tabs" class="input" id="tab-manage" type="checkbox"/>
<label class="label" for="tab-manage">Manage Work For Results</label>
<div class="tab-content">
<div class="container">
<p>Content goes here</p>
</div>
</div>
</div>
<div class="tab">
<input name="tabs" class="input" id="tab-grow" type="checkbox"/>
<label class="label" for="tab-grow">Grow Careers</label>
<div class="tab-content">
<div class="container">
<p>Content goes here</p>
</div>
</div>
</div>
<div class="tab">
<input name="tabs" class="input" id="tab-build" type="checkbox"/>
<label class="label" for="tab-build">Build A Deep bench</label>
<div class="tab-content">
<div class="container">
<p>Content goes here</p>
</div>
</div>
</div>
<div class="bottombar"></div>
</div>
Use document.getElementById("button_id").addEventListener("click", function); for trigger.
Use window.location.hash = '#div_id';to get focus.
Example:
document.getElementById("bt1").addEventListener("click", getfocus1);
document.getElementById("bt2").addEventListener("click", getfocus2);
document.getElementById("bt3").addEventListener("click", getfocus3);
document.getElementById("bt4").addEventListener("click", getfocus4);
document.getElementById("bt5").addEventListener("click", getfocus5);
function getfocus1(){
window.location.hash = '#tab1';
}
function getfocus2(){
window.location.hash = '#tab2';
}
function getfocus3(){
window.location.hash = '#tab3';
}
function getfocus4(){
window.location.hash = '#tab4';
}
function getfocus5(){
window.location.hash = '#tab5';
}
div{
width:100%;
height:300px;
text-align: center;
}
<button type="button" id = "bt1">Click Me for get focus in div 1!</button>
<button type="button" id = "bt2">Click Me for get focus in div 2!</button>
<button type="button" id = "bt3">Click Me for get focus in div 3!</button>
<button type="button" id = "bt4">Click Me for get focus in div 4!</button>
<button type="button" id = "bt5">Click Me for get focus in div 5!</button>
<div id ="tab1">
Data 1
</div>
<div id ="tab2">
Data 2
</div>
<div id ="tab3">
Data 3
</div>
<div id ="tab4">
data 4
</div>
<div id ="tab5">
data 5
</div>
I hope this is what you want.

Transition: translate and z-index

It seems like CSS transition: translate() has a conflict with z-index and I can't create a fold effect for my block.
HTML
<div class="card">
<div class="arrow-box">
<span>Destinations</span>
</div>
<div class="choice" style="z-index: 1">
<div class="choice-header">New York</div>
<div class="choice-content" style="background: red"></div>
</div>
<div class="choice" style="z-index: 2">
<div class="choice-header">Boston</div>
<div class="choice-content" style="background: #801566"></div>
</div>
<div class="choice" style="z-index: 3">
<div class="choice-header">Seattle</div>
<div class="choice-content" style="background: green"></div>
</div>
<div class="choice" style="z-index: 4">
<div class="choice-header">Washington</div>
<div class="choice-content" style="background: #1e3180"></div>
</div>
<div class="choice" style="z-index: 5">
<div class="choice-header">San Francisco</div>
<div class="choice-content" style="background: #e5f400"></div>
</div>
</div>
CSS
.choice {
transition: .6s;
margin-bottom: -264px;
z-index: 0;
}
.choice-content {
transition: .6s;
}
.choice-header {
height: 44px;
background: #49647a;
transition: .6s;
transition-timing-function: ease-in-out;
text-align: center;
line-height: 44px;
color: white;
font-size: 22px;
font-family: 'PFBagueSansProLight', sans-serif;
text-transform: uppercase;
cursor: pointer;
}
.choice-header:after {
content: '';
position: absolute;
margin-top: 15px;
right: 22px;
display: inline-block;
width: 18px;
height: 18px;
background: url("/static/pages/img/polygon.png") no-repeat center;
transition: 0.6s;
}
.choice:last-child {
margin-bottom: 0;
}
.choice.selected {
transform: translate3d(0, -265px, 0);
margin-bottom: -265px;
}
.choice.selected > .choice-header:after {
transform: rotate(180deg);
}
.choice-content {
height: 265px;
}
.card {
height: 527px;
background: #ebebeb;
overflow: hidden;
}
.arrow-box {
position: relative;
background: #49647a;
height: 44px;
margin-bottom: 260px;
}
.arrow-box:after {
top: 100%;
left: 50%;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-color: rgba(73, 100, 122, 0);
border-top-color: #49647a;
border-width: 16px 165px 0 165px;
border-style: solid;
margin-left: -165px;
}
.arrow-box span {
text-align: center;
vertical-align: middle;
display: block;
height: 44px;
line-height: 44px;
font-size: 22px;
color: white;
}
JavaScript
$('.choice-header').click(function() {
var elem = $(this).parents().eq(1).find('.choice');
var i = $(this).hasClass('selected') ? 0 : 1;
var n = elem.index($(this).parent());
elem.removeClass('selected');
elem.slice(0, n + i).addClass('selected');
});
Codepen
You can see that .choice-content interferes with other .choices during the transition animation. Is there a way to avoid that?
You have assigned z-index to each .choice which is correct but you forgot to give position to them. Codepen
.choice {
transition: .6s;
margin-bottom: -264px;
z-index: 0;
position: relative;
}
Point, Note:
Only works on positioned elements(position: absolute;, position: relative; or position: fixed;).

Categories