I want to ask you a very simple question. Im trying to make a nav-mobile which opens whenever you touch the hamburger button. Everything works fine but I wanted to add a "darker" background to the main page.
I ended up doing something like:
JS CODE:
var Opened = document.getElementById('menu-open');
var Closed = document.getElementById('menu-close');
function OpenNav()
{
if (Opened.getAttribute('src') == "news-homepage-main/assets/images/icon-menu.svg"){
document.getElementById('nav-mobile').style.width = '250px';
document.body.style.backgroundColor = "black";
}
}
function CloseNav()
{
if (Closed.getAttribute('src') == "news-homepage-main/assets/images/icon-menu-close.svg"){
document.getElementById('nav-mobile').style.width = '0';
document.body.style.backgroundColor = "";
}
}
BLACK COLOR CHOICE IS ONLY A TEST, the color I chose is to let you see how the results is. Still doesn't work, look at the image.
Thanks!
I tried so far to change the:
document.body.style.backgroundColor = "black";
to a filter. Still not working. I tried to make even an overlay div, but still with no success.
My guess on what you want here is an overlay with a light dark background that will be placed in front of your main page when the side nav is opened and hidden when the side nav is closed. I would suggest an absolute element that takes full width and height of the page. Something like this:
<div id="overlay"></div>
With the rules below:
#overlay {
width: 100%;
height: 100%;
background: rgba(0,0,0,0.7);
position: absolute;
top: 0;
left: 0;
display: none;
z-index: 2;
}
Have in mind you need to adjust your side-navs z-index to be less than the z-index of the overlay so it will be in front.
And in your function that open and closes the sidebar you should show and hide it accordingly. Something like this:
function OpenNav()
{
if (Opened.getAttribute('src') == "news-homepage-main/assets/images/icon-menu.svg"){
document.getElementById('nav-mobile').style.width = '250px';
document.getElementById('overlay').style.display = 'block';
}
}
function CloseNav()
{
if (Closed.getAttribute('src') == "news-homepage-main/assets/images/icon-menu-close.svg"){
document.getElementById('nav-mobile').style.width = '0';
document.getElementById('overlay').style.display = 'none';
}
}
Related
my question has 3 parts. Any assistance with any part of this JS problem would be greatly appreciated. I am attempting to learn and comprehend JS by trial and error.
I've created this nice looking travel landing page, https://portfolioprime.github.io/Nature%20carousel/glidejs.html with a thumbnail carousel which uses Glide.js, which is really cool and works well. The carousel moves to the left and has arrow buttons to manually control the slide.
But I've been trying to implement a vanilla JS carousel slider,but I am failing miserably. Been struggling for 2 days and the best I can achieve is getting a single carousel item moving left and right. See https://portfolioprime.github.io/Nature%20carousel/.
What I'd like is to get the carousel sliding left automatically, with arrow buttons to manually control the slider.
I'm targeting all the carousel-items with querySelectorAll('.carousel-items') and adding left:-274px to the carousel container glide__slides.
Here's my JS code.
// var & event-listener buttons
document.querySelector(".left").addEventListener("click", slideLeft);
document.querySelector(".right").addEventListener("click", slideRight);
// Function slide left
function slideLeft(left) {
document.querySelector('.glide__slides').style.left = left;
}
// Function slide left
function slideRight(right) {
document.querySelector('.glide__slides').style.left = right;
}
Secondly, I'd like to have an active carousel-item, which when active automatically changes the background Image.
Right now I have the hero.style.background = var; and I've got it changing onclick with onclick = function('01.jpg') on each carousel item.
Here's the code.
// Change Hero Img
function heroChange(hmmm) {
var hero = document.querySelector('.hero');
hero.style.background = hmmm;
}
So I guess I would add EventListeners to the carousel-items and add an active class to the carousel-item like so,
var slides = document.querySelectorAll('.carousel-items');
function changeBgImg() {
slides.forEach(s => s.classList.remove('active');
this.classList.add('active');
//change the bg image === this
//But I have no idea how to do that
}
Thirdly I've got the content, background and carousel indicators using the same functions above but it seems like really dirty code. The HTML has each .carousel-item, there are ten of them, calling 4 functions each. It looks like this:
<div class="glide hero-carousel">
<div class="glide__track" data-glide-el="track">
<ul class="glide__slides">
<li class="glide__slide carousel-item"
onclick="heroChange('url(images/02.jpg) bottom/cover no-repeat');
number('01');
h4('Destination Shire');
h1('Valley<br> of Dreams');">
<div class="carousel-text">
<p>Destination Shire</p>
<h3>Valley<br> of Dreams</h3>
</div>
</li>
<li class="glide__slide carousel-item"
onclick="heroChange('url(images/03.jpg) bottom/cover no-repeat');
number('02');
h4('Destination Westwood');
h1('Misty<br> Woodlands');">
<div class="carousel-text">
<p>Destination Westwood</p>
<h3>Misty<br> Woodlands</h3>
</div>
</li>
</ul>
</div>
</div>
So it looks pretty yucky. It works though, but I would love to find a more elegant way of achieving this by putting all of these functions into one function that does each part in sequence.
Lastly, I'd want to get transition on-click animations going but that's another kettle of fish entirely.
So that's it. Whew!
Thanks for taking the time guys, I appreciate it. Any help you can provide is going to make me a better designer. There are actually a bunch of projects I have will benefit from the answers.
If you can provide help with at least Part 2 & 3: cleaning up the code into 1 function and getting the bg-image changing on the active class that would be a big big help.
There's just so much that JS can do and I'm not finding the answers on Google and youTube.
Thank you again.
An Update:
I have edited the slider by by using margin-left as shown by this question:
vanilla javascript carousel not sliding
// var & event-listener buttons
document.querySelector(".left").addEventListener("click", slideLeft);
document.querySelector(".right").addEventListener("click", slideRight);
let marginLeft = 0;
const slides = document.querySelector('.glide__slides');
// Function slide left
function slideLeft() {
marginLeft += 264;
slides.style.marginLeft = marginLeft + 'px';
console.log(getComputedStyle(slides).marginLeft);
}
// Function slide Right
function slideRight() {
marginLeft -= 264;
slides.style.marginLeft = marginLeft + 'px';
console.log(getComputedStyle(slides).marginLeft);
}
This has now got the carousel moving manually 1 slide at a time.
Still not fully understanding why my previous code above didn't work. If anyone can explain that to me that would be great.
I'm still left with some issues:
Autosliding and looping at the end of the slides.
Having the active slider change the background automatically. At this point it only changes onclick.
Finding a way to tidy up the function calls and functions.
The question asks for various ideas on how to simplify code and how to use native JavaScript to create a slider that rolls continuously.
The code originally used glider and it may be something simpler would be sufficient to get the desired result, for example using animationend event to change the background when a slide gets to the left hand side. However, eating the elephant slowly I'll tackle the yucky code (part 3) first.
Although the HTML looks rather daunting, 4 calls on a click for every li element for example, it is currently what is required so let's investigate creating it at run time. This gives us more easily maintainable code. For example, if we want to remove a slide, or alter the order of slides or add one we can just alter the slider array defined below and JavaScript will do the rest.
Part 1 of the question asked about sliding. We slide the whole ul element using CSS animation defined something like this, where 33vw is the total width of a slide (inc. margins/padding)
#keyframes sliding0 {
0% { left: 0; }
30% { left: 0; }
100% { left: -33vw; }
}
and we add an event listener to the element to trap animationend events because when the ul has slid one slide's width we want to change the hero image, and we want to put the slide that has just disappeared onto the back of the infinie sliding will work. We then set the animation running again.
See the snippet for details on how this and other events are dealt with. It also shows how the changeHero function can work which was part 2 of the question. Note, the snippet works more or less in the SO environment, though occasionally hover action is partially ignored. Running the code on your own machine it should be fine though.
<!DOCTYPE html>
<html>
<head>
<style>
#keyframes sliding0 {
0% { left: 0; }
30% { left: 0; }
100% { left: -33vw; }
}
#keyframes sliding1 {
0% { left: 0; }
30% { left: 0; }
100% { left: -33vw; }
}
body {
background-repeat: no-repeat no-repeat;
background-size: cover;
background-position: center center;
}
div .glide_track {
position: relative;
width: 100vw;
overflow-x: hidden;
}
ul {
position:relative;
left: 0;
width: 330vw;
height:100vh;
animation-name: sliding0;
animation-duration: 3s;
animation-delay: 0s;
animation-iteration-count: 1;
animation-timing-function: linear;
margin: 0;
padding: 0;
list-style-type: none;
}
li {
position: relative;
left:0;
top:0;
float:left;
width: 32vw;
height:30vw;
display: inline-block;
margin: 0;
margin-right: 1vw;
padding: 0;
background-size: cover;
background-repeat: no-repeat no-repeat;
background-position: center center;
}
</style>
</head>
<body>
<script>
// we put the two lots of text and the image url for each slide in an array in the order they are to be shown
// this makes it easier to maintain when you want to add or remove a slide or change their order
// we only have one slider at the moment but this makes it more general
// these are the offsets in the array describing a slide. Done as indexes rather than named as easier to set up sliders array
const img = 0;
const text1 = 1;
const text2 = 2;
const sliders = [
[
['https://ahweb.org.uk/boxfordmosaic.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/gear-in-turbine-house-reading.jpg','Westwood','Misty Woodlands'],
['https://ahweb.org.uk/tricycle-in-abbey-ruins.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/boxfordmosaic.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/gear-in-turbine-house-reading.jpg','Westwood','Misty Woodlands'],
['https://ahweb.org.uk/tricycle-in-abbey-ruins.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/boxfordmosaic.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/gear-in-turbine-house-reading.jpg','Westwood','Misty Woodlands'],
['https://ahweb.org.uk/tricycle-in-abbey-ruins.jpg','Shire','Valley<br> of Dreams'],
['https://ahweb.org.uk/tricycle-in-abbey-ruins.jpg','Shire','Valley<br> of Dreams']
]
];
// go through each slider and create its outer divs and its ul element
sliders.forEach(createSlider);
function createSlider(slider,sliderno) {
const div1 = document.createElement('DIV');
const div2 = document.createElement('DIV');
const ul = document.createElement('UL');
div1.classList.add("glide","hero-carousel");
div2.classList.add("glide_track");
div2.setAttribute("data-glide-el","track");
div1.appendChild(div2);
div2.appendChild(ul);
document.body.appendChild(div1);
ul.classList.add("glide__slides");
ul.addEventListener("animationend", animationEnd);
slider.forEach(createLi);
function createLi(slide,slideNo) {
const li = document.createElement('LI');
li.classList.add("glide__slide","carousel-item");
li.style.backgroundImage='url('+slide[img]+')';
li.addEventListener("click",slideClicked);
li.addEventListener("mouseover",slideHovered);
li.addEventListener("mouseout",slideUnhovered);
li.setAttribute('data-slideno','0' + slideNo);//! needs generalising if you have >10 slides !
ul.appendChild(li);
const div = document.createElement('DIV');
const p = document.createElement('P');
const h3 = document.createElement('H3');
p.innerHTML = slide[text1];
div.appendChild(p);
h3.innerHTML = slide[text2];
div.appendChild(h3);
li.appendChild(div);
}
}
// this is for testing, in real version use whatever required (i.e. whichever element is to have the hero image)
function ahHeroChange(backgroundImage) {
document.body.style.background = backgroundImage + " bottom/cover no-repeat";
}
function slideClicked(event) {
var slide = event.target;
var slideNo = slide.getAttribute('data-slideno');
// make the hero image the same as the slide's
ahHeroChange(slide.style.backgroundImage);
/* I don't know what these functions do - they were executed in the original on a click
number(slideno);
h4(slide.firstElementChild.querySelector('p').innerHTML);// text1 of the slide is passed to h4
h1(slide.firstElementChild.querySelector('h3').innerHTML;// text2 of the slide is passed to h1
*/
}
function slideHovered(event) {
var slide = event.target;
var slider = slide.parentElement;
slider.style.animationPlayState = 'paused';
ahHeroChange(slide.style.backgroundImage);
}
function slideUnhovered(event) {
var slide = event.target;
var slider = slide.parentElement;
//restore the hero image to the first one in the slider
ahHeroChange(slider.firstElementChild.style.backgroundImage);
//get the animation running again
slider.style.animationPlayState = 'running';
}
function animationEnd(event) {
//find the element that was clicked (it will be a ul element representing a slider)
var slider = event.target;
//take the first slide off the list and put it back at the end
slider.append(this.firstElementChild);
//change the hero image to the slide which is now the leftmost - use modified heroChange in the final version
document.body.style.backgroundImage = this.firstElementChild.style.backgroundImage;
// toggle the animationName (to an identical keyframes action) to force the animation to start again
slider.style.animationName='sliding'+(Number(event.animationName.replace('sliding',''))+1)%2;
}
</script>
</body>
</html>
This question already has answers here:
Why don't my alert message and background color change execute simultaneously?
(3 answers)
Closed 3 years ago.
I need to display an alert box and at the same time cover what is on my HTML page. Basically, I'd like to have a blank or white background when my alert pop-up appears. I tried something like below, but doesn't work.
if (something happens) {
changeBackgroundColor();
if (alert("My alert box")){
} else {
//Return to previous page
window.history.go(-1);
}
}
..
....
.....
function changeBackgroundColor() {
document.body.style.backgroundColor = "white";
}
Changing your background color will not hide any of the elements on your page. You will most likely need an overlay, which can be a simple div styled something like this:
.overlay {
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
z-index:999; /* adjust the z-index as you need it */
background:#fff;
display:none;
}
you can then show the overlay before your alert and hide it afterwards
function toggleOverlay( show ){
document.querySelector('.overlay').style.display = (show === true) ? 'block' : 'none';
}
// ...
toggleOverlay(true);
// Kudos to Kobe for pointing out that the alert is triggered before the repaint
// simple way to solve the problem is a timeout, which will
// make the browser paint the changes before the alert is triggered
setTimeout(function(){
alert('Something');
toggleOverlay(false);
}, 0);
Here is a working jsFiddle: https://jsfiddle.net/UsernamesSuck/cpdrtgb8/2/
The problem is that when alert() is called the rest of the script pauses. A solution is to wrap it in a setTimeout() function to make it async to allow the rest of the code to be executed.
Take a look at the following Fiddle for a possible solution:
https://jsfiddle.net/hckevbtp/
You can create an absolutely positioned div with a z-index greater than all of your content to hide it:
const hide = () => {
var div = document.getElementById('hide')
div.style.display = 'block'
setTimeout(() => {
alert()
div.style.display = 'none'
}, 0)
}
.hide {
position: fixed;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
background-color: blue;
z-index: 1000;
display: none;
}
<p>Content Content Content</p>
<button onclick="hide()">HIDE</button>
<div id="hide" class="hide"></div>
Since alert is blocking, you can immediately remove the style after the alert, which will take effect after the alert is closed.
you can use the display='none' for the container and call the alert in setTimeout() as follows -
function openAlert() {
document.getElementsByClassName('block')[0].style.display = 'none';
setTimeout(function() {
alert('hello world!');
document.getElementsByClassName('block')[0].style.display = 'block';
}, 100);
}
html -
<body>
<div class='block'>
<button onclick={openAlert()}>hello</button>
</div>
</body>
Try this:
if (something happens) {
changeBackgroundColor();
setTimeout(function() {alert("hey");}, 0)
}
..
....
.....
function changeBackgroundColor() {
document.body.style.opacity= "0";
}
You can use below code:
function showMessage() {
var div = document.getElementById('div');
if(div == null){
div = document.createElement('div');
div.id = "div";
}
div.classList.add('alert')
document.body.appendChild(div)
setTimeout(function() {
alert("alert text");
div.classList.remove('alert');
},0)
}
Style:
.alert {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: absolute;
background-color: white;
}
On my page I have a gallery (just a div) with several images on it. I want to show the first 9 images immediately, then load more images and use CSS transitions to animate between the existing images.
Loading the initial images is easy but I do not know the best way to load the next set of images and then start animating (using the CSS Transform property). So far this is what I have:
HTML (abbreviated):
<div id="mainContainer">
<div class="imageHolder"><img class="homeImages" src="test.png"></div>
<div class="imageHolder"><img class="homeImages" src="test1.png"></div>
<div class="imageHolder"><img class="homeImages" src="test3.png"></div>
</div>
CSS (abbreviated):
img {
display: inline;
position: relative;
margin: 0;
padding: 0;
width: 30%;
}
.changed.opaque {
opacity: 0;
border: 2px solid red;
}
I am looking to do a variety of effects, the most simple one would be to change the opacity and fade one image over the other. To load the next set of images I have this:
Javascript:
var imageArray = [
'test2.png',
'test3.png',
'test4.png',
'test5.png',
'test6.png',
];
var imageNodeArray = [];
for(var i = imageArray.length - 1; i >= 0; i -= 1) {
var img = new Image();
img.onload = function() {
imageNodeArray.push(this);
};
img.src = imageArray[i];
}
document.onclick = function() {
imageNodeArray[0].setAttribute('class', 'changed.opaque');
divs[0].appendChild(imageNodeArray[0])
}
This does add an image to my mainContainer however, even though I can tell from devTools that it has the changed.opaque class applied to it, no opacity is shown on the added image.
I am curious about this. I would also like to know the best way to "stack" images to have a bunch to animate through. I am not sure that appending child is right.... Thank you
function animate() {
var index = Math.floor((Math.random() * document.querySelectorAll('#mainContainer > .imageHolder').length + 1));
var current = document.querySelector('.top');
var next = document.querySelector('.imageHolder:nth-of-type(' + index + ')');
current.className = "imageHolder";
next.className += "top";
}
Should be able to handle and switch between any dynamically inserted images.
Currently using:
.imageHolder {
display: none;
}
.top {
display: inherit;
}
to switch the image is just a simple implementation.
Here's the working fiddle: http://jsfiddle.net/e9dxN/1/
Alternative implementation: http://jsfiddle.net/e9dxN/6/
Hello, I want a certain text to appear when I scroll past it or when I scroll until the point where the text is. The effect when appearing should be somewhat like the first effect on the top of the website http://namanyayg.com/.
I want the effect in minimal code with pure CSS and JS i.e no jQuery.
I was thinking that maybe I would use something like a display:none property for a span and then when you scroll past it the display becomes block but I dont know how to trigger the effect using javascript.
Any help would be appreciated.
First wrap whatever your text or content that you want to show on scroll, in one div so that you can show hide the div depending upon the scroll. Write two classes for your target div.
Your CSS:
/*Use this class when you want your content to be hidden*/
.BeforeScroll
{
height: 100px; /*Whatever you want*/
width: 100%; /*Whatever you want*/
.
.
display: none;
}
/*Use this class when you want your content to be shown after some scroll*/
.AfterScroll
{
height: 100px; /*Whatever you want*/
width: 100%; /*Whatever you want*/
.
.
display: block;
}
Your HTML:
<!--Set class BeforeScoll to your target div-->
<div id = "divToShowHide" class = "BeforeScroll">Content you want to show hide on scroll</div>
Your Script:
<!--include these script in head section or wherever you want-->
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js" type="text/javascript"></script>
<script type = "text/javascript">
$(document).ready(function(){
//Take your div into one js variable
var div = $("#divToShowHide");
//Take the current position (vertical position from top) of your div in the variable
var pos = div.position();
//Now when scroll event trigger do following
$(window).scroll(function () {
var windowpos = $(window).scrollTop();
//Now if you scroll more than 100 pixels vertically change the class to AfterScroll
// I am taking 100px scroll, you can take whatever you need
if (windowpos >= (pos.top - 100)) {
div.addClass("AfterScroll");
}
//If scroll is less than 100px, remove the class AfterScroll so that your content will be hidden again
else {
s.removeClass("AfterScroll");
}
//Note: If you want the content should be shown always once you scroll and do not want to hide it again when go to top agian, no need to write the else part
});
});
</script>
Hope it will solve your problem.
I would recommend this plugin
http://johnpolacek.github.io/superscrollorama/
Edit:
I don't know how no one noticed that the solution had to be made without using external libraries like jQuery. However, the solution is extremely easy with basic functionality. Find it here
HTML:
<div id="parent-div">
<div id="child-div">
Psst .. I am here!!
</div>
</div>
CSS:
#parent-div
{
position:relative;
height:3000px;
width:300px;
background-color:red;
}
#child-div
{
color:white;
position:relative;
top:1000px;
width:300px;
display:none;
text-align:center;
}
JS:
var body=document.getElementsByTagName("body")[0];
var parent=document.getElementById("parent-div");
var child=document.getElementById("child-div");
body.onscroll = function(){
//console.log(documenhttps://fiddle.jshell.net/3urv0tp0/#tidyt.getElementById("child-div").style.top)
if(document.documentElement.scrollTop>=child.offsetTop)//Adjust Tolerance as you want
{
child.style.display="block"
}
};
I was looking for this either. Here i was trying to make "show text after scrolling to (number)px with fade effect". I wish it will work as it works for me :) The animation will be playing again if u scroll back to it, idk how to make it just one like in web u showed xd (i will edit if I find out)
window.addEventListener("scroll", function() {showFunction()});
function showFunction() {
if (document.body.scrollTop > 900 || document.documentElement.scrollTop > 900) {
document.getElementById("toptexts2").style.display = "block";
} else {
document.getElementById("toptexts2").style.display = "none";
}
}
.toptexts2 {
animation: fadeEffect 3s; /* fading effect takes 3s */
}
#keyframes fadeEffect { /* from 0 to full opacity */
from {opacity: 0;}
to {opacity: 1;}
}
<div class="toptexts2" id="toptexts2">
<div>Hi!</div>
<div>↓ go down ↓</div>
</div>
I like this:
var doc = document, dE = doc.documentElement, bod = doc.body;
function E(e){
return doc.getElementById(e);
}
function xy(e, d){
if(!d)d = 'Top';
d = 'offset'+d;
var r = e[d];
while(e.offsetParent){
e = e.offsetParent; r += e[d];
}
return r;
}
function x(e){
return xy(e, 'Left');
}
function y(e){
return xy(e);
}
var txt = E('theId'), txtS = txt.style;
onscroll = function(){
var left = dE.scrollLeft || bod.scrollLeft || 0;
var top = dE.scrollTop || bod.scrollTop || 0;
var w = innerWidth || dE.clientWidth || bod.clientWidth;
var h = innerHeight || dE.clientHeight || bod.clientHeight;
if(top > y(txt)-h){
txtS.display = 'none';
}
else{
txtS.display = 'block';
}
}
I left the left stuff in there, just in case, but you can probably remove it.
var div=$("#divtochange");
$(window).scroll(function () {
var windowpos = $(window).scrollTop();
//---check the console to acurately see what the positions you need---
console.log(windowpos);
//---------------------
//Enter the band you want the div to be displayed
if ((windowpos >= 0) && (windowpos <= 114)){
div.addClass("AfterScroll");
}
else{
div.removeClass("AfterScroll");
}
I'm trying to toggle between images, but the code I have is just laying one on top of the other, not removing the initial image. This is what I have:
<script>
var button = document.getElementById('box'),
text = document.getElementById('menu');
button.onclick = function () {
var isHidden = text.style.display == 'none';
text.style.display = isHidden ? 'block' : 'none';
};
$("#box").click(function () {
$(this).toggleClass("red");
});
</script>
I have the intial image set up as a div and the second one as a class:
.close {
width: 29px;
z-index: 1;
height: 16px;
cursor: crosshair;
background-image: url('http://gabrielamagana.com/project1/ndxz-studio/site/sample/close-eye.png');
}
This is probably not the best way to set this up but '=I'm fairly new at this.
If you're trying to toggle images, try the following technique:
I don't have a clear understanding of your existing HTML structure so this simply serves as an example.
Live Demo
HTML
<div class='img1' id='dvImage'> </div>
JS
$(function(){
var ele = $('#dvImage');
ele.click(function(){
ele.toggleClass("img2");
});
});
CSS
.img1, .img2{
width:400px;
height:100px;
}
.img1{
background-image:url('http://dummyimage.com/400x150/000/fff');
}
.img2{
background-image:url('http://dummyimage.com/400x150/000/aaa');
}
NOTE: To get rid of the flicker between initial image loads, use a "sprite image." You'll gain performance by reducing requests and eliminate the flicker associated with loading new images.