Show/hide div or image when scrolling - javascript

Is there a way to show an image or a div when scrolling down a web page and hide it when not scrolling and vice versa?
So in the code below the red div would be displayed when not scrolling, and the green div would be displayed only when scrolling.
.square {
position: fixed;
width: 100px;
height: 100px;
}
.green {
background: green;
display: none;
}
.red {
background: red;
}
.container {
width: 100%;
height: 3000px;
}
<div class="container">
<div class="square green"></div>
<div class="square red"></div>
</div>
The end goal is to achieve something like this: https://mailchimp.com/annual-report/ where the character appears to be walking when the user scrolls, and stands still when the user stops. Is this easily achievable?

You just need an eventListener that listen to a scroll event. However this has the issue that it only recoginze when you scroll but not when you stop scrolling. For that you can use this answer that explains how to listen for a "scroll-stop"
To make the code shorter and easier, I removed your display: none from the green box. I added a new class d-none that contains this proeprty now instead. By default it is added to the green box.
With classList.toggle('d-none') I can toggle class within both boxes which makes it easier then to address and then add or remove the class for every box on its own.
var timer = null;
var box = document.querySelectorAll('.square');
window.addEventListener('scroll', function() {
if (timer !== null) {
clearTimeout(timer);
} else {
box.forEach(el => el.classList.toggle('d-none'));
}
timer = setTimeout(function() {
box.forEach(el => el.classList.toggle('d-none'));
}, 150);
}, false);
.d-none {
display: none;
}
.square {
position: fixed;
width: 100px;
height: 100px;
}
.green {
background: green;
/* display: none; */
/* removed */
}
.red {
background: red;
}
.container {
width: 100%;
height: 3000px;
}
<div class="container">
<div class="square green d-none"></div>
<div class="square red"></div>
</div>

You just need a setTimeout function:
(function($) {
$(function() {
$(window).scroll(function() {
$('.square.red').show()
$('.square.green').hide()
clearTimeout($.data(this));
$.data(this, setTimeout(function() {
$('.square.red').hide()
$('.square.green').show()
}, 250));
});
});
})(jQuery);
.square {
position: fixed;
width: 100px;
height: 100px;
}
.green {
background: green;
}
.red {
background: red;
display: none;
}
.container {
width: 100%;
height: 3000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="square green"></div>
<div class="square red"></div>
</div>

Related

Opening a div 'popup' from clicking a parent div

When clicking the 'test' div, it opens up the div price-list-test in a popup way like this:
However, I am stuck on trying to get the div to pop up on the 'right' alignment of the element rather than left, like this:
How can I achieve this?
$(document).ready(function() {
$(".test").each(function() {
$(this).click(function() {
var leftpos = $(this).offset() - window.screen.width;
$(this).children().css("left", leftpos.left);
$(this).children().css("display", "block");
});
})
});
.price-list-test {
width: 100px;
height: 100px;
background-color: red;
color: white;
display: none;
position: absolute;
}
.test {
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="test">
Open
<div class="price-list-test">
Test
</div>
</div>
Make 'test' class position relative, after that set 'price-list-test' left : 0%
.test {
postion: relative;
}
.price-list-test {
left: 0 %;
width: 100px;
height: 100px;
background-color: red;
color: white;
display: none;
position: absolute;
}

How to make a div go over another div when clicking on it?

I have these 2 divs and when I click on div 1 I want it to go over the second div, and if I click on Div 1 again I want it to go back to its original position (I want Div 1 to increase its width so it goes over the second Div). Here is my code where I have my 2 divs next to each other. Can anyone point me in the right direction on how to accomplish this? Thanks a lot in advance!
NOTE:
- No jQuery please. I'm trying to accomplish this with javascript and css.
#parent {
display: flex;
}
#narrow {
width: 200px;
background: lightblue;
}
#wide {
flex: 1;
background: lightgreen;
}
<div id="parent">
<div id="wide">Div 1</div>
<div id="narrow">Div 2</div>
</div>
If you're willing to ditch flex, you can use a combination of float , postion:absolute and transition so that the main div "slides over" the other div
document.querySelector("#wide").onclick = toggleWidth;
function toggleWidth() {
this.classList.toggle("active");
}
#parent {
position: relative;
}
#narrow {
width: 200px;
background: lightblue;
float: right;
}
#wide {
position: absolute;
background: lightgreen;
width: calc(100% - 200px);
transition: width 2s;
}
#wide.active {
width: 100%;
opacity: 0.9;
}
<div id="parent">
<div id="wide">Div 1</div>
<div id="narrow">Div 2</div>
</div>
Note: Changing the opacity is purely optional, I've only done it to further illustrate the "slide over" effect.
Try this
#parent {
display: flex;
}
#narrow {
width: 20vw;
position: absolute;
left: calc(80vw - 10px);
background: lightblue;
z-index: 1;
margin: 0;
}
#wide {
width: calc(80vw - 10px);
background: lightgreen;
transition: all 0.3s ease-out;
}
.wider {
width: 100vw!important;
z-index: 2;
}
<div id="parent">
<div id="wide" onclick="myFunction()">Div 1</div>
<div id="narrow">Div 2</div>
</div>
<script>
function myFunction() {
var element = document.getElementById("wide");
element.classList.toggle("wider");
}
</script>
You can try it using JavaScript.
First, you prepare your CSS:
#narrow {
width: 200px;
transition: 0.32s;
overflow: hidden;
}
#wide.fullwidth ~ #narrow {
width: 0;
opacity: 0;
}
Then, the JavaScript, like this:
document.querySelector("#wide").onclick = changeDivWidth;
var wideFull = false;
function changeDivWidth () {
if (!wideFull) {
this.classList.add("fullwidth");
wideFull = true;
return; // if variable wideFull is false, function stops here
}
wideFull = false;
this.classList.remove("fullwidth");
}
Shorter approach using toggle();
document.querySelector("#wide").onclick = changeDivWidth;
function changeDivWidth () {
this.classList.toggle("fullwidth");
}
Are you looking for something like this : JSFiddle ?
JavaScript (Pure) :
function HideDivOne(){
var wide = document.getElementById("wide");
var narrow = document.getElementById("narrow");
if (wide.style.width == "70%"){
wide.style.width = "100%";
narrow.style.width = "0%";
narrow.style.opacity = "0";
}
else{
wide.style.width = "70%";
narrow.style.width = "30%";
narrow.style.opacity = "1";
}
}
CSS
#parent {
display: flex;
}
#narrow {
width: 30%;
background: lightblue;
height: 20px;
transition: 0.2s;
}
#wide {
width: 70%;
flex: 1;
background: lightgreen;
height: 20px;
transition: 0.2s;
}
HTML
<div id="parent">
<div id="wide" onclick="HideDivOne()">Div1</div>
<div id="narrow" onclick="HideDivTwo()">Div2</div>
</div>
You can change the z-index of the divs based on your desired effect. My suggestion is using jQuery. On click on div 1 add a class to the div that modify the zindex, that is, if the class is not already added, if so, remove it.

How to keep user's scrolling place when resizing div

I wanted to do a cool menu effect for a website I'm working on. I'm having a div act as the the section for the main content. When the user opens the menu, the main content div will resize and move out of the way, revealing the menu. However, when I do this with the code I have written, it always loses my scrolling place on the page. Is there any way to keep my place on the page when it shrinks and also when it expands back again? Below is what I have. Thank you in advance!
function shrinkPage() {
var element = document.getElementById("mock-body");
element.classList.toggle("mock-body-on-burger");
var z = document.getElementById("mock-body-container");
z.classList.toggle("mock-body-container-on-burger");
var x = document.getElementById("body");
x.classList.toggle("body-on-burger");
};
body {
margin: 0;
background:#000;
}
.body-on-burger {
max-width: 100%;
overflow-x:hidden;
}
.mock-body-container{
height:100vh;
}
.mock-body-container-on-burger {
height:100vh;
transform: scale(0.4) translate(130%);
overflow: hidden;
}
.mock-body-size-change{
overflow: scroll;
}
.mock-body {
position:relative;
background: #fff;
margin-left: 50px;
}
.container {
position: fixed;
height:50px;
width:50px;
cursor: pointer;
}
.container #icon {
width: 16px;
height: 8px;
position: relative;
margin: 0px auto 0;
top: 40%;
}
.container #icon .bars {
height: 1px;
background: #fff;
}
.myDiv {
height:500px;
}
.one {
background:red;
}
.two {
background:green;
}
.three {
background:blue;
}
<body id="body">
<div class="menu-activator" onclick="shrinkPage()">
<div class="container usd">
<div id="icon">
<div class="bars first"></div>
</div>
</div>
</div>
<div id="mock-body-container" class="mock-body-container">
<div id="mock-body" class="mock-body">
<div class="myDiv one"></div>
<div class="myDiv two"></div>
<div class="myDiv three"></div>
</div>
</div>
</body>
Please take a look at the snippet below. Notice how the overflow property is used.
You have to scroll mock-body-container to keep its scrolling position.
You're scrolling body instead, so when you scale mock-body-container there is nothing to scroll in body and you loose the scrolling position.
function shrinkPage() {
var element = document.getElementById("mock-body");
element.classList.toggle("mock-body-on-burger");
var z = document.getElementById("mock-body-container");
z.classList.toggle("mock-body-container-on-burger");
var x = document.getElementById("body");
x.classList.toggle("body-on-burger");
};
body {
margin: 0;
background:#000;
}
.body-on-burger {
max-width: 100%;
overflow-x:hidden;
}
.mock-body-container{
height:100vh;
overflow:auto;
}
.mock-body-container-on-burger {
height:100vh;
transform: scale(0.4) translate(130%);
}
.mock-body-size-change{
overflow: scroll;
}
.mock-body {
position:relative;
background: #fff;
margin-left: 50px;
}
.container {
position: fixed;
height:50px;
width:50px;
cursor: pointer;
}
.container #icon {
width: 16px;
height: 8px;
position: relative;
margin: 0px auto 0;
top: 40%;
}
.container #icon .bars {
height: 1px;
background: #fff;
}
.myDiv {
height:500px;
}
.one {
background:red;
}
.two {
background:green;
}
.three {
background:blue;
}
<body id="body">
<div class="menu-activator" onclick="shrinkPage()">
<div class="container usd">
<div id="icon">
<div class="bars first"></div>
</div>
</div>
</div>
<div id="mock-body-container" class="mock-body-container">
<div id="mock-body" class="mock-body">
<div class="myDiv one"></div>
<div class="myDiv two"></div>
<div class="myDiv three"></div>
</div>
</div>
</body>
Once you know the element that was in focus it should be relatively easy. If you need to find which element was last in focus, you can do that with a scroll function. If you need this as well let me know and I will update my answer.
If you know that #mock-body is the last element in focus, just scroll back to it after the resize.
In this example I've used jQuery as it makes this interaction easier, but this can be done (albeit more verbosely) with vanilla JS as well.
$('html, body').animate({
scrollTop: $('#mock-body').offset().top
}, 0); // If you want the animation to be smoother you can increase 0 to a higher number
A simple way to do it is to remember the position of the document scroll and reapply it when you getting back to "normal" view:
let savedScroll;
function shrinkPage() {
let _s = (el) => document.querySelector(el),
s_ = (d) => !d.classList.contains('body-on-burger'),
x = _s('#body'),
element = _s('#mock-body'),
z = _s('#mock-body-container');
if (s_(x)) {
savedScroll = document.documentElement.scrollTop;
}
element.classList.toggle("mock-body-on-burger");
z.classList.toggle("mock-body-container-on-burger");
x.classList.toggle("body-on-burger");
if (s_(x)) {
document.documentElement.scrollTop = savedScroll;
}
};
Check it out:
let savedScroll;
function shrinkPage() {
let _s = (el) => document.querySelector(el),
s_ = (d) => !d.classList.contains('body-on-burger'),
x = _s('#body'),
element = _s('#mock-body'),
z = _s('#mock-body-container');
if (s_(x)) {
savedScroll = document.documentElement.scrollTop;
}
element.classList.toggle("mock-body-on-burger");
z.classList.toggle("mock-body-container-on-burger");
x.classList.toggle("body-on-burger");
if (s_(x)) {
document.documentElement.scrollTop = savedScroll;
}
};
body {
margin: 0;
background: #000;
}
.body-on-burger {
max-width: 100%;
overflow-x: hidden;
}
.mock-body-container {
height: 100vh;
}
.mock-body-container-on-burger {
height: 100vh;
transform: scale(0.4) translate(130%);
overflow: hidden;
}
.mock-body-size-change {
overflow: scroll;
}
.mock-body {
position: relative;
background: #fff;
margin-left: 50px;
}
.container {
position: fixed;
height: 50px;
width: 50px;
cursor: pointer;
}
.container #icon {
width: 16px;
height: 8px;
position: relative;
margin: 0px auto 0;
top: 40%;
}
.container #icon .bars {
height: 1px;
background: #fff;
}
.myDiv {
height: 500px;
}
.one {
background: red;
}
.two {
background: green;
}
.three {
background: blue;
}
<body id="body">
<div class="menu-activator" onclick="shrinkPage()">
<div class="container usd">
<div id="icon">
<div class="bars first"></div>
</div>
</div>
</div>
<div id="mock-body-container" class="mock-body-container">
<div id="mock-body" class="mock-body">
<div class="myDiv one"></div>
<div class="myDiv two"></div>
<div class="myDiv three"></div>
</div>
</div>
</body>
Legend: _s(el) returns first match of el and s_(d) checks if d has class body-on-burger.
The simple way to do this is to determine the change in height during the resize, and scroll that much.
const heightChange = newHeight - initialHeight;
scrollableDiv.scrollTop = scrollableDiv.scrollTop - heightChange;
In my case I am using a resize method I wrote, so I do this work inside of a window.addEventListener("mousemove", handleResize); when I know the div in actively being resized by the user.
This will still work fine with native html resizable elements, you just need to figure out how/when to listen for resize/drag events accordingly.

with javascript onclick add classname to a div

I want to achieve with javascript something like when i clink on any of thumbnail (btn-1, btn-2 and btn-3) the specific class should be add to box div dynamically.
my code: JSFiddle
document.getElementById('btn-1').onclick = function() {
document.getElementById('box').className = 'bg-1';
}
#box {
background-color: darkgray;
width: 200px;
height: 200px;
}
.thumbnail {
width: 30px;
height: 30px;
border: 1px solid;
margin: 5px;
position: relative;
float: left;
}
#btn-1 {
background-color: red;
}
#btn-2 {
background-color: green;
}
#btn-3 {
background-color: blue;
}
.bg-1 {
background-color: red;
}
.bg-2 {
background-color: blue;
}
.bg-3 {
background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box"></div>
<div class="thumbnail" id="btn-1"></div>
<div class="thumbnail" id="btn-2"></div>
<div class="thumbnail" id="btn-3"></div>
You javascript is working, but your CSS isn't.
You need to add !important as follows to .bg-1, .bg-2 and .bg-3
.bg-1 {
background-color: red !important;
}
Otherwise the id styling is taking preference over the class styling
You can see the classname is being added if you right click on the grey div and choose inspect element in Chrome.
Instead of bothering with classes, use simply a data- attribute like: data-bg="#f00"
$('[data-bg]').css('background', function () {
$(this).on('click', () => $('#box').css('background', this.dataset.bg));
return this.dataset.bg;
});
#box {
background: darkgray;
width: 120px; height: 120px;
}
[data-bg] {
width: 30px; height: 30px;
margin: 5px;
float: left;
}
<div id="box"></div>
<div data-bg="red"></div>
<div data-bg="#00f"></div>
<div data-bg="rgb(255,0,180)"></div>
<div data-bg="linear-gradient(to right, #E100FF, #7F00FF)"></div>
<script src="//code.jquery.com/jquery-3.1.0.js"></script>
You want to use jquery .addClass() function:
$('.myButton').addClass('myNewClass');
The function would probably look something like this:
$(function () {
$('.thumbnail').click(function() {
$('#box').addClass($(this).attr('id'));
});
})
You can get all the thumbnails as an array, and then iterate through the array and dynamically add an event listener to each, which will add the desired className to box when clicked:
var thumbnails = document.getElementsByClassName('thumbnail');
Array.from(thumbnails).forEach(function(thumbnail) {
var id = thumbnail.id;
thumbnail.addEventListener('click', function() {
document.getElementById('box').className = id.replace('btn', 'bg')
});
});

How to remove hover state when the element moves

I have this example:
<div class="container">
<div class="bp"></div>
</div>
http://jsfiddle.net/VKwjD/20/
if you hover the same square, his color changes; if you click, the parent size changes so the square move.
My problem is: If you don't move your mouse after the click, the square stays in the hover state... Why ?
It's possible to remove this state after the click? without moving the mouse...
Thank you for your help
HTML:
<div class="container">
<div class="bp" id="bp"></div>
</div>
CSS:
.container {
background: #FF0000;
width: 200px;
height: 200px;
position: relative;
}
.container.hide {
width: 50px;
}
.bp {
background: #00FFFF;
width: 30px;
height:30px;
top:0px;
right:0px;
position:absolute;
cursor: pointer;
}
.bp:hover{
background: #0000FF!important;
}
JavaScript:
$(document).ready(function() {
$('.bp').click(function() {
if($('.container').hasClass('hide')) {
$('.container').removeClass('hide');
var l1 = document.getElementById('bp');
l1.style.background = '#00FFFF';
}
else {
$('.container').addClass('hide');
var l1 = document.getElementById('bp');
l1.style.background = '#0000FF';
}
});
});

Categories

Resources