Javascript blocking css? - javascript

I have a lightbox photo gallery I am building. When the first image loads the css transition works. When every image after loads it does not. Any ideas why? The photos after the first one load but they have no transition.
Image.prototype.load = function(url){
var thisImg = this;
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.open('GET', url,true);
xmlHTTP.responseType = 'arraybuffer';
xmlHTTP.onload = function(e) {
var blob = new Blob([this.response]);
thisImg.src = window.URL.createObjectURL(blob);
};
xmlHTTP.onprogress = function(e) {
thisImg.completedPercentage = parseInt((e.loaded / e.total) * 100);
};
xmlHTTP.onloadstart = function() {
thisImg.completedPercentage = 0;
};
xmlHTTP.onloadend = function() {
thisImg.completedPercentage = 0;
gallery.appendChild(currentImage);
gallery.className = "gallery toggle";
};
xmlHTTP.send();
};
.gallery {
display: absolute;
position: fixed;
margin: auto;
visibility: hidden;
opacity: 0;
-moz-transition: opacity 0.5s, visibility 0.5s ease-in-out;
-webkit-transition: opacity 0.5s, visibility 0.5s ease-in-out;
-ms-transition: opacity 0.5s, visibility 0.5s ease-in-out;
transition: opacity 0.5s, visibility 0.5s ease-in-out;
background: rgba(0, 0, 0, 0.0);
width: 96%;
height: 96%;
margin-top: 2%;
margin-left: 2%;
overflow: hidden;
z-index: 1001;
}
.gallery.toggle {
visibility: visible;
opacity: 1;
}

your CSS is executed on page load. When you dynamically add or remove content, CSS is not loaded again. You would probably have to create the transitions with JS after loading the image.
Maybe this helps:
https://timtaubert.de/blog/2012/09/css-transitions-for-dynamically-created-dom-elements/

You are adding the images with the class gallery toggle, which means the transition will never take place; it will be loaded in its final state. You need to load the images with gallery, allow the DOM to render, and then add the toggle class. You can probably get it working by doing this:
xmlHTTP.onloadend = function() {
thisImg.completedPercentage = 0;
gallery.appendChild(currentImage);
gallery.className = "gallery";
setTimeout(function () {
gallery.className = 'gallery toggle';
}, 20);
};

Related

css transitions don't work when changes are made in javascript

#loading_screen {
display: none;
z-index: 1;
height: 100vh;
width: 100vw;
opacity: 0;
background-color: red;
transition: opacity 4s 0s ease;
}
<div id="loading_screen" class="page">
</div>
<script>
function hide_page() {
const loading = document.getElementById('loading_screen');
loading.style.display = 'block';
loading.style.opacity = '1';
}
hide_page()
</script>
The loading_screen div appears instantly, as if the transition didn't even exist
Is there a chance that the css is not functional immediately when I run the page?
You need to wait for the browser to update and paint the loading element first, then you can use setTimeout to change the opacity after the browser has done its paint.
function hide_page() {
const loading = document.getElementById('loading_screen');
loading.style.display = 'block';
setTimeout(() => {
loading.style.opacity = '1';
});
}
hide_page();
#loading_screen {
display: none;
z-index: 1;
height: 100vh;
width: 100vw;
opacity: 0;
background-color: red;
transition: opacity 4s ease;
}
<div id="loading_screen" class="page">
</div>

CSS transition not working when moving element

I have a CSS element/ball which I am moving to new coordinates on click.
This works, however the transition I am applying does not seem to take affect.
The ball jumps to the new location. I want it to slowly animate/transition/move to the new coordinates.
What am I doing wrong?
.ball {
width: 30px;
height: 30px;
border-radius: 50%;
background-color: #FF5722;
position: absolute;
// d.style.transition = "all 1s ease-in";
transition: all 3s ease-in-out;
// -webkit-transition: all 1s ease-in-out;
// -moz-transition: all 1s ease-in-out;
// -o-transition: all 1s ease-in-out;
// -ms-transition: all 1s ease-in-out;
}
handleClick = (e) => {
console.log('ball clicked');
var d = document.getElementById('ball');
console.log('d', d);
d.style.x = 12 + "px";
d.style.top = 341 + "px";
d.style.transition = "all 1s ease-in";
}
Thanks
You have to assign a default value for x and top or you are trying to transition from nothing.
P.S. It seems your CSS is selecting elements with the CLASS ball instead of an element with the ID of ball. Use #ball instead of .ball in CSS. (credit to jaromanda-x)
window.onclick = (e) => {
console.log('ball clicked');
var d = document.getElementById('ball');
console.log('d', d);
d.style.x = 12 + "px";
d.style.top = 341 + "px";
d.style.transition = "all 1s ease-in";
}
#ball {
width: 30px;
height: 30px;
border-radius: 50%;
background-color: #FF5722;
position: absolute;
// d.style.transition = "all 1s ease-in";
transition: all 3s ease-in-out;
// -webkit-transition: all 1s ease-in-out;
// -moz-transition: all 1s ease-in-out;
// -o-transition: all 1s ease-in-out;
// -ms-transition: all 1s ease-in-out;
x:0; /* default value */
top:0; /* default value */
}
<div id="ball">
It seems like there are a few things that need to be corrected;
The ball is styled by the .ball class in your CSS where as the ball element is being accessed via an id, which suggests a potential problem. Is the ball class being applied to the element with id ball?
the x property on the style object should be replaced with the left property to ensure horizontal movement of the ball element
ensure that the transition is assigned to the target elements prior to any CSS properties being modified
Here's an example demonstrating these corrections:
const handleClick = (e) => {
console.log('ball clicked');
const ball = document.getElementById('ball');
/* Setting random coordinates to demonstrate transition */
ball.style.left = Number.parseInt(Math.random() * 200) + "px";
ball.style.top = Number.parseInt(Math.random() * 200) + "px";
}
document.addEventListener("click", handleClick);
#field {
position: relative;
width: 100%;
height: 100%;
}
/* Corrected to id selector with # rather than class selector
with . */
#ball {
position: absolute;
width: 30px;
height: 30px;
border-radius: 50%;
background-color: #FF5722;
position: absolute;
/* Assigning transition behavior which is applied during
property changes */
transition: all 3s ease-in-out;
}
<div id="field">
<div id="ball"></div>
</div>
Hope that helps

IntersectionObserver: Trigger event when scrolling back to the top

I am starting to use the IntersectionObserver API and could create some basic animations, which includes hiding and appearing of elements. However, once a person wants to scroll back to the top, the elements which disappeared by one of the triggers are not getting visible again.
My Solution so far
So I thought I might create another test variable within the intersection observer callback function (the stepI and stepII variable in my code), which checks if the callback function was previously triggered. If so, instead of disappearing the elements, let them appear again.
My current problem
So let's say a background image (id="hiddenImg") should appear when the first text block (id="I") passes the 50% border of the viewport and it disappears when the second text block (id="II") enters this area. Even though the image is getting visible again when scrolling back up, if the user does not scroll back completely (so that the second text block goes out of the viewport) and then scrolls back to the bottom, the disappearing trigger of that second text block is not called. This would mean that the background image would stay visible, which it shouldn't.
Here is the js part:
var stepI = false;
var stepII = false;
// list of options
let options = {
rootMargin: '0px 0px -50%' //WHEN reaching half of the viewport
};
// instantiate a new Intersection Observer
"use strict";
var intersectionObserver = new IntersectionObserver(function (entries, observer) {
entries.forEach(function (change) {
if (change.isIntersecting) {
if (change.target.id == "I") {
$("#hiddenImg").removeClass("hidden_img");
$("#hiddenImg").addClass("visible_img");
stepI = true;
observer.unobserve(change.target);
}
if (change.target.id == "II") {
if (stepII == false) {
$("#hiddenImg").removeClass("visible_map");
$("#hiddenImg").addClass("hidden_map");
stepII = true
} else {
$("#hiddenImg").removeClass("hidden_map");
$("#hiddenImg").addClass("visible_map");
stepII = false;
}
}
}
});
},options);
// list of paragraphs
let elements = document.querySelectorAll(".stepper");
for (let elm of elements) {
intersectionObserver.observe(elm);
}
Here is my complete code:
<html>
<head>
<!-- Load the polyfill. -->
<script src="/js/intersection-observer.js"></script>
<script src='https://unpkg.com/intersection-observer#0.5.0/intersection-observer.js'></script>
</head>
<body>
<style>
.intro-imgs {
display: block;
margin: 0 auto; /* Will not center vertically and won't work in IE6/7. */
left: 0;
right: 0;
position: fixed;
position: expression(fixed);
}
.hidden_img {
visibility: hidden;
opacity: 0;
-ms-transform: scaleX(0); /* IE 9 */
-webkit-transform: scaleX(0); /* Safari 3-8 */
-o-transform: scaleX(0);
-moz-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: visibility 0s 0.5s, opacity 0.5s linear, -webkit-transform 0.5s;
-moz-transition: visibility 0s 0.5s, opacity 0.5s linear, -moz-transform 0.5s;
-o-transition: visibility 0s 0.5s, opacity 0.5s linear, -o-transform 0.5s;
transition: visibility 0s 0.5s, opacity 0.5s linear, transform 0.5s;
}
.visible_img {
visibility: visible;
opacity: 1;
-ms-transform: scaleX(1); /* IE 9 */
-webkit-transform: scaleX(1); /* Safari 3-8 */
-o-transform: scaleX(1);
-moz-transform: scaleX(1);
transform: scaleX(1);
-webkit-transition: opacity 0.5s linear, -webkit-transform 0.5s;
-moz-transition: opacity 0.5s linear, -moz-transform 0.5s;
-o-transition: opacity 0.5s linear, -o-transform 0.5s;
transition: opacity 0.5s linear, transform 0.5s;
}
.stepper{
max-width: 70rem;
margin: 550px auto 600px auto;
width: 90%;
background-color: rgba(248, 248, 248, 0.95);
font-family: "Helvetica";
font-size: 17px;
line-height: 26px;
padding: 15px;
}
</style>
<!--HTML-->
<div class="headline">
<img id="hiddenImg" class="hidden_img intro-imgs" src="https://image.shutterstock.com/image-photo/funny-portrait-hero-260nw-410898763.jpg" >
</div>
<div id="I" class="stepper">
<p>Lorem Ipsum</p>
</div>
<div id="II" class="stepper">
<h1>THE HEADLINE</h1>
</div>
<!-- SCRIPT-->
<script>
var stepI = false;
var stepII = false;
// list of options
let options = {
rootMargin: '0px 0px -50%' //WHEN reaching half of the viewport
};
// instantiate a new Intersection Observer
"use strict";
var intersectionObserver = new IntersectionObserver(function (entries, observer) {
entries.forEach(function (change) {
if (change.isIntersecting) {
if (change.target.id == "I") {
$("#hiddenImg").removeClass("hidden_img");
$("#hiddenImg").addClass("visible_img");
stepI = true;
observer.unobserve(change.target);
}
if (change.target.id == "II") {
if (stepII == false) {
$("#hiddenImg").removeClass("visible_map");
$("#hiddenImg").addClass("hidden_map");
stepII = true
} else {
$("#hiddenImg").removeClass("hidden_map");
$("#hiddenImg").addClass("visible_map");
stepII = false;
}
}
}
});
},options);
// list of paragraphs
let elements = document.querySelectorAll(".stepper");
for (let elm of elements) {
intersectionObserver.observe(elm);
}
</script>
</body>

How do I add a cycle style repeating image phase background to my website?

The question title says it all, I am not sure how to organize it in to my websites HTML due to the fixed menu bar, and its over all build. So to say, I want my website to have multiple backgrounds that fade in and out. I intend on adding more backgrounds over time. What I listed below is what I've been attempting to work with.
body {
width: 400px;
height: 400px;
}
/* set `#slideshow` parent background color */
.slideshow {
background: #000;
display:block;
width:inherit;
height:inherit;
}
#slideshow {
width: 100%;
height: 100%;
display: block;
opacity: 0.0;
background-color: #000;
/*
set background images as `url(/path/to/image)` here,
separated by commas
*/
background-image: url("http://lorempixel.com/400/400/cats/?1"),
url("http://lorempixel.com/400/400/animals/?2"),
url("http://lorempixel.com/400/400/nature/?3"),
url("http://lorempixel.com/400/400/technics/?4"),
url("http://lorempixel.com/400/400/city/?5");
background-size: cover, 0px, 0px, 0px;
/* set transtitions at 3000ms
-webkit-transition: background-image 3000ms linear;
-moz-transition: background-image 3000ms linear;
-ms-transition: background-image 3000ms linear;
-o-transition: background-image 3000ms linear;
transition: background-image 3000ms linear;
*/
}
Javascript below.
$(function() {
$.fx.interval = 0;
(function cycleBgImage(elem, bgimg) {
// `elem`:`#slideshow`
// set, reset, delay to `1000` after background image reset
elem.css("backgroundImage", bgimg)
// fade in background image
.fadeTo(3000, 1, "linear", function() {
// fade in background image
$(this).delay(3000, "fx").fadeTo(3000, 0, "linear", function() {
// split background image string at comma , creating array
var img = $(this).css("backgroundImage").split(","),
// concat first background image to `img` array,
// remove first background image from `img` array
bgimg = img.concat(img[0]).splice(1).join(",");
// recursively call `cycleBgImage`
cycleBgImage(elem, bgimg);
});
});
}($("#slideshow")));
});
The division script, which I'm not sure I have a use for unless I make my whole website one large div which seems pointless.
<div class="slideshow">
Here is a quick hack. I would probably do something more elegant with management of the images in an array, but this should get you going.
function swap(){
var $targets = $("#slideshow img");
var className = "active";
var $next = $targets.filter(".active").next();
if ($next.length === 0) { $next = $targets.first(); }
$targets.removeClass(className);
$next.addClass(className)
}
swap();
window.setInterval(swap, 5 * 1000);
#slideshow {
background-color: #000;
width: 400px;
height: 400px;
border: solid 1px;
overflow: hidden;
position: relative;
}
#slideshow img {
position:absolute;
opacity: 0;
transition: opacity 2s ease-in-out;
}
#slideshow img.active {
opacity: 1;
}
<div id="slideshow">
<img src="http://lorempixel.com/400/400/cats/?1" />
<img src="http://lorempixel.com/400/400/animals/?2" />
<img src="http://lorempixel.com/400/400/nature/?3" />
<img src="http://lorempixel.com/400/400/technics/?4" />
<img src="http://lorempixel.com/400/400/city/?5" />
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

why my background-image transition is not working in firefox

I am trying to change the background image of an div without having any effect on the content inside the div. i wrote following code to change the background-mage. I didn't understand why firefox doesn't respond to my css transition. is there any fix by which i can make it to work in ie and firefox.
Html
<body>
<header>
</header>
</body>
Css
body {
margin: 0;
}
header {
height: 665px;
width: 100%;
background-image: url('image0.jpg');
-moz-transition: background-image 1s ease-in-out;
-webkit-transition: background-image 1s ease-in-out;
-ms-transition: background-image 1s ease-in-out;
-o-transition: background-image 1s ease-in-out;
}
Jquery
function preloadImages(array) {
if (!preloadImages.list) {
preloadImages.list = [];
}
for (var i = 0; i < array.length; i++) {
var img = new Image();
img.src = array[i];
preloadImages.list.push(img);
}
}
var imageURLs = [
"image0.jpg",
"image1.jpg",
"image2.jpg",
"image3.jpg",
"image4.jpg"
];
preloadImages(imageURLs);
var counterForBackgroundImage = -1;
function changeBackgroundImage() {
counterForBackgroundImage++;
if (counterForBackgroundImage > imageURLs.length-1)
counterForBackgroundImage = 0;
$('header').css('background-image', 'url(' + imageURLs[counterForBackgroundImage] + ')');
setTimeout(function() {
changeBackgroundImage();
}, 5000);
}
changeBackgroundImage();
background-image animate property is not listed at w3c animatable list.
Try using some trick such as this.

Categories