Forum Moderators: open

Message Too Old, No Replies

Javascript Slide Animation Broken in Firefox

         

l008comm

8:49 am on Feb 28, 2020 (gmt 0)

10+ Year Member Top Contributors Of The Month



I use CSS transitions to make an image slide across a <div> on my page. First, here is the code:
[jsfiddle.net...]

It works properly in Webkit, but it does not work properly in Firefox. Originally, it didn't work in Webkit either (failed in the same way). That was when it was suggested that I put lines 17 and 18 inside a setTimeout function, that way the page will update before the position change.

This fix works perfectly in Safari and Chrome, but very sporadically in Firefox. It would seem that line 17 is running before the results of line 13 get added to the page. So the move is instant, not animated like I want.

Also let me give you a description of what this does. There is an image sitting inside a div box. Every loop through my function, a new image is created inside the div box, to the right of the current one. It is not visible because the box hides overflow. Then both images, the new and the old, change their Left property to animate a simultaneous slide to the left. Then the 'old' image, now invisible and to the left of the visible image, is deleted. This isn't the exact code I'm using on my site but it's very similar, and is having the same rendering problem.

And finally, if you prefer code in the post instead of a jsfiddle link, well then here you go:


var $products;

$products = document.getElementById("products");
setInterval(slide_image,3000);

function slide_image()
{
var $new_image = document.createElement("img");
$new_image.setAttribute("alt","Mac");
$new_image.setAttribute("id","new_item");
$new_image.setAttribute("src","http://new.www.macfixer.com/product_images/apple_watch_2018.png");
$new_image.style.left = "202px";
$products.append($new_image);

setTimeout(function()
{
$products.querySelector("#new_item").style.left = "0px";
$products.querySelector("#current_item").style.left = "-202px";
}, 0);

setTimeout(function()
{
$products.removeChild($products.querySelector("#current_item"));
$products.querySelector("#new_item").setAttribute("id","current_item");
},1500);
}


NickMNS

1:42 pm on Feb 28, 2020 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Try setting the timer in the first setTimeout to 10, this will ensure that it fires in the correct sequence. A value 0 is ambiguous and may be causing the browser issues.

coothead

3:26 pm on Feb 28, 2020 (gmt 0)

5+ Year Member Top Contributors Of The Month



Hi there l008comm,

try this coding...

index.html

<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>code for l008comm</title>

<link rel="stylesheet" href="screen.css" media="screen">

</head>
<body>

<div id="products">
<img id="current_item" src="http://new.www.macfixer.com/product_images/apple_watch_2018.png" width="384" height="384" alt="Products">
</div>

<script src="slider.js"></script>

</body>
</html>


screen.css



body {
text-align: center;
}

#products {
position: relative;
display: inline-block;
cursor: pointer;
height: 12em;
width: 12em;
padding: 1em;
overflow: hidden;
border: solid 1px #999;
}

#products > img {
position: absolute;
top: 1em;
left: 1em;
width: 12em;
height: auto;
transition: left 1.5s ease-in-out;
}


slider.js

( function( d ) {
var products,
product_timer,
slide_hold = false,
pointer = 0,
slide_image_timer = 5000, // Time between automated slides
speed,
new_image,
image_list = [
'http://new.www.macfixer.com/product_images/appletv_2017.png',
'http://new.www.macfixer.com/product_images/macbook_air_2018.png',
'http://new.www.macfixer.com/product_images/macmini_2018.png',
'http://new.www.macfixer.com/product_images/imac_2017.png',
'http://new.www.macfixer.com/product_images/mojave_2018.png',
'http://new.www.macfixer.com/product_images/macpro_2013.png',
'http://new.www.macfixer.com/product_images/ipad_2017.png',
'http://new.www.macfixer.com/product_images/apple_watch_2018.png',
'http://new.www.macfixer.com/product_images/macbook_pro_2018.png',
'http://new.www.macfixer.com/product_images/iphone_xr_2018.png',
'http://new.www.macfixer.com/product_images/ipod_2017.png'
];

products = d.getElementById('products');
product_timer = setTimeout( slide_image , slide_image_timer );


function slide_image(speed) {
slide_hold = true;
if (speed === undefined) {
speed = 1500;
}

new_image = d.createElement('img');
new_image.setAttribute('alt','Mac');
new_image.setAttribute('id','new_item');
new_image.setAttribute('src',get_next_product());
new_image.style.left = '202px';new_image.style.left = '14em';
new_image.onload = function() {
setTimeout(function() {
products.querySelector('#new_item').style.left = '1em';
products.querySelector('#new_item').style.transitionDuration = speed + 'ms';
products.querySelector('#current_item').style.left = '-14em';
products.querySelector('#current_item').style.transitionDuration = speed + 'ms';
},1);

setTimeout(function() {
products.removeChild(products.querySelector('#current_item'));
products.querySelector('#new_item').setAttribute('id','current_item');
slide_hold = false;
product_timer = setTimeout( slide_image , slide_image_timer - speed );
},speed);
};

products.append(new_image);
}

function get_next_product() {
pointer ++;
if (pointer >= image_list.length) {
pointer = 0;
}
return image_list[pointer];
}
}( document ) );


birdbrain

l008comm

5:56 pm on Feb 28, 2020 (gmt 0)

10+ Year Member Top Contributors Of The Month



coothead what changes did you make exactly? You snagged a lot of code off my site rather than sticking to the simplified example so I'm not clear what the actual "fix" is in your code?

l008comm

6:04 pm on Feb 28, 2020 (gmt 0)

10+ Year Member Top Contributors Of The Month



coothead so I just threw your code in a jsfiddle myself and it still doesn't work right in firefox.
[jsfiddle.net...]

coothead

1:16 am on Feb 29, 2020 (gmt 0)

5+ Year Member Top Contributors Of The Month



Hi there 1008comm,

the code that I supplied worked in my test browsers.

To work in jsfiddle or codepen requires this HTML replacement...


<img id="current_item" src="https://www.macfixer.com/product_images/apple_watch_2018.png" width="384" height="384" alt="Products">


...and this javascript replacement...


image_list = [
'https://www.macfixer.com/product_images/appletv_2017.png',
'https://www.macfixer.com/product_images/macbook_air_2018.png',
'https://www.macfixer.com/product_images/macmini_2018.png',
'https://www.macfixer.com/product_images/imac_2017.png',
'https://www.macfixer.com/product_images/mojave_2018.png',
'https://www.macfixer.com/product_images/macpro_2013.png',
'https://www.macfixer.com/product_images/ipad_2017.png',
'https://www.macfixer.com/product_images/apple_watch_2018.png',
'https://www.macfixer.com/product_images/macbook_pro_2018.png',
'https://www.macfixer.com/product_images/iphone_xr_2018.png',
'https://www.macfixer.com/product_images/ipod_2017.png'
];


Check it out here...

  1. [jsfiddle.net ]
  2. full page - [codepen.io ]
  3. code - [codepen.io ]



birdbrain

l008comm

7:15 am on Feb 29, 2020 (gmt 0)

10+ Year Member Top Contributors Of The Month



It still doesn't work consistently in firefox. Some frames slide normally, properly. But other frames break and the new image appears centered, not sliding in. I just tested your fiddle under Firefox 73 mac and Firefox 73 windows. You have to let it run for a while. It seems to work at first but then it stops working.

I'm also still not clear on what you actually did differently in your code since it's not really the code I started with on this post, but I guess it's all moot since it doesn't really fix the problem.

l008comm

7:18 am on Feb 29, 2020 (gmt 0)

10+ Year Member Top Contributors Of The Month



@NickMNS unfortunately setting the timeout to 10 (from 0) does not have any effect on the display glitch.

coothead

5:22 am on Mar 1, 2020 (gmt 0)

5+ Year Member Top Contributors Of The Month



Hi there l008comm,

here is a total reworking of the code...

  1. full page - [codepen.io ]
  2. the code - [codepen.io ]


It does not work in jsfiddle but I will settle for it
working in all my test browsers and codepen. :)

birdbrain

coothead

10:54 pm on Mar 1, 2020 (gmt 0)

5+ Year Member Top Contributors Of The Month



Hi there l008comm,

I forgot to mention that the main advantage of the JavaScript code
that I provided is that it does not include any CSS coding at all. :)

birdbrain