Smooth css change transitions - javascript

I've setup a jQuery function that changes the body background colour when a certain div comes into view, e.g. the body background colour is black, when #block-three (that contains black text), the body background colour changes to white, and changes back when this goes out of view. This works fine, it's just very sudden though, I'm looking for a much smoother transition between background colours, fading between colours as you scroll (if possible).
jsFiddle demo: http://jsfiddle.net/neal_fletcher/TB53d/
HTML:
<div id="block-one" class="block">
<div class="inner-block">Test</div>
<div class="inner-block"></div>
<div class="inner-block"></div>
</div>
<div id="block-two" class="block">
<div class="inner-block">Test</div>
</div>
<div id="block-three" class="block">
<div class="inner-block">Test</div>
<div class="inner-block"></div>
</div>
<div id="block-four" class="block">
<div class="inner-block">Test</div>
<div class="inner-block"></div>
<div class="inner-block"></div>
</div>
<div id="block-five" class="block">
<div class="inner-block">Test</div>
<div class="inner-block"></div>
<div class="inner-block"></div>
</div>
jQuery:
var blockHeight = [];
$(".block").each(function () {
blockHeight.push($(this).height());
});
function hoverCurrentItem() {
var sIndex = 0;
var totalHeight = 0;
var scrolled = $(window).scrollTop();
for (var i in blockHeight) {
totalHeight += blockHeight[i];
if (totalHeight > scrolled) {
break;
} else {
sIndex++;
}
}
var $sItem = $(".block").eq(sIndex);
if (!$sItem.hasClass("selected")) {
$(".selected").removeClass("selected");
$sItem.addClass("selected");
}
if ($("#block-three").hasClass("selected")) {
$("body").css("background-color", "white");
} else {
$("body").css("background-color", "black");
}
}
hoverCurrentItem();
$(window).scroll(function (e) {
hoverCurrentItem()
});
Any suggestions would be greatly appreciated!

You could use transition with CSS:
body {
background-color: black;
transition:all 1s;
}
The Demo Fiddle

Related

Changing CSS styling with an if statement in javascript

Context: I'm trying to change the color of a text according to a if statement (Green if returnOfInvestment >= 0 red if this isn't true) however, it doesn't seem to be working. I've searched on SO already, but can't figure out why it isn't working as expected.
var returnOfInvestment = (netProfit / initialInvestment.value) * 100;
var valEl = document.querySelector(".number dashtext-2");
var portfolioEl = document.querySelector(".number dashtext-3");
if (returnOfInvestment >= 0) {
valEl.style.color = "green";
portfolioEl.style.color = "green";
} else {
valEl.style.color = "red";
portfolioEl.style.color = "red";
}
.dashtext-2 {
color: #27b83f !important;
}
.dashtext-3 {
color: #27b83f !important;
}
<div class="col-md">
<div class="statistic-block block">
<div class="progress-details d-flex align-items-end justify-content-between">
<div class="title">
<div class="icon"><i class="icon-bars"></i></div>
<strong><div class="valdeval"></div></strong>
</div>
<div class="number dashtext-2">
<div class="valorization"></div>
</div>
</div>
</div>
</div>
<div class="col-md">
<div class="statistic-block block">
<div class="progress-details d-flex align-items-end justify-content-between">
<div class="title">
<div class="icon"><i class="icon-pie-chart"></i></div><strong> Portfolio</strong>
</div>
<div class="number dashtext-3">
<div class="totalportfolio"></div>
</div>
</div>
</div>
</div>
Give the elements you want to style a class and use CSS to apply a green text-color.
Create a class within CSS for a red text-color like: .color-red { color: red; }
Change the script slightly as below. Use classList.remove('.color-red'); to remove the class that changes the text-color to red or the same function with .add instead of .remove to apply the class for the red tex-color.
function changeStyle() {
var returnOfInvestment = document.getElementById('input-number').value;
var valEl = document.querySelector('.random-element'),
portfolioEl = document.querySelector('.portfolio-element');
if (returnOfInvestment >= 0) {
valEl.classList.remove('color-red');
portfolioEl.classList.remove('color-red');
} else {
valEl.classList.add('color-red');
portfolioEl.classList.add('color-red');
}
}
.random-element,
.portfolio-element {
color: green;
}
.color-red {
color: red;
}
<input type="number" id="input-number" name="input-number" onchange="changeStyle()">
<h1 class="random-element">Random element</h1>
<h1 class="portfolio-element">Portfolio element</h1>
Alternativly you could add a specific class to all elements you want to change color for. Then you can use this instead:
var allEL = document.querySelectorAll('.class-name');
if (returnOfInvestment >= 0) {
allEL.forEach(el => el.classList.remove('color-red'));
} else {
allEL.forEach(el => el.classList.add('color-red'));
}
}
That will apply/remove the class of all elements with a specific class. Really helpfull if you need to apply changes to multiple elements.

Add prev/next buttons to scroll container with CSS and jQuery

After a long research I found a solution to add a custom scrollbar to a DIV element.
It's called SimpleBar. Docs can be found here.
The HTML structure and JS code is pretty simple:
Working demo
<div class="gallery" data-simplebar data-simplebar-auto-hide="false">
<div class="item"><img src="https://via.placeholder.com/250x150/0000FF" /></div>
<div class="item"><img src="https://via.placeholder.com/350x150/FF0000" /></div>
[...]
</div>
With data-simplebar I can add a custom scrollbar to any DIV.
There is just one thing I couldn't solve.
I want to add prev/next arrows to the scroll element.
The buttons should jump to the prev/next element in the DIV which is next to the left/right side of the div and not yet scrolled (partially) over.
And the JS should work for every slider instance on the site. Like the SimpleBar itself. There is no need for extra code per scroll container.
Is there anything I could use in jQuery?
EDIT: I found this answer and fiddle. I added the code to my example and changed it to left/right. It's not exactly what I need but I thought it could be a starting point. Unfortunately it doesn't work properly.
You can use the following code. Note that the scrolling depends on the viewport, so that once there's no more right width to go to, it won't have more room to move.
const DIRECTION = { PREV: 1, NEXT: 2 };
$(document).ready(function () {
$('.container').each(function (index, containerItem) {
var $gallery = $(containerItem).find('.gallery');
const simpleBar = new SimpleBar($gallery[0], {
autoHide: false,
scrollbarMaxSize: 50
});
var $scroller = $(simpleBar.getScrollElement());
$(containerItem).find('.scrollLeft').on('click', function () {
scroll(DIRECTION.PREV, $scroller);
event.preventDefault(); // prevents anchor jump on click
});
$(containerItem).find('.scrollRight').on('click', function () {
scroll(DIRECTION.NEXT, $scroller);
event.preventDefault();
});
$scroller.scroll(function () {
setButtonsVisibility($scroller);
});
});
});
function scroll(direction, $scroller) {
var $active = $scroller.find('.active');
var $target = direction == DIRECTION.PREV ? $active.prev() : $active.next();
if ($target.length) {
$scroller.animate({
scrollLeft: $target[0].offsetLeft
}, 2000);
$active.removeClass('active');
$target.addClass('active');
}
}
function setButtonsVisibility($scroller) {
var scrollLeft = $scroller.scrollLeft();
isScrollerStart($scroller, scrollLeft);
isScrollerEnd($scroller, scrollLeft);
}
function isScrollerStart($scroller, scrollLeft, $button) {
var $prevButton = $scroller.closest('.container').find('.scrollLeft');
if (scrollLeft == 0) {
$prevButton.css('visibility', 'hidden');
} else {
$prevButton.css('visibility', 'visible');
}
}
function isScrollerEnd($scroller, scrollLeft) {
var $nextButton = $scroller.closest('.container').find('.scrollRight');
var scrollWidth = $scroller[0].scrollWidth; // entire width
var scrollerWidth = $scroller.outerWidth() // visible width
if (scrollLeft >= scrollWidth - scrollerWidth) {
$nextButton.css('visibility', 'hidden');
} else {
$nextButton.css('visibility', 'visible');
}
}
.container {margin: 0 auto 2rem; max-width: 960px;}
.gallery {padding-bottom: 2rem; margin-bottom: 2rem;}
.gallery .simplebar-content {display: flex;}
.gallery .item {margin-right: 1rem;}
.simplebar-scrollbar:before {background: red !important;}
.simplebar-track.simplebar-horizontal {background: #eee !important;;}
.buttons {display: flex; justify-content: space-between; width: 100%; margin-bottom: 2rem;}
.buttons a {padding: 0.5rem; background: #ddd; text-decoration: none; color: #000;}
.scrollLeft { visibility: hidden; }
<script src="https://unpkg.com/simplebar#latest/dist/simplebar.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/simplebar#latest/dist/simplebar.css">
<div class="container">
<h2>Slider</h2>
<div class="gallery">
<div class="item active"><img src="https://via.placeholder.com/150x30/110000" /></div>
<div class="item"><img src="https://via.placeholder.com/450x30/3300FF" /></div>
<div class="item"><img src="https://via.placeholder.com/350x30/992244" /></div>
<div class="item"><img src="https://via.placeholder.com/400x30/0000FF" /></div>
</div>
<div class="buttons">
<a class="scrollLeft" href="#"><strong>Prev</strong> (remove if first)</a>
<a class="scrollRight" href="#"><strong>Next</strong> (remove if last)</a>
</div>
</div>
<div class="container">
<h2>Slider</h2>
<div class="gallery">
<div class="item active"><img src="https://via.placeholder.com/150x30/110000" /></div>
<div class="item"><img src="https://via.placeholder.com/450x30/3300FF" /></div>
<div class="item"><img src="https://via.placeholder.com/350x30/992244" /></div>
<div class="item"><img src="https://via.placeholder.com/400x30/0000FF" /></div>
</div>
<div class="buttons">
<a class="scrollLeft" href="#"><strong>Prev</strong> (remove if first)</a>
<a class="scrollRight" href="#"><strong>Next</strong> (remove if last)</a>
</div>
</div>

Two clicks - different actions (same div)

Hope someone could help!
I have some divs (using bootstrap) like:
<div class="container">
<div class="row" id="r2">
<div class="col-lg-8">
<div class="block-in-div"></div>
</div>
<div class="col-lg-4">
<div class="col-lg-12">
<div class="block-in-div"></div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="col-lg-4">
<div class="row">
<div class="col-lg-12">
<div class="block-in-div"></div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="block-in-div"></div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="block-in-div"></div>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="block-in-div"></div>
</div>
</div>
</div>
</div>
</div>
</div>
When I click on some div it should randomly get some background color.
When I click on another div, previous should reset its background, and newly clicked div should get its random background.
Whith this issues everything is clear.
I can`t get how to do next: I clicked on div, it changes its colour, I click again and it should become bigger.
Color randomizer:
function getRandomColor() {
var r=Math.floor(Math.random() * (256));
var g=Math.floor(Math.random() * (256));
var b=Math.floor(Math.random() * (256));
var color = '#' + r.toString(16) + g.toString(16) + b.toString(16);
return color;};
Reset background:
function cancelBg() {
let selectedBlocks = $("div.block-in-div");
$.each(selectedBlocks,function(key,value){
selectedBlocks[key].style.background = "none";
});};
Main function:
$(document).ready(function () {
$(".block-in-div").click(function () {
cancelBg();
$(this).css("background", getRandomColor());
});});
Trying smth like:
$(document).ready(function () {
$(".block-in-div").click(function () {
var state = 1;
return function () {
cancelBg();
if(state===1){
$(this).css("background", getRandomColor());
state=2;
}
else if(state===2){
/*$(this).addClass("active");*/
state=1;
}
};
}());});
.active just for test and it is simply:
.active{
height: 100vh;
width: 100vw;
}
Please help!
Be the force with you! :)
You can achieve this by adding a class when the div was clicked first.
$(document).ready(function () {
$(".block-in-div").click(function () {
return function () {
cancelBg();
if(!$(this).hasClass('not-resized')) {
$(this).css("background", getRandomColor());
$(this).addClass('not-resized');
}
else if ($(this).hasClass('not-resized')) {
$(this).addClass("active");
$(this).removeClass('not-resized');
}
};
}());
});
If you need to reset the state on click on other div you can just add $(".block-in-div").removeClass('not-resized'); at the end.
Note 1: Adding active class like you did will have lower priority than the size on original class (add an !important as a temporal fix to see the changes or even better... make a stronger selector).
Note 2: If I didn't get the requirements right pls. tell me.
Thanks everyone!
Mold something like JSFiddle
$(document).ready(function () {
$(".block-in-div").click(function () {
if($(this).hasClass('tofull') && !$(this).hasClass('active')){
$(this).addClass("active");
}
else if($(this).hasClass('active')){
$(this).removeClass("active tofull");
$(this).css("background", "none");
}
else{
cancelBg();
let clr = "#"+((1<<24) * Math.random()|0).toString(16);
$(this).css("background", clr);
$(this).addClass("noColor tofull");
}
});
});
Still got some problems with working but got ideas how to fix it.
Problem is: Click block A (become red), click B (yellow), click C (green), click A again - size changes but no background

Jquery change background colour for a selected div

I have this HTML code div in 4*4 format :
$(document).ready(function() {
$("div").click(function(e){
var id_val=this.id;
var word = id_val.split("-").pop();
alert(word)
e.preventDefault();
for(var i=1;i<=4;i++)
{
if(i!=word)
{
$("#div-"+i+"").css("background-color","white");
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div-1">
<p>div1</p>
<div id="div-2">
<p>div2</p>
<div id="div-3">
<p>div3</p>
<div id="div-4">
<p>div4</p>
</div>
</div>
</div>
</div>
I have written the jquery code when on click the particular div has to change colour to red and remaining div colour should be white
When I have executed this only the div1 has changing the colour to red and other divs are not changing the colour.
for eg :
if I click div1 change to red colour and other div2,div3,div4 should be in white
color
If I click div2 change to red colour and other div1,div3,div4 should be in white
color
You need to use e.stopPropagation(); to prevent the other div elements from triggering as well.
you didn't properly terminate the first two lines with }); at the end of the script.
$(document).ready(function() {
$("div").click(function(e) {
var id_val = this.id;
var word = id_val.split("-").pop();
if (word != null) {
alert(word)
e.stopPropagation();
for (var i = 1; i <= 4; i++) {
if (parseInt(i) === parseInt(word)) {
$("#div-" + i + "").css("background-color", "red");
} else {
$("#div-" + i + "").css("background-color", "white");
}
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="div-1">
<p>div1</p>
<div id="div-2">
<p>div2</p>
<div id="div-3">
<p>div3</p>
<div id="div-4">
<p>div4</p>
</div>
</div>
</div>
</div>
Try something Like that
$("div").click(function(e){
$("div[id^='div-']").css("background-color","white");
$(this).css("background-color","red");
}
You need to use e.stopPropagation() and not e.preventDefault(). Also since divs are nested you should give a color to the inside p tag and not the div itself. Also terminate your function correctly.
$(document).ready(function() {
$("div").click(function(e){
var id_val=this.id;
$(this).first("p").css("background-color","red")
var word = id_val.split("-").pop();
alert(word)
e.stopPropagation();
for(var i=1;i<=4;i++)
{
if(i!=word)
{
$("#div-"+i+"").css("background-color","white");
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div-1">
<p>div1</p>
<div id="div-2">
<p>div2</p>
<div id="div-3">
<p>div3</p>
<div id="div-4">
<p>div4</p>
</div>
</div>
</div>
</div>
This worked for me
$("div").click(function (e) {
$(this).css("background-color", "red");
$('div:not(#' + this.id + ')').css("background-color", "white");
e.stopImmediatePropagation();
});
Try to use this simple code
$(document).ready(function() {
$("div").click(function(e) {
$('div[id^="div-"] p').css("background-color", "white"); //change the remaining elements who's id start with div- color to white
if ($(e.target).is('p')) {
$(e.target).css("background-color", "red"); //change the clicked element color
}
});
});
$("div").click(function(e) {
$('div[id^="div-"] p').css("background-color", "white"); //change the remaining elements who's id start with div- color to white
if ($(e.target).is('p')) {
$(e.target).css("background-color", "red"); //change the clicked element color
}
});
body {
background: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div-1">
<p>div1</p>
<div id="div-2">
<p>div2</p>
<div id="div-3">
<p>div3</p>
<div id="div-4">
<p>div4</p>
</div>
</div>
</div>
</div>

Viewport - jQuery selectors for finding elements in viewport

In my project every div has a video so I'm trying to check if a div is in viewport, so if it is that video to start playing and if it's not to pause or to stop. I'm jusing jekyll.
For example my html code for only one div looks like this :
<div class="container">
<div class="row">
<input type="button" id="play" value="Play"></input>
<input type="button" id="pause" value="Pause"></input>
<br/><br/>
<div class="col-lg-5 col-lg-offset-1 col-sm-push-6 col-sm-6">
<hr class="section-heading-spacer">
<div class="clearfix"></div>
<h2 class="section-heading">Vjetersia</h2>
<div class="lead"><p class="justify"> Vjetersia</p></div>
</div>
<div class="col-lg-5 col-sm-pull-6 col-sm-6">
<div class="gifv-player" id="">
<video preload="none" loop="loop">
<source type="video/webm" src="all_files/1.webm" />
</video>
<img src="example.png" alt="Animated Gif" />
</div>
</div>
<div class="col-lg-3 col-sm-pull-2 col-sm-2"></div>
</div>
</div>
I tried to do it on button click and it works:
$( document ).ready(function() {
player = new GifvPlayer();
$("#play").click(function() {
$('.gifv-player').find('video').show();
$('.gifv-player').find('video')[0].play();
});
$("#pause").click(function() {
$('.gifv-player').find('video')[0].pause();
});
});
but how can i modify it so it can work on stroll if a div is visible to start to play its video ? Any help?
easy quick and dirty example how you could implement it. play/pause like changing colors of the divs ... http://jsfiddle.net/7mkdj4ak/1/
var scrollPosition = $(window).scrollTop();
var windowViewHeight = $(window).height();
var videoWrapHeight = $('.container').outerHeight();
$(window).on('scroll', function(){
scrollPosition = $(window).scrollTop();
playVideos(scrollPosition);
});
$(window).on('resize', function(){
windowViewHeight = $(window).height();
});
var playVideos = function(scrollPosition) {
$('.container').each(function(i){
var thisContainerTopPosition = $(this).offset().top;
var thisContainerBottomPosition = thisContainerTopPosition + videoWrapHeight;
if(
thisContainerTopPosition >= scrollPosition &&
thisContainerBottomPosition <= (scrollPosition + windowViewHeight )
) {
/* div is in view PLaY */
$(this).css('background-color','orange');
} else {
/* div is out of view PausE */
$(this).css('background-color','#afafaf');
}
});
};
playVideos(scrollPosition);
.container {
width: 100%;
height: 100px;
background-color: #afafaf;
margin: 20px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h1>my Video 1</h1>
</div>
<div class="container">
<h1>my Video 2</h1>
</div>
<div class="container">
<h1>my Video 3</h1>
</div>
<div class="container">
<h1>my Video 4</h1>
</div>
You can refer this demo
.growme {
background-color: #990000;
height: 0;
width: 0;
position: absolute;
filter: alpha(opacity=0);
opacity: 0;
top:0;
left:0;
bottom:0;
right:0;
margin:auto;
}
DEMO HERE

Categories