I have a div at the top of the page, middle, and bottom. When I refresh the page each time I would like the top and bottom divs to switch without affecting the middle div at all. Thanks in advance for any answers.
My jsfiddle
Code:
.top {
background: lightpink;
padding: 40px;
}
.content {
background: white;
}
.bottom {
background: lightblue;
padding: 40px;
}
<div class="top">
1
</div>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam fuga impedit, obcaecati, commodi dolores quasi odit numquam esse aliquid, alias natus doloribus nihil eius dicta eaque, nobis veritatis! Praesentium, laboriosam.
</div>
<div class="bottom">
2
</div>
It can be done using sessionStorage and cloning divs.
What this is doing is taking a copy of each div in the clone variables and then using a sessionStorage value to toggle between the states. If the sessionStorage value is 0 then it will do nothing but change the value, if it's 1 then it'll remove the divs and then add them in the new order from the cloned content.
var divOne = document.querySelector('.top');
var divTwo = document.querySelector('.bottom');
var divOneClone = document.querySelector('.top').outerHTML;
var divTwoClone = document.querySelector('.bottom').outerHTML;
var divContent = document.querySelector('.content');
if (sessionStorage.getItem('refreshState')) {
if (sessionStorage.getItem('refreshState') == 1) {
divOne.parentNode.removeChild(divOne);
divTwo.parentNode.removeChild(divTwo);
divContent.insertAdjacentHTML('beforebegin', divTwoClone);
divContent.insertAdjacentHTML('afterend', divOneClone);
sessionStorage.setItem('refreshState', 0);
} else {
sessionStorage.setItem('refreshState', 1);
}
} else {
sessionStorage.setItem('refreshState', 0);
}
Here's a working JS Fiddle example.
Related
This is my first post here.
i have a big problem. i am in a bootcamp, currently.
I have a site and sections
const bookmarkButton = document.querySelectorAll('.pictureBook')
bookmarkButton.forEach(function (setIt) {
setIt.addEventListener('click', () => {
setIt.classList.toggle('bookmarkChecked')
})
})
.pictureBook {
all: unset;
background-image: url(/img/bookmark-svgrepo-com.svg);
background-size: cover;
width: 100px;
height: 100px;
position: absolute;
top: -15px;
right: -10px;
cursor: pointer;
opacity: 0.5;
}
.bookmarkChecked {
opacity: 1;
}
<section class="main__section">
<h2 class="question__title">Frage</h2>
<p class="question__text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nulla eius
voluptatibus modi voluptates nisi quam expedita fugiat repudiandae
animi ab.
</p>
<button class="pictureBook"></button>
<button class="showanswer__btn">Antwort anzeigen</button>
<p class="answershowed hideanswer">
Lorem ipsum dolor sit, amet consectetur adipisicing elit. A nemo
libero tempore dolore numquam dolorum sed cumque nihil explicabo
ullam.
</p>
</section>
Now i can click the bookmark "svg" and opacity gone to 100 % ( bookmark set, color black )
I have a button. and i want, only show the "classes" i added the class for bookmarked it.
I am on the Limit. Google doesn`t help. Maybe you can?
When i click another button in my footer, the site Show please only the active sections with the class bookmarkChecked.
Thank you very much.
A bookmarked button has the bookmarkChecked class. So you can use
querySelectorAll to choose only the bookmarked button.
Use forEach to loop over the list of buttons.
Inside the forEach callback get the corresponding section for each button using the closest method
Now you can hide the bookmarked section using a class to set display none.
If all this needs to happen after a button click, then do the following inside an addEventListener.
So i have been trying to build this accordion component for a review section for a couple of days...I'm really new to javascript and have figured it out mostly except the review section that collapses out is being shown in the initial state so on a page reload you see the section expanded right away, and only is hidden when you click the expand arrow. I would rather it be hidden on the initial state so it only is shown after the user clicks the expand arrow.
I have a div with the class="reviewsHide" as a wrapper and another div with the class="reviewsActive" as a wrapper. Its written in sass and any solution i try to come up with in targeting the wrapper with javascript doesn't apply its children class styles so it ends up not looking right. Inside the main container wrappers i have 3 more container sections each is its own container. with a couple of classes inside each of those containers.
<div class="reviewsHide">
<div class="reviewsActive">
<div class="reviewsActive__top">
<button href="#" class="reviewsActive__top-smallTxt">Write A Review →</button>
<span class="reviewsActive__top-largeTxt">Reviews(10)</span>
<button href="#" class="reviewsActive__top-smallTxt">More Reviews →</button>
</div>
<div class="reviewsActive__bottomL">
<div class="reviewsActive__bottomL-title">
<img class="starSmall"src="img/main/StarRating.svg" alt="Star Rating"> Title
</div>
<p class="reviewsActive__bottomL-reviewP">
  Lorem ipsum dolor sit amet consectetur adipisicing elit. Perferendis, dolorem quae! Quidem officiis rerum nam, veritatis ullam, placeat est doloremque exercitationem, a quis sequi tempora blanditiis eligendi consequuntur. Ipsam a hic eligendi? Facilis vero fugit omnis ducimus inventore ipsam libero ad expedita numquam, ullam delectus ratione modi, atque esse veritatis.
</p>
</div>
<div class="reviewsActive__bottomR">
<div class="reviewsActive__bottomR-title">
<img class="starSmall"src="img/main/StarRating.svg" alt="Star Rating"> Title
</div>
<p class="reviewsActive__bottomR-reviewP">
  Lorem ipsum dolor sit amet consectetur adipisicing elit. Perferendis, dolorem quae! Quidem officiis rerum nam, veritatis ullam, placeat est doloremque exercitationem, a quis sequi tempora blanditiis eligendi consequuntur.
</p>
</div>
</div>
</div>
.reviewsHide.show {
height: 15rem;
display: none;
}
.reviewsActive {
display: flex;
flex-direction: row;
flex-wrap: wrap;
background-color: white;
height: 22.5rem;
font-family: 'Montserrat Alternates', sans-serif;
&__top {
display: flex;
flex-direction: row;
justify-content: space-evenly;
align-items: center;
height: 3rem;
width: 100%;
&-smallTxt {
cursor: pointer;
font-size: 1.05rem;
}
&-largeTxt {
font-size: 2rem;
}
}
&__bottomL {
#include reviewsBottom;
margin: auto 1rem .75rem 1rem;
&-title {
#include reviewsTitle;
}
&-reviewP {
#include reviewsParagraph;
}
}
&__bottomR {
#include reviewsBottom;
margin: 1rem 1rem .75rem auto;
&-title {
#include reviewsTitle;
}
&-reviewP {
#include reviewsParagraph;
}
}
}
// Get the button, and when the user clicks on it, execute myFunction
document.querySelector(".span").onclick = function() {myFunction()};
/* myFunction toggles between adding and removing the show class, which is used to hide and show the dropdown content */
function myFunction() {
document.querySelector(".reviewsHide").classList.toggle("show");
/* This selector below is for the arrow animation to rotate on click */
document.querySelector(".span").classList.toggle("spanshow");
}
Re-wrote my javascript to this and its working as intended
const reviewsOpen = () => {
var expandArrow = document.querySelector(".span");
var hide = document.querySelector(".reviewsHide");
expandArrow.addEventListener('click', () => {
hide.classList.toggle("reviewsHide");
expandArrow.classList.toggle("spanshow")
});
}
reviewsOpen();
This question already has answers here:
How do I detect a click outside an element?
(91 answers)
Closed 2 years ago.
I'm trying to find multiple ways to close a sidebar menu that pops out from the left side. The idea of this is to have a page with an "Open/Close Menu" button. As expected this button should be able to open and close the menu with clicked, but I also want to include an option of closing it when simply clicking outside the menu bar.
My thought process behind this is to add a div that surrounds all of the content on the page, and gives it a class name of "notMenu". I would define the dimensions of this to be the entire page and give it a z-index of 1. When the menu pops up, it would be on top of .notMenu with a z-index of 2, yet I can't seem to get it to work.
var menuBtn = document.querySelector('.menuBtn');
var sidebar = document.querySelector('.sidebar');
var closeMenuBtn = document.querySelector('.closeMenuBtn');
var notMenu = document.querySelector('.notMenu');
var nav = 'closed'
menuBtn.addEventListener('click', function() {
if (nav === 'closed') {
sidebar.style.display = 'block'
nav = 'open'
} else {
sidebar.style.display = 'none'
nav = 'closed'
}
});
// closeMenuBtn.addEventListener('click',function(){
// sidebar.style.display = 'none'
// });
closeMenuBtn.addEventListener('click', function() {
sidebar.style.display = 'none';
nav = 'closed';
});
/*
notMenu.addEventListener('click',function(){
sidebar.style.display = 'none'
nav = 'closed';
})
*/
h1 {
text-align: center;
}
.menuBtn {
position: relative;
left: 50%;
transform: translateX(-50%);
}
.closeMenu {
font-size: 30px;
z-index: 2;
}
.sidebar {
position: absolute;
top: 0;
height: 100vh;
width: 300px;
background: grey;
display: none;
z-index: 2;
}
.notMenu {
position: absolute;
top: 0;
height: 100%;
width: 100%;
z-index: 1;
}
<body>
<div class="notMenu">
<h1> Header </h1>
<div class="sidebar">
<ul>
<li><a href=''>Link1</a></li>
<li><a href=''>Link2</a></li>
<li><a href=''>Link3</a></li>
</ul>
<button class="closeMenuBtn">Close Menu</button>
</div>
<button class="menuBtn">Open/Close Menu</button>
<div class="content1">
<br><br> Lorem ipsum dolor sit amet consectetur, adipisicing elit. Aspernatur quia ipsam optio, veritatis corrupti exercitationem quae itaque accusamus voluptas ipsa consequuntur nostrum, culpa, cum dolore incidunt ducimus harum minus doloremque?
</div>
<div class="content2">
<br><br> Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum quia laboriosam ut accusantium itaque adipisci vitae error provident voluptate, dolorem veniam dignissimos atque accusamus aut rem quos esse fugit voluptas soluta laudantium.
Nam voluptates maxime sapiente, pariatur voluptatibus mollitia quia.
</div>
</div>
<!--closes .notMenu-->
</body>
CodePen Link
Alternatively, is there a way to do this without designated a new class as .notMenu? I assume there is a possibility to do this with e.target in JS with if statements.
function(e){
if (e.target !== 'sidebar'){
sidebar.style.display = 'none'
}
}
The issue I ran into with this is that e.target returns an object. I'm unable to define which objects represent the sidebar and which ones do not, therefore I can't determine if the area outside the sidebar is being clicked.
try this
window.addEventListener('mouseup', function(e) {
var x = document.querySelector('.sidebar');
if (event.target != document.querySelector(".icon")) {
x.style.display = "none";
}
});
var menuBtn = document.querySelector('.menuBtn');
var sidebar = document.querySelector('.sidebar');
var closeMenuBtn = document.querySelector('.closeMenuBtn');
var notMenu = document.querySelector('.notMenu');
var nav = 'closed'
menuBtn.addEventListener('click',function(){
if (nav === 'closed'){
sidebar.style.display='block'
nav = 'open'
}
else{
sidebar.style.display = 'none'
nav = 'closed'
}
});
closeMenuBtn.addEventListener('click',function(){
sidebar.style.display = 'none';
nav = 'closed';
});
// fire event if click is outside of sidebar and menubtn
window.onclick = function(event) {
if (event.target !== sidebar && event.target !== menuBtn) {
sidebar.style.display = "none";
console.log('clicked');
}
}
h1{
text-align:center;
}
.menuBtn{
position:relative;
left:50%;
transform:translateX(-50%);
}
.closeMenu{
font-size:30px;
z-index:2;
}
.sidebar{
position:absolute;
top:0;
height:100vh;
width:300px;
background:grey;
display:none;
z-index:2;
}
.notMenu{
position:absolute;
top:0;
height:100%;
width:100%;
z-index:1;
}
<div class="notMenu">
<h1> Header </h1>
<div class="sidebar">
<ul>
<li><a href =''>Link1</a></li>
<li><a href =''>Link2</a></li>
<li><a href =''>Link3</a></li>
</ul>
<button class="closeMenuBtn">Close Menu</button>
</div>
<button class="menuBtn">Open/Close Menu</button>
<div class="content1">
<br><br>
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Aspernatur quia ipsam optio, veritatis corrupti exercitationem quae itaque accusamus voluptas ipsa consequuntur nostrum, culpa, cum dolore incidunt ducimus harum minus doloremque?
</div>
<div class="content2">
<br><br>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum quia laboriosam ut accusantium itaque adipisci vitae error provident voluptate, dolorem veniam dignissimos atque accusamus aut rem quos esse fugit voluptas soluta laudantium. Nam voluptates maxime sapiente, pariatur voluptatibus mollitia quia.
</div>
</div>
try this
I am trying to create a simple Read More example. It consists of a paragraph and a button with half of the paragraph enclosed in a span tag which is initially set to hidden. When user clicks on Read More button the hidden span shows up. I have got the working code but just want to do a fade in effect like JQuery but with pure Javascript. Anyone please help.
var span = document.getElementsByTagName('span')[0];
var hideshow = document.getElementById('hideshow');
span.style.display = 'none';
hideshow.onclick = function() {
span.style.display = 'block';
};
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsa maiores dolore earum ducimus molestiae, aut. <span>Quisquam consequuntur, maiores et, doloremque atque provident similique consequatur totam voluptas vitae veniam, molestiae laborum.</span></p>
<button id="hideshow">Read More</button>
One approach is to use a CSS3 transition in order to transition the element's opacity.
In the example below, the class fade-in is added to the child span element when clicking the button.
var button = document.querySelector('.read-more');
button.addEventListener('click', function(event) {
var span = event.target.previousElementSibling.querySelector('span');
span.classList.add('fade-in');
});
.show-more span {
display: inline-block;
height: 0;
overflow: hidden;
transition: opacity 2s;
opacity: 0;
}
.show-more span.fade-in {
height: auto;
opacity: 1;
}
<p class="show-more">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsa maiores dolore earum ducimus molestiae, aut. <span>Quisquam consequuntur, maiores et, doloremque atque provident similique consequatur totam voluptas vitae veniam, molestiae laborum.</span></p>
<button class="read-more">Read More</button>
If you want an approach that works for multiple elements, you could also use the following:
var buttons = document.querySelectorAll('.read-more');
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function(event) {
var span = event.target.previousElementSibling.querySelector('span');
span.classList.add('fade-in');
});
}
.show-more span {
display: inline-block;
height: 0;
overflow: hidden;
transition: opacity 2s;
opacity: 0;
}
.show-more span.fade-in {
height: auto;
opacity: 1;
}
<p class="show-more">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsa maiores dolore earum ducimus molestiae, aut. <span>Quisquam consequuntur, maiores et, doloremque atque provident similique consequatur totam voluptas vitae veniam, molestiae laborum.</span></p>
<button class="read-more">Read More</button>
<p class="show-more">Another shorter paragraph. <span>Quisquam consequuntur, maiores et, doloremque atque provident similique consequatur totam voluptas vitae veniam, molestiae laborum.</span></p>
<button class="read-more">Read More</button>
Starting here
span.style.opacity = 0;
You'll need to gradually transition the opacity to here.
span.style.opacity = 1;
You'll need to use an asynchronous construct (setTimeout/setInterval/requestAnimationFrame) for iterating, because a synchronous one (while/for/for-in/forEach) will block the main thread, preventing the browser from actually rendering the element with the updated opacity.
function fadeIn(element) {
function transition() {
if(element.style.opacity < 1) {
requestAnimationFrame(transition);
element.style.opacity = Number(element.style.opacity) + 0.05;
}
}
transition();
}
Alternatively, if you're happy to use CSS (rather than pure JS) you can do this with classes and transitions.
.out {
opacity: 0;
transition-duration: 0.5s;
}
.in {
opacity: 1;
transition-duration: 0.5s;
}
Make sure that the element has the out class when it arrives in the DOM, then when you're ready to fade it in, swap it for the in class and the browser will handle the animation for you.
var duration = 2000; // msecs
document.getElementById('hideshow').onclick = () => {
requestAnimationFrame((start_time) => {
var anim = (time) => {
var p = (time - start_time) / duration;
(p < 1) && requestAnimationFrame(anim);
span.style.opacity = 1 - p;
}
anim(start_time);
})
}
I've got a responsive site I'm building Where I have two elements that overlap each other. THe size of the elements will change depending on the browser width as will the overlap and consequently I need to set left-padding on the right element dynamically.
I'm unsure of how to proceed with this. Have set up a Fiddle here.
html:
<div class="container">
<div class="row copy intro">
<section class="red">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolor illum nobis ullam neque, harum, magni. Reprehenderit veritatis in deleniti incidunt dolore dolores ex id expedita.</p>
<p>Corporis soluta ducimus ut quasi libero nesciunt, eligendi autem, consequatur error sapiente labore, officia tempora in voluptas non deleniti veniam officiis, quis vero consequuntur quia!</p>
</section>
<section class="white">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolor illum nobis ullam neque, harum, magni. Reprehenderit veritatis in deleniti incidunt dolore dolores ex id expedita.</p>
<p>Corporis soluta ducimus ut quasi libero nesciunt, eligendi autem, consequatur error sapiente labore, officia tempora in voluptas non deleniti veniam officiis, quis vero consequuntur quia!</p>
</section>
</div>
</div><!--container-->
css:
/* line 3, ../build/sass/_intro.scss */
.intro {
background: #0079c2;
position: relative;
padding: 15px;
padding-bottom: 150px;
}
/* line 9, ../build/sass/_intro.scss */
.intro section {
position: relative;
padding: 100px;
width: 60%;
-moz-border-radius: 500px;
-webkit-border-radius: 500px;
border-radius: 500px;
}
/* line 26, ../build/sass/_intro.scss */
.intro section.red {
background: rgba(238, 45, 36, 0.85);
color: #fff;
z-index: 200;
}
/* line 31, ../build/sass/_intro.scss */
.intro section.red h1 {
font-size: 24px;
}
/* line 45, ../build/sass/_intro.scss */
.intro section.white {
background: #fff;
color: #0079c2;
position: absolute;
top: 150px;
right: 15px;
}
js:
// set intro sections width = height
$(document).ready(function() {
var circleWidth= $('.intro section.red').outerWidth();
$('.intro section').css('min-height', circleWidth + 'px');
$('.intro section.white').css('width', circleWidth + 'px');
});
Thank you for your time.
Use % for padding and adjust accordingly. See this revised Fiddle for an example.
The revised Fiddle comments out:
$('.intro section.white').css('width', circleWidth + 'px');
Fixing the width of the white circle means that it is not responsive any more. If you need to do that for some reason, you would have to make adjustments.
Here's a JSFiddle doing what I think you want: http://jsfiddle.net/6yro5vhx/2/
Basically I user offset() & outerWidth() on the two elements to work out the overlap, and then call calculatePadding() function on documentready & resize events.
function calculatePadding() {
var white = $('.intro section.white');
var red = $('.intro section.red');
var extraPadding = 20;
var distanceLeft = white.offset().left;
var redDistanceRight = red.offset().left + red.outerWidth();
var paddingLeft = (redDistanceRight - distanceLeft) + extraPadding;
$('.intro section.white').css('padding-left', paddingLeft + 'px');
}
Update the answer below mine is a far better way to achieve what you're looking for. CSS is a much better responsive approach than excess JQuery.