Whats wrong with my code? See Tabs 1-2, and then Tab 3.
I recently posted this question: 'How can i change the height of active tabs dynamically?' and received the following code.
As you can see, tab 1 and 2 are working fine. (Posted original question with 2 tabs. But after adding more tabs however, the dynamical change of height is not working anymore. Any suggestions?
Much appreciated
document.getElementById('tab').style.height = document.querySelector(`#tab div`).getBoundingClientRect().height + 'px'
const btn = [].slice.call(document.getElementsByTagName('button'))
btn.forEach((item, index) => {
item.addEventListener('click',function(){
btn.forEach((item) => {item.classList.remove('active')})
item.classList.add('active')
document.getElementById('tab').setAttribute('data-tab', index)
const currentTab = index === 0 ? document.querySelector(`#tab div`) : document.querySelector(`#tab div + div`)
document.getElementById('tab').style.height = currentTab.getBoundingClientRect().height + 'px'
})
}
)
.wrapper {
overflow: hidden;
}
.tabs {
position: relative;
-webkit-transition: all .9s ease-in-out;
-moz-transition: all .9s ease-in-out;
-ms-transition: all .9s ease-in-out;
-o-transition: all .9s ease-in-out;
transition: all .9s ease-in-out;
}
.active {
color:blue;
}
.tabs> * {
width: 100%;
}
.tabs[data-tab='1'] {
transform: translateX(-100%);
}
.tabs[data-tab='2'] {
transform: translateX(-200%);
}
.tabs[data-tab='3'] {
transform: translateX(-300%);
}
.tabs[data-tab='4'] {
transform: translateX(-400%);
}
.inliner {
white-space: nowrap;
}
.inliner > * {
display: inline-block;
*display: inline;
*zoom: 1;
font-size: 1rem;
letter-spacing: normal;
vertical-align: top;
word-spacing: normal;
white-space: normal;
}
<div class="wrapper">
<button> Tab 1</button>
<button> Tab 2</button>
<button> Tab3</button>
<div id="tab" class="tabs inliner">
<div>
<h2>Content 1 </h2>
</div>
<div>
<h2>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam </h2>
</div>
<div> <h3>TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT</h3>
</div>
</div>
</div>
<p>The Height of this text does not keep changing dynamically when clicking Tab no3</p>
I think you should make the variable currentTab point to the correct current tab.just like this
const currentTab = document.querySelector(`#tab div:nth-of-type(${index + 1})`)
I recently started making a little website project and I'm struggling a bit with customizing my scrollbar.
I got so far that the scrollbar is only visible when you hover over it but that's not exactly my goal. I want it to be hidden when the user didn't scroll for a certain period of time. This is what I got so far:
<style>
::-webkit-scrollbar {
width: 6px;
height: 12px;
}
::-webkit-scrollbar-track {
background: rgba(242, 242, 242, 0);
}
::-webkit-scrollbar-thumb {
background: rgba(221, 221, 221, 0);
border-radius: 3px;
}
/*Commented because I don't want it to show when I just hover the site
body:hover::-webkit-scrollbar-thumb {
background: rgb(0, 0, 0);
}
*/
body.scrolling::-webkit-scrollbar-thumb,
::-webkit-scrollbar-thumb:horizontal:hover,
::-webkit-scrollbar-thumb:vertical:hover {
background: rgb(0, 0, 0);
}
::-webkit-scrollbar-thumb:horizontal:active,
::-webkit-scrollbar-thumb:vertical:active {
background: rgb(0, 0, 0);
}
</style>
<script>$(window).scroll(function() {
$('body').addClass('scrolling');
alert("!!");
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
$('body').removeClass('scrolling');
}, 250));
});</script>
This is my first post on a forum like this so please just tell me if I have to provide more info and which info is missing.
I think its just a typo. Change the closing style tag to </style>. It can't be tested very well if theres an alert popping up every time you scroll. Remove alert("!!"); or change it to console.log("!!");
[LATER]
As you want the scrollbar to fade in and out with a transition, you'll have to use an element that covers it and animate its opacity. It's not possible to put an element above the document's scrollbar though. That's why you have to wrap the whole page inside a div and customize its scrollbar.
document.querySelector('.scroll-box').addEventListener('scroll', hideCoverBar);
document.querySelector('.scroll-box').addEventListener('mousemove', hideCoverBar);
var showTimeout;
function hideCoverBar() {
document.querySelector('.cover-bar').classList.add('hidden');
clearTimeout(showTimeout);
showTimeout = setTimeout(showCoverBar, 1000);
}
function showCoverBar() {
document.querySelector('.cover-bar').classList.remove('hidden');
}
body,
html {
margin: 0;
padding: 0;
font-family: monospace;
}
.main {
padding: 20px;
}
h1 {
font-size: 50px;
margin: 0;
}
p {
font-size: 12px;
margin: 0;
}
img {
display: block;
margin: 0 auto;
padding: 20px;
max-width: 100%;
box-sizing: border-box;
}
.scroll-bar-wrap {
width: 100vw;
position: relative;
}
.scroll-box {
width: 100%;
height: 100vh;
overflow-y: scroll;
}
.scroll-box::-webkit-scrollbar {
width: .4em;
}
.scroll-box::-webkit-scrollbar,
.scroll-box::-webkit-scrollbar-thumb {
overflow: visible;
border-radius: 4px;
}
.scroll-box::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, .2);
}
.cover-bar {
position: absolute;
background: #fff;
pointer-events: none;
height: 100%;
top: 0;
right: 0;
width: .4em;
-webkit-transition: all .5s;
opacity: 1;
}
.cover-bar.hidden {
opacity: 0;
}
<div class="scroll-bar-wrap">
<div class="scroll-box">
<div class="main">
<h1>Lorem ipsum dolor sit amet
</h1>
<img src="http://placekitten.com/600/400" />
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
</p>
</div>
</div>
<div class="cover-bar"></div>
</div>
fiddle: https://jsfiddle.net/71fjr0Lz/
I want to do infinite scroll in plain Javascript. I saw several tutorials but all of them fetch some random data from some api. I understand the code from tutorials but I don't know how to get data in order, not random.
I want to do something similar like here: https://codepen.io/FlorinPop17/pen/RwwvKYJ but I want to use data from my local file. Let's assume it's data.js and has code like it:
data = [{}, {}]
so it's array of objects and let's assume the content of objects is like here: https://jsonplaceholder.typicode.com/posts/
How would you change the code from this codepen to display posts one by one in order? I guess, the function getPost should have parameter "id" and every time this function is called the parameter should be plus 1? But how to do it? Or maybe I should iterate through data.js and on every iteration check if user scrolled to bottom?
You simply have to change the getPost() function to use your inline blog_data which contains all the available posts. The current offset is saved in a global variable post_offset which is increased by every getPost() call so the order will stay the same and no post is shown multiple times.
// all the blog entries that are available
const blog_data = [{
title: "Blog Entry 1",
body: "This is the example body text for entry 1."
},{
title: "This is number two",
body: "Also blog entry number 2 has some content."
},{
title: "Blog entry three",
body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."
},{
title: "Blog entry four",
body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."
},{
title: "Blog entry five",
body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."
},{
title: "Blog entry six",
body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."
}];
const container = document.getElementById('container');
const loading = document.querySelector('.loading');
let post_offset = 0;
getPost();
getPost();
getPost();
window.addEventListener('scroll', () => {
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
if(clientHeight + scrollTop >= scrollHeight - 5) {
// show the loading animation
showLoading();
}
});
function showLoading() {
if(post_offset < blog_data.length){
loading.classList.add('show');
// load more data
setTimeout(getPost, 1000)
}
else{
// end has been reached, no more posts available
}
}
async function getPost() {
if(post_offset < blog_data.length){
addDataToDOM(blog_data[post_offset]);
post_offset++;
}
}
function addDataToDOM(data) {
const postElement = document.createElement('div');
postElement.classList.add('blog-post');
postElement.innerHTML = `
<h2 class="title">${data.title}</h2>
<p class="text">${data.body}</p>
`;
container.appendChild(postElement);
loading.classList.remove('show');
}
#import url('https://fonts.googleapis.com/css?family=Open+Sans:300,600&display=swap');
* {
box-sizing: border-box;
}
body {
background-color: #fafafa;
font-family: 'Open Sans', sans-serif;
padding-bottom: 100px;
}
.container {
margin: 0 auto;
max-width: 600px;
}
.blog-post {
background-color: #fff;
box-shadow: 0px 1px 2px rgba(50, 50, 50, .1), 0px 2px 4px rgba(60, 60, 60, 0.1);
border-radius: 4px;
padding: 40px;
margin: 20px 0;
}
.title {
margin: 0;
}
.text {
color: #555;
margin: 20px 0;
}
.loading {
opacity: 0;
display: flex;
position: fixed;
bottom: 50px;
left: 50%;
transform: translateX(-50%);
transition: opacity .3s ease-in;
}
.loading.show {
opacity: 1;
}
.ball {
background-color: #777;
border-radius: 50%;
margin: 5px;
height: 10px;
width: 10px;
animation: jump .5s ease-in infinite;
}
.ball:nth-of-type(2) {
animation-delay: 0.1s;
}
.ball:nth-of-type(3) {
animation-delay: 0.2s;
}
#keyframes jump {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
<div class="container" id="container">
<h1>Blog Posts</h1>
</div>
<div class="loading">
<div class="ball"></div>
<div class="ball"></div>
<div class="ball"></div>
</div>
I coded a simple javascript "clearning Shopping List" code.
I was able to remove the shopping list and add two messages:
One says that the shopping list has been cleared and one pops up a button that asks if it was a mistake and you want to undo your change.
Now my problem is that when you press the "Undo" button the class doesn't get added back.
// javascript
var shoppingList = document.querySelector(".shoppingCart");
var toggleButton = document.querySelector("button.showList");
var clearedBox = document.querySelector(".clearedBox");
var clearedUndo = document.querySelector("button.clearedUndo");
//Toggle Shopping Cart
toggleButton.addEventListener("click", () => {
shoppingList.remove(".shoppingCart");
clearedBox.style.display = "block";
toggleButton.remove("button.showList");
});
//Undo Removal
clearedUndo.addEventListener("click", () => {
clearedUndo.createClass(".shoppingCart");
});
html, body {
margin: 0;
padding: 0;
margin-left:30px;
}
.clearedBox {
display:none;
}
.clearedMessage {
background:#D66A68;
color: white;
padding:10px;
width:260px;
text-align:center;
border-radius:10px;
}
.clearedUndo {
background:#1C77C3;
color: white;
padding:5px;
width:225px;
border-radius:5px;
text-align:center;
font-size:12px;
}
<html>
<head>
<link rel="stylesheet" href="index.css">
</head>
<body>
<h1>index.html</h1>
<button class="showList">Show</button>
<div class="shoppingCart">
<ul>
<li>Milk</li>
<li>Eggs</li>
<li>Juice</li>
<li>Pasta</li>
<li>Water</li>
<li>Donuts</li>
</ul>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et.</p>
</div>
<div class="clearedBox">
<p class="clearedMessage">Your Shopping cart is now cleared!</p>
<button class="clearedUndo">Accidental? Undo your change!</button>
</div>
<script src="index.js"></script>
</body>
</html>
I would assume this part is wrong:
//Undo Removal
clearedUndo.addEventListener("click", () => {
clearedUndo.createClass(".shoppingCart");
});
Once you remove it, it's gone, and if you want to put it back with JavaScript then all that markup really needs to be re-inserted, so I'd consider just hiding and showing the elements as needed, by changing the JS to this:
var shoppingList = document.querySelector(".shoppingCart");
var toggleButton = document.querySelector("button.showList");
var clearedBox = document.querySelector(".clearedBox");
var clearedUndo = document.querySelector("button.clearedUndo");
//Toggle Shopping Cart
toggleButton.addEventListener("click", () => {
shoppingList.style.display = "none";
clearedBox.style.display = "block";
toggleButton.style.display = "none";
});
//Undo Removal
clearedUndo.addEventListener("click", () => {
shoppingList.style.display = "block";
clearedBox.style.display = "none";
toggleButton.style.display = "block";
});
ISSUE
Don't use the elem.remove .Because if you undo the action no elements are present .For alternatively you can use elem.classList.toggle
// javascript
var shoppingList = document.querySelector(".shoppingCart");
var toggleButton = document.querySelector("button.showList");
var clearedBox = document.querySelector(".clearedBox");
var clearedUndo = document.querySelector("button.clearedUndo");
//Toggle Shopping Cart
toggleButton.addEventListener("click", () => {
shoppingList.classList.toggle('hide')
clearedBox.classList.toggle('show')
//toggleButton.remove("button.showList");
});
//Undo Removal
clearedUndo.addEventListener("click", () => {
shoppingList.classList.toggle('hide')
clearedBox.classList.toggle('show')
});
html,
body {
margin: 0;
padding: 0;
margin-left: 30px;
}
.clearedBox {
display: none;
}
.hide{
display: none;
}
.show{
display: block;
}
.clearedMessage {
background: #D66A68;
color: white;
padding: 10px;
width: 260px;
text-align: center;
border-radius: 10px;
}
.clearedUndo {
background: #1C77C3;
color: white;
padding: 5px;
width: 225px;
border-radius: 5px;
text-align: center;
font-size: 12px;
}
<html>
<head>
<link rel="stylesheet" href="index.css">
</head>
<body>
<h1>index.html</h1>
<button class="showList">Show</button>
<div class="shoppingCart">
<ul>
<li>Milk</li>
<li>Eggs</li>
<li>Juice</li>
<li>Pasta</li>
<li>Water</li>
<li>Donuts</li>
</ul>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et.</p>
</div>
<div class="clearedBox">
<p class="clearedMessage">Your Shopping cart is now cleared!</p>
<button class="clearedUndo">Accidental? Undo your change!</button>
</div>
<script src="index.js"></script>
</body>
</html>
I have several divs arranged vertically one on top of the other which from here on out I will call panels. Each panel has the width and height of the viewport. All panels have the same background color at all times. Initially, that color is black.
Every other panel is empty, and acts as a gap between panels that actually have content. The order is like this:
Content
No content
Content
No content
Content
What I want to do is make it so that when a user has scrolled down enough for a panel with content to be out of view, the color should change from black to white. Then, once they have scrolled far enough for the second panel with content to be out of view, it should change back.
This is the part I cannot figure out. I have a working demo with my code so far:
$(document).scroll(function() {
var viewportHeight = $("html").outerHeight();
var currentY = $(document).scrollTop();
if (currentY % viewportHeight != 0) {
lighten();
} else {
darken();
}
});
function darken() {
$("body").css("background-color", "black");
$(".panel.content").css("color", "white");
}
function lighten() {
$("body").css("background-color", "white");
$(".panel.content").css("color", "black");
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
</body>
As you can see, my code is a ways off from achieving the desired result. Not only is the order wrong, the main problem is that it only triggers when the user is at the exact Y for the change to happen.
The order should be:
Black
White
White
Black
Black
White
White
Black
Black
etc.
How do I do this?
$(document).scroll(function() {
var viewportHeight = $("html").outerHeight();
var currentY = $(document).scrollTop();
var panelNumber = Math.floor(currentY / viewportHeight);
if (panelNumber % 4 === 1 || panelNumber % 4 === 2) {
lighten();
} else {
darken();
}
});
function darken() {
$("body").css("background-color", "black");
$(".panel.content").css("color", "white");
}
function lighten() {
$("body").css("background-color", "white");
$(".panel.content").css("color", "black");
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
</body>
Not only is the order wrong, the main problem is that it only triggers
when the user is at the exact Y for the change to happen.
yes..that is right. currentY % viewportHeight != 0 will not work. Scrolling is not smooth. Pulling scrollbar down may result in change of 10000 px/sec, but browser renders 60fps which means your currentY (scroll-y) will increase by 150px every frame (your are expecting a change of 1px). So if your code contains if(currentY === 100){} definitely not going to work. currentY may have values like 0,50,80,99,120,....
It should be clear currentY % viewportHeight != x is not so much different.
So if(0<currentY<500) will be be better option.
Now suppose viewportHeight = 500. We can get panelNumber = Math.floor(currentY/viewportHeight) (=>0,1,2,3,4,5...)
(Not clear from your question) Suppose you want to have
panel: 0 =>black, 1=>white, 2=>white, 3=>black, 4=>black ...
you can get black by panelNumber%4==0 || panelNumber%4==3.
[please change accordingly if you want something different]
I know it's a bit late, but I made a solution for this and didn't had time to post it.
So: "How is my solution any different?"
I get gap-from-top values to all your .blank divs and then check where view-port is located. This allows you to use borders, add any other divs in between, change size of your divs and this will not lose functionality.
var elem = document.getElementsByClassName("blank");
var i;
var marks = [];
for (i = 0; i < elem.length; i++) {
var rect = elem[i].getBoundingClientRect();
marks.push(rect.top);
}
$(document).scroll(function() {
if (findi() % 2 == 1) {
lighten();
} else {
darken();
}
});
function findi() {
pos = 0;
for (i = 0; i < marks.length; i++) {
if (marks[i] < $(document).scrollTop()) {
pos++;
}
}
return (pos);
}
function darken() {
$("body").css("background-color", "black");
$(".panel.content").css("color", "white");
}
function lighten() {
$("body").css("background-color", "white");
$(".panel.content").css("color", "black");
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
html,
body {
padding: 0;
margin: 0;
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
.panel {
border-bottom: 32px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
Here is my solution. I'm pretty sure this is the order you need.
(function() {
var lastfunc = darken;
$(document).scroll(function() {
var y = $(document).scrollTop();
var x = $("html").outerHeight();
var func = (Math.floor(((y + x) / (2 * x))) % 2) ? lighten : darken;
if (func !== lastfunc) {
lastfunc = func;
func();
}
});
})();
This does the following:
Create a variable lastfunc to keep track of the last thing we called.
Get the user's Y and the height of the viewport.
Use evil factorized math to get a bool which decides which of the two functions, lighten() or darken() to assign to func.
Check to see if lastfunc is equal to func, to see if a change is necessary.
If they are not equal, call func() and set lastfunc equal to func
This has the following benefits:
All wrapped up to prevent making lastfunc a global.
Math is solid.
This calls the style modifying functions only if a change is required.
I've also optimized your darken() and lighten() functions:
function darken() {
document.body.style.backgroundColor = "black";
$(".panel.content").css("color", "white");
}
function lighten() {
document.body.style.backgroundColor = "white";
$(".panel.content").css("color", "white");
}
This slight optimization saves jQuery the trouble of finding your body, which should save off a couple of milliseconds. Not a huge difference, but this is optimal.
Additional note: if you are able to get rid of the second style change in lighten and darken, we can get rid of the overhead of having the function calls at all, and do it all within scroll():
(function() {
var lastColor;
$(document).scroll(function() {
var y = $(document).scrollTop();
var color = (Math.floor(((y + x) / (2 * x))) % 2) ? "red" : "blue";
if (color !== lastColor) {
lastColor = color;
document.body.style.color = color;
}
});
})();
Demo of the first solution:
(function() {
var lastfunc = darken;
$(document).scroll(function() {
var y = $(document).scrollTop();
var x = $("html").outerHeight();
var func = (Math.floor(((y + x) / (2 * x))) % 2) ? lighten : darken;
if (func !== lastfunc) {
lastfunc = func;
func();
}
});
})();
function darken() {
document.body.style.backgroundColor = "black";
$(".panel.content").css("color", "white");
}
function lighten() {
document.body.style.backgroundColor = "white";
$(".panel.content").css("color", "white");
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
</body>
You can use .hover() on $(document).ready(); I have added an example of it if it works for you.
$(document).ready(function() {
$(".panel.content").hover(function(){
$("body").css("background-color", "white");
$(this).css("color", "black");
},function(){
$("body").css("background-color", "black");
$(this).css("color", "white");
});
});
$(document).scroll(function() {
$(".panel.content").hover(function(){
$("body").css("background-color", "white");
$(this).css("color", "black");
},function(){
$("body").css("background-color", "black");
$(this).css("color", "white");
});
});
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
</body>
I've made it so you can choose which panel sets the background color to white/black. You can do that by adding the class 'black' or 'white' to it, though the way you requested it makes perfect sense afterall.
Also my solution uses a class to change the background color of the body. This should make it more easy to make style changes.
$(document).ready(init)
function init(){
$(document).scroll(updateBackground)
updateBackground()
}
function updateBackground(){
var w = $(window).width()
var h = $(window).height()
var panels = $('.panel') // get all panels on page
for(var i=0;i<panels.length;i++){ // loop though each panel
var panel = panels.eq(i) // get the current panel
var panel_y = panel.offset().top - $(document).scrollTop() // get the panels y coordinate relative to the window
var panel_height = panel.height() // get the panels height
if(panel_y<=0 && panel_y+panel_height>0){ // check if the panel is in the visible area
if(panel.hasClass('black')){ // check if the panel is set to make the background black
$('body').removeClass('white')
$('body').addClass('black')
}else if(panel.hasClass('white')){
$('body').removeClass('black')
$('body').addClass('white')
}
return // return, because we already found the visible panel
}
}
}
html{
height: 100%
}
body{
margin: 0;
padding: 0;
transition: background-color 500ms linear;
height: 100%
}
body.white{
background-color: white;
color: black;
}
body.black{
background-color: black;
color: white;
}
.panel{
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 50px;
border: solid 1px #888888;
text-align: center;
overflow: hidden;
}
.panel > h1{
font-size: 38pt;
}
.panel > p{
font-size: 18pt;
line-height: 200%;
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head
<body>
<div class="panel with-content black">
<h1>Content</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div>
<div class="panel gap white"></div>
<div class="panel with-content white">
<h1>Content</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div>
<div class="panel gap black"></div>
<div class="panel with-content black">
<h1>Content</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div>
<div class="panel gap white"></div>
<div class="panel with-content white">
<h1>Content</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div>
<div class="panel gap black"></div>
<div class="panel with-content black">
<h1>Content</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div>
</body>
</html>
Add a condition in your code
Math.floor(currentY / viewportHeight) % 4 == 1 || Math.floor(currentY / viewportHeight) % 4 == 2
and your code is working now.
Testing
If you run this code in java it will display same output as you expected.
public static void main(String...arr){
for(int i = 0; i<100; i++){
if(i%4 ==1 || i%4 == 2){
System.out.println("true");
} else {
System.out.println("false");
}
}
}
$(document).scroll(function() {
var viewportHeight = $("html").outerHeight();
var currentY = $(document).scrollTop();
if (Math.floor(currentY / viewportHeight) % 4 == 1 || Math.floor(currentY / viewportHeight) % 4 == 2) {
lighten();
} else {
darken();
}
});
function darken() {
$("body").css("background-color", "black");
$(".panel.content").css("color", "white");
}
function lighten() {
$("body").css("background-color", "white");
$(".panel.content").css("color", "black");
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
</body>
What I want to do is make it so that when a user has scrolled down enough for a panel with content to be out of view, the color should change from black to white. Then, once they have scrolled far enough for the second panel with content to be out of view, it should change back.
This statement conflicts with the order you mentioned. From the statement, it is implied that the color changes should be alternate, but the order mentioned in your question is not alternate.
Please see the below code which changes colors on alternate divs through out the scrolling.
$(document).scroll(function() {
var viewportHeight = $("html").outerHeight();
var currentY = $(document).scrollTop();
if (Math.floor(currentY / viewportHeight) % 2) {
lighten();
} else {
darken();
}
});
function darken() {
$("body").css("background-color", "black");
$(".panel.content").css("color", "white");
}
function lighten() {
$("body").css("background-color", "white");
$(".panel.content").css("color", "black");
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
</body>